diff --git a/ext/native/.gitignore b/ext/native/.gitignore new file mode 100644 index 0000000000..2f3dc5a3ff --- /dev/null +++ b/ext/native/.gitignore @@ -0,0 +1,6 @@ +Release +Debug +*.vcxproj.user +android/.settings +local.properties +.DS_Store diff --git a/ext/native/Android.mk b/ext/native/Android.mk new file mode 100644 index 0000000000..2ae05260c5 --- /dev/null +++ b/ext/native/Android.mk @@ -0,0 +1,133 @@ +# Basic Android.mk for libnative + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libnative +LOCAL_ARM_MODE := arm +LOCAL_SRC_FILES :=\ + android/native_audio.cpp \ + android/native-audio-so.cpp \ + audio/wav_read.cpp \ + audio/mixer.cpp.arm \ + base/backtrace.cpp \ + base/buffer.cpp \ + base/compat.cpp \ + base/display.cpp \ + base/timeutil.cpp \ + base/colorutil.cpp \ + base/error_context.cpp \ + base/stringutil.cpp \ + data/compression.cpp \ + ext/rg_etc1/rg_etc1.cpp \ + ext/cityhash/city.cpp \ + ext/libpng17/png.c \ + ext/libpng17/pngerror.c \ + ext/libpng17/pngget.c \ + ext/libpng17/pngmem.c \ + ext/libpng17/pngpread.c \ + ext/libpng17/pngread.c \ + ext/libpng17/pngrio.c \ + ext/libpng17/pngrtran.c \ + ext/libpng17/pngrutil.c \ + ext/libpng17/pngset.c \ + ext/libpng17/pngtest.c \ + ext/libpng17/pngtrans.c \ + ext/libpng17/pngwio.c \ + ext/libpng17/pngwrite.c \ + ext/libpng17/pngwtran.c \ + ext/libpng17/pngwutil.c \ + ext/jpge/jpgd.cpp \ + ext/jpge/jpge.cpp \ + ext/sha1/sha1.cpp \ + ext/stb_vorbis/stb_vorbis.c.arm \ + ext/vjson/json.cpp \ + ext/vjson/block_allocator.cpp \ + file/dialog.cpp \ + file/fd_util.cpp \ + file/easy_file.cpp \ + file/chunk_file.cpp \ + file/file_util.cpp \ + file/path.cpp \ + file/ini_file.cpp \ + file/zip_read.cpp \ + json/json_writer.cpp \ + i18n/i18n.cpp \ + input/gesture_detector.cpp \ + input/input_state.cpp \ + math/fast/fast_math.c \ + math/fast/fast_matrix.c \ + math/math_util.cpp \ + math/curves.cpp \ + math/expression_parser.cpp \ + math/lin/aabb.cpp.arm \ + math/lin/plane.cpp.arm \ + math/lin/quat.cpp.arm \ + math/lin/vec3.cpp.arm \ + math/lin/matrix4x4.cpp.arm \ + midi/midi_input.cpp \ + net/http_client.cpp \ + net/http_server.cpp \ + net/http_headers.cpp \ + net/resolve.cpp \ + net/url.cpp \ + profiler/profiler.cpp \ + thread/executor.cpp \ + thread/threadutil.cpp \ + thread/prioritizedworkqueue.cpp \ + thread/threadpool.cpp \ + gfx_es2/glsl_program.cpp \ + gfx_es2/gpu_features.cpp \ + gfx_es2/gl3stub.c \ + gfx_es2/draw_buffer.cpp.arm \ + gfx_es2/draw_text.cpp.arm \ + gfx_es2/vertex_format.cpp \ + gfx/gl_debug_log.cpp \ + gfx/gl_lost_manager.cpp \ + gfx/texture.cpp \ + gfx/texture_atlas.cpp \ + gfx/texture_gen.cpp \ + image/zim_load.cpp \ + image/zim_save.cpp \ + image/png_load.cpp \ + thin3d/thin3d.cpp \ + thin3d/thin3d_gl.cpp \ + ui/view.cpp \ + ui/viewgroup.cpp \ + ui/ui.cpp \ + ui/ui_screen.cpp \ + ui/ui_context.cpp \ + ui/screen.cpp \ + ui/virtual_input.cpp \ + util/random/perlin.cpp \ + util/text/utf8.cpp \ + util/text/parsers.cpp \ + util/hash/hash.cpp + +LOCAL_CFLAGS := -O3 -DUSING_GLES2 -fsigned-char -fno-strict-aliasing -Wall -Wno-multichar -D__STDC_CONSTANT_MACROS +LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder +LOCAL_C_INCLUDES := $(LOCAL_PATH)/ext $(LOCAL_PATH)/ext/libzip + +#Portable native and separate code on android in future is easy you needs add files +#by ($(target_arch_ABI),arquitecture (armeabi-v7a , armeabi , x86 , MIPS) +# ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) +ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + math/fast/fast_matrix_neon.S.neon \ + ext/libpng17/arm/arm_init.c \ + ext/libpng17/arm/filter_neon_intrinsics.c \ + ext/libpng17/arm/filter_neon.S.neon + +else ifeq ($(TARGET_ARCH_ABI),armeabi) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 +else ifeq ($(TARGET_ARCH_ABI),arm64-v8a) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_ARCH_64 -DARM64 +else ifeq ($(TARGET_ARCH_ABI),x86) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86 +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + math/fast/fast_matrix_sse.c +endif + +include $(BUILD_STATIC_LIBRARY) diff --git a/ext/native/LICENSE.TXT b/ext/native/LICENSE.TXT new file mode 100644 index 0000000000..e92ab68fef --- /dev/null +++ b/ext/native/LICENSE.TXT @@ -0,0 +1,9 @@ +Copyright (C) 2012 Henrik Rydgard + +This applies to all the code here not covered under other licenses, see README.md. + +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/ext/native/README.md b/ext/native/README.md new file mode 100644 index 0000000000..fb9f428c97 --- /dev/null +++ b/ext/native/README.md @@ -0,0 +1,50 @@ +native +====== + +This is my library of stuff that I use when writing C++ programs, mostly for Android but it's all written to enable easy portability between Android, Linux, Windows and MacOSX. The code is part ugly, part inconsistent but quite useful. + +Features +-------- + +* JSON read/write (two libraries that should be made more similar) +* basic OpenGL utility code, like compressed texture loading +* 2D texture atlases and drawing code +* ETC1 texture save/load support +* basic logging +* Really simple audio mixer with OGG sample support +* RIFF file read/write +* MIDI Input (only on Windows) + +Notes +----- + +* The associated tools to create ZIM texture files and atlases do not yet live here but I might move them here eventually. +* This library is not really meant to be a public library but I see no reason not to set it free. +* Note that the included VS project is probably not very useful for you and you're likely better off making your own. +* Don't complain about inconsistent naming etc - this consists of code that has been cobbled together from a variety of my projects through the years. Fashions come and go. + +Licenses +-------- + +This library, for my convenience, incorporates code from a variety of public domain or similarly-licensed code. This is the list: + +* glew (GL extension wrangler), MIT license. TODO: should just use a submodule. +* rg_etc1. ZLIB license. +* sha1, public domain implementation by Dominik Reichl +* vjson in a heavily modified form, originally by Ivan Vashchaev (TODO: break out into its own repo?) +* libzip with attribution "Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner" +* stb_vorbis, public domain by Sean Barrett of RAD Tools + +If you're not okay with the licenses above, don't use this code. + +I hereby release all code here not under the licenses above under the MIT license. + +Contact +------- + +If you find this useful for your own projects, drop me a line at hrydgard@gmail.com . + +Henrik Rydgård + + + diff --git a/ext/native/android/.classpath b/ext/native/android/.classpath new file mode 100644 index 0000000000..7bc01d9a9c --- /dev/null +++ b/ext/native/android/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ext/native/android/.gitignore b/ext/native/android/.gitignore new file mode 100644 index 0000000000..021b4205f9 --- /dev/null +++ b/ext/native/android/.gitignore @@ -0,0 +1,2 @@ +gen +bin diff --git a/ext/native/android/.project b/ext/native/android/.project new file mode 100644 index 0000000000..790a38db49 --- /dev/null +++ b/ext/native/android/.project @@ -0,0 +1,33 @@ + + + libnative + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/ext/native/android/AndroidManifest.xml b/ext/native/android/AndroidManifest.xml new file mode 100644 index 0000000000..f85c5efadd --- /dev/null +++ b/ext/native/android/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/ext/native/android/README.md b/ext/native/android/README.md new file mode 100644 index 0000000000..61612db953 --- /dev/null +++ b/ext/native/android/README.md @@ -0,0 +1,8 @@ +Here's an Android library project. Add this to your eclipse workspace +and add a dependency to it, then just inherit from NativeActivity, +write your C++ code, and Bob's your uncle. + + +Contact: hrydgard@gmail.com + + diff --git a/ext/native/android/app-android.cpp b/ext/native/android/app-android.cpp new file mode 100644 index 0000000000..5e5cd79d10 --- /dev/null +++ b/ext/native/android/app-android.cpp @@ -0,0 +1,536 @@ +// This is generic code that is included in all Android apps that use the +// Native framework by Henrik Rydgård (https://github.com/hrydgard/native). + +// It calls a set of methods defined in NativeApp.h. These should be implemented +// by your game or app. + +#include +#include +#include +#include +#include +#include +#include + +#include "base/basictypes.h" +#include "base/display.h" +#include "base/mutex.h" +#include "base/NativeApp.h" +#include "base/logging.h" +#include "base/timeutil.h" +#include "thread/threadutil.h" +#include "file/zip_read.h" +#include "input/input_state.h" +#include "profiler/profiler.h" +#include "audio/mixer.h" +#include "math/math_util.h" +#include "net/resolve.h" +#include "android/native_audio.h" +#include "gfx/gl_common.h" + +#include "app-android.h" + +static JNIEnv *jniEnvUI; + +struct FrameCommand { + FrameCommand() {} + FrameCommand(std::string cmd, std::string prm) : command(cmd), params(prm) {} + + std::string command; + std::string params; +}; + +static recursive_mutex frameCommandLock; +static std::queue frameCommands; + +std::string systemName; +std::string langRegion; +std::string mogaVersion; + +static float left_joystick_x_async; +static float left_joystick_y_async; +static float right_joystick_x_async; +static float right_joystick_y_async; +static float hat_joystick_x_async; +static float hat_joystick_y_async; + +static int optimalFramesPerBuffer = 0; +static int optimalSampleRate = 0; +static int sampleRate = 0; +static int framesPerBuffer = 0; +static int androidVersion; +static int deviceType; + +// Should only be used for display detection during startup (for config defaults etc) +static int display_xres; +static int display_yres; + +// Android implementation of callbacks to the Java part of the app +void SystemToast(const char *text) { + lock_guard guard(frameCommandLock); + frameCommands.push(FrameCommand("toast", text)); +} + +void ShowKeyboard() { + lock_guard guard(frameCommandLock); + frameCommands.push(FrameCommand("showKeyboard", "")); +} + +void Vibrate(int length_ms) { + lock_guard guard(frameCommandLock); + char temp[32]; + sprintf(temp, "%i", length_ms); + frameCommands.push(FrameCommand("vibrate", temp)); +} + +void LaunchBrowser(const char *url) { + lock_guard guard(frameCommandLock); + frameCommands.push(FrameCommand("launchBrowser", url)); +} + +void LaunchMarket(const char *url) { + lock_guard guard(frameCommandLock); + frameCommands.push(FrameCommand("launchMarket", url)); +} + +void LaunchEmail(const char *email_address) { + lock_guard guard(frameCommandLock); + frameCommands.push(FrameCommand("launchEmail", email_address)); +} + +void System_SendMessage(const char *command, const char *parameter) { + lock_guard guard(frameCommandLock); + frameCommands.push(FrameCommand(command, parameter)); +} + +std::string System_GetProperty(SystemProperty prop) { + switch (prop) { + case SYSPROP_NAME: + return systemName; + case SYSPROP_LANGREGION: // "en_US" + return langRegion; + case SYSPROP_MOGA_VERSION: + return mogaVersion; + default: + return ""; + } +} + +int System_GetPropertyInt(SystemProperty prop) { + switch (prop) { + case SYSPROP_SYSTEMVERSION: + return androidVersion; + case SYSPROP_DEVICE_TYPE: + return deviceType; + case SYSPROP_DISPLAY_XRES: + return display_xres; + case SYSPROP_DISPLAY_YRES: + return display_yres; + case SYSPROP_AUDIO_SAMPLE_RATE: + return sampleRate; + case SYSPROP_AUDIO_FRAMES_PER_BUFFER: + return framesPerBuffer; + case SYSPROP_AUDIO_OPTIMAL_SAMPLE_RATE: + return optimalSampleRate; + case SYSPROP_AUDIO_OPTIMAL_FRAMES_PER_BUFFER: + return optimalFramesPerBuffer; + case SYSPROP_DISPLAY_REFRESH_RATE: + return (int)(display_hz * 1000.0); + default: + return -1; + } +} + +// Remember that all of these need initialization on init! The process +// may be reused when restarting the game. Globals are DANGEROUS. + +float dp_xscale = 1.0f; +float dp_yscale = 1.0f; + +InputState input_state; + +static bool renderer_inited = false; +static bool first_lost = true; +static std::string library_path; + +std::string GetJavaString(JNIEnv *env, jstring jstr) { + const char *str = env->GetStringUTFChars(jstr, 0); + std::string cpp_string = std::string(str); + env->ReleaseStringUTFChars(jstr, str); + return cpp_string; +} + +// This is now only used as a trigger for GetAppInfo as a function to all before Init. +// On Android we don't use any of the values it returns. +extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_isLandscape(JNIEnv *env, jclass) { + std::string app_name, app_nice_name, version; + bool landscape; + NativeGetAppInfo(&app_name, &app_nice_name, &landscape, &version); + return landscape; +} + +// Allow the app to intercept the back button. +extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_isAtTopLevel(JNIEnv *env, jclass) { + return NativeIsAtTopLevel(); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_audioConfig + (JNIEnv *env, jclass, jint optimalFPB, jint optimalSR) { + optimalFramesPerBuffer = optimalFPB; + optimalSampleRate = optimalSR; +} + +extern "C" jstring Java_com_henrikrydgard_libnative_NativeApp_queryConfig + (JNIEnv *env, jclass, jstring jquery) { + std::string query = GetJavaString(env, jquery); + std::string result = NativeQueryConfig(query); + jstring jresult = env->NewStringUTF(result.c_str()); + return jresult; +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_init + (JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jint jxres, jint jyres, jstring jlangRegion, jstring japkpath, + jstring jdataDir, jstring jexternalDir, jstring jlibraryDir, jstring jshortcutParam, + jstring jinstallID, jint jAndroidVersion) { + jniEnvUI = env; + + setCurrentThreadName("androidInit"); + + ILOG("NativeApp.init() -- begin"); + PROFILE_INIT(); + + memset(&input_state, 0, sizeof(input_state)); + renderer_inited = false; + first_lost = true; + androidVersion = jAndroidVersion; + deviceType = jdeviceType; + + g_buttonTracker.Reset(); + + left_joystick_x_async = 0; + left_joystick_y_async = 0; + right_joystick_x_async = 0; + right_joystick_y_async = 0; + hat_joystick_x_async = 0; + hat_joystick_y_async = 0; + display_xres = jxres; + display_yres = jyres; + + std::string apkPath = GetJavaString(env, japkpath); + VFSRegister("", new ZipAssetReader(apkPath.c_str(), "assets/")); + + systemName = GetJavaString(env, jmodel); + langRegion = GetJavaString(env, jlangRegion); + + std::string externalDir = GetJavaString(env, jexternalDir); + std::string user_data_path = GetJavaString(env, jdataDir) + "/"; + library_path = GetJavaString(env, jlibraryDir) + "/"; + std::string shortcut_param = GetJavaString(env, jshortcutParam); + std::string installID = GetJavaString(env, jinstallID); + + ILOG("NativeApp.init(): External storage path: %s", externalDir.c_str()); + ILOG("NativeApp.init(): Launch shortcut parameter: %s", shortcut_param.c_str()); + + std::string app_name; + std::string app_nice_name; + std::string version; + bool landscape; + + net::Init(); + + NativeGetAppInfo(&app_name, &app_nice_name, &landscape, &version); + + // If shortcut_param is not empty, pass it as additional varargs argument to NativeInit() method. + // NativeInit() is expected to treat extra argument as boot_filename, which in turn will start game immediately. + // NOTE: Will only work if ppsspp started from Activity.onCreate(). Won't work if ppsspp app start from onResume(). + + if (shortcut_param.empty()) { + const char *argv[2] = {app_name.c_str(), 0}; + NativeInit(1, argv, user_data_path.c_str(), externalDir.c_str(), installID.c_str()); + } + else { + const char *argv[3] = {app_name.c_str(), shortcut_param.c_str(), 0}; + NativeInit(2, argv, user_data_path.c_str(), externalDir.c_str(), installID.c_str()); + } + + ILOG("NativeApp.init() -- end"); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_audioInit(JNIEnv *, jclass) { + sampleRate = optimalSampleRate; + if (NativeQueryConfig("force44khz") != "0" || optimalSampleRate == 0) { + sampleRate = 44100; + } + if (optimalFramesPerBuffer > 0) { + framesPerBuffer = optimalFramesPerBuffer; + } else { + framesPerBuffer = 512; + } + + // Some devices have totally bonkers buffer sizes like 8192. They will have terrible latency anyway, so to avoid having to + // create extra smart buffering code, we'll just let their regular mixer deal with it, missing the fast path (as if they had one...) + if (framesPerBuffer > 512) { + framesPerBuffer = 512; + sampleRate = 44100; + } + + ILOG("NativeApp.audioInit() -- Using OpenSL audio! frames/buffer: %i optimal sr: %i actual sr: %i", optimalFramesPerBuffer, optimalSampleRate, sampleRate); + AndroidAudio_Init(&NativeMix, library_path, framesPerBuffer, sampleRate); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_audioShutdown(JNIEnv *, jclass) { + AndroidAudio_Shutdown(); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_resume(JNIEnv *, jclass) { + ILOG("NativeApp.resume() - resuming audio"); + AndroidAudio_Resume(); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_pause(JNIEnv *, jclass) { + ILOG("NativeApp.pause() - pausing audio"); + AndroidAudio_Pause(); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_shutdown(JNIEnv *, jclass) { + ILOG("NativeApp.shutdown() -- begin"); + NativeShutdown(); + VFSShutdown(); + net::Shutdown(); + ILOG("NativeApp.shutdown() -- end"); +} + +static jmethodID postCommand; + +extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { + ILOG("NativeApp.displayInit()"); + if (!renderer_inited) { + NativeInitGraphics(); + renderer_inited = true; + } else { + NativeDeviceLost(); // ??? + ILOG("displayInit: NativeDeviceLost completed."); + } + + DLOG("(Re)-fetching method ID to postCommand..."); + postCommand = env->GetMethodID(env->GetObjectClass(obj), "postCommand", "(Ljava/lang/String;Ljava/lang/String;)V"); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayResize(JNIEnv *, jobject clazz, jint w, jint h, jint dpi, jfloat refreshRate) { + ILOG("NativeApp.displayResize(%i x %i, dpi=%i, refresh=%0.2f)", w, h, dpi, refreshRate); + + g_dpi = dpi; + g_dpi_scale = 240.0f / (float)g_dpi; + + pixel_xres = w; + pixel_yres = h; + dp_xres = pixel_xres * g_dpi_scale; + dp_yres = pixel_yres * g_dpi_scale; + dp_xscale = (float)dp_xres / pixel_xres; + dp_yscale = (float)dp_yres / pixel_yres; + display_hz = refreshRate; + + NativeResized(); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayRender(JNIEnv *env, jobject obj) { + static bool hasSetThreadName = false; + if (!hasSetThreadName) { + hasSetThreadName = true; + setCurrentThreadName("AndroidRender"); + } + + if (renderer_inited) { + // TODO: Look into if these locks are a perf loss + { + lock_guard guard(input_state.lock); + + input_state.pad_lstick_x = left_joystick_x_async; + input_state.pad_lstick_y = left_joystick_y_async; + input_state.pad_rstick_x = right_joystick_x_async; + input_state.pad_rstick_y = right_joystick_y_async; + + UpdateInputState(&input_state); + } + NativeUpdate(input_state); + + { + lock_guard guard(input_state.lock); + EndInputState(&input_state); + } + + NativeRender(); + time_update(); + } else { + ELOG("BAD: Ended up in nativeRender even though app has quit.%s", ""); + // Shouldn't really get here. Let's draw magenta. + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glClearColor(1.0, 0.0, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } + + lock_guard guard(frameCommandLock); + while (!frameCommands.empty()) { + FrameCommand frameCmd; + frameCmd = frameCommands.front(); + frameCommands.pop(); + + DLOG("frameCommand %s %s", frameCmd.command.c_str(), frameCmd.params.c_str()); + + jstring cmd = env->NewStringUTF(frameCmd.command.c_str()); + jstring param = env->NewStringUTF(frameCmd.params.c_str()); + env->CallVoidMethod(obj, postCommand, cmd, param); + env->DeleteLocalRef(cmd); + env->DeleteLocalRef(param); + } +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayShutdown(JNIEnv *env, jobject obj) { + if (renderer_inited) { + NativeDeviceLost(); + ILOG("NativeDeviceLost completed."); + NativeShutdownGraphics(); + renderer_inited = false; + NativeMessageReceived("recreateviews", ""); + } +} + +extern "C" jboolean JNICALL Java_com_henrikrydgard_libnative_NativeApp_touch + (JNIEnv *, jclass, float x, float y, int code, int pointerId) { + float scaledX = x * dp_xscale; + float scaledY = y * dp_yscale; + + TouchInput touch; + touch.id = pointerId; + touch.x = scaledX; + touch.y = scaledY; + touch.flags = code; + if (code & 2) { + input_state.pointer_down[pointerId] = true; + } else if (code & 4) { + input_state.pointer_down[pointerId] = false; + } + + bool retval = NativeTouch(touch); + { + lock_guard guard(input_state.lock); + if (pointerId >= MAX_POINTERS) { + ELOG("Too many pointers: %i", pointerId); + return false; // We ignore 8+ pointers entirely. + } + input_state.pointer_x[pointerId] = scaledX; + input_state.pointer_y[pointerId] = scaledY; + input_state.mouse_valid = true; + } + return retval; +} + +extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_keyDown(JNIEnv *, jclass, jint deviceId, jint key, jboolean isRepeat) { + KeyInput keyInput; + keyInput.deviceId = deviceId; + keyInput.keyCode = key; + keyInput.flags = KEY_DOWN; + if (isRepeat) { + keyInput.flags |= KEY_IS_REPEAT; + } + return NativeKey(keyInput); +} + +extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_keyUp(JNIEnv *, jclass, jint deviceId, jint key) { + KeyInput keyInput; + keyInput.deviceId = deviceId; + keyInput.keyCode = key; + keyInput.flags = KEY_UP; + return NativeKey(keyInput); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_beginJoystickEvent( + JNIEnv *env, jclass) { + // mutex lock? +} + +extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_joystickAxis( + JNIEnv *env, jclass, jint deviceId, jint axisId, jfloat value) { + if (!renderer_inited) + return false; + switch (axisId) { + case JOYSTICK_AXIS_X: + left_joystick_x_async = value; + break; + case JOYSTICK_AXIS_Y: + left_joystick_y_async = -value; + break; + case JOYSTICK_AXIS_Z: + right_joystick_x_async = value; + break; + case JOYSTICK_AXIS_RZ: + right_joystick_y_async = -value; + break; + case JOYSTICK_AXIS_HAT_X: + hat_joystick_x_async = value; + break; + case JOYSTICK_AXIS_HAT_Y: + hat_joystick_y_async = -value; + break; + } + + AxisInput axis; + axis.axisId = axisId; + axis.deviceId = deviceId; + axis.value = value; + return NativeAxis(axis); +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_endJoystickEvent( + JNIEnv *env, jclass) { + // mutex unlock? +} + + +extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_mouseWheelEvent( + JNIEnv *env, jclass, jint stick, jfloat x, jfloat y) { + // TODO: Support mousewheel for android + return true; +} + +extern "C" jboolean JNICALL Java_com_henrikrydgard_libnative_NativeApp_accelerometer(JNIEnv *, jclass, float x, float y, float z) { + if (!renderer_inited) + return false; + + // Theoretically this needs locking but I doubt it matters. Worst case, the X + // from one "sensor frame" will be used together with Y from the next. + // Should look into quantization though, for compressed movement storage. + input_state.accelerometer_valid = true; + input_state.acc.x = x; + input_state.acc.y = y; + input_state.acc.z = z; + + AxisInput axis; + axis.deviceId = DEVICE_ID_ACCELEROMETER; + axis.flags = 0; + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X; + axis.value = x; + bool retvalX = NativeAxis(axis); + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y; + axis.value = y; + bool retvalY = NativeAxis(axis); + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z; + axis.value = z; + bool retvalZ = NativeAxis(axis); + + return retvalX || retvalY || retvalZ; +} + +extern "C" void Java_com_henrikrydgard_libnative_NativeApp_sendMessage(JNIEnv *env, jclass, jstring message, jstring param) { + std::string msg = GetJavaString(env, message); + std::string prm = GetJavaString(env, param); + + if (msg == "moga") { + mogaVersion = prm; + } + NativeMessageReceived(msg.c_str(), prm.c_str()); +} diff --git a/ext/native/android/app-android.h b/ext/native/android/app-android.h new file mode 100644 index 0000000000..bf842ac54a --- /dev/null +++ b/ext/native/android/app-android.h @@ -0,0 +1,8 @@ +#pragma once + +#include "input/keycodes.h" + +// Compatability we alias the keycodes +// since native's keycodes are based on +// android keycodes. +typedef enum _keycode_t AndroidKeyCodes; diff --git a/ext/native/android/build.xml b/ext/native/android/build.xml new file mode 100644 index 0000000000..65e93a3e9a --- /dev/null +++ b/ext/native/android/build.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/native/android/libs/com.bda.controller.jar b/ext/native/android/libs/com.bda.controller.jar new file mode 100644 index 0000000000..f71dbece34 Binary files /dev/null and b/ext/native/android/libs/com.bda.controller.jar differ diff --git a/ext/native/android/native-audio-so.cpp b/ext/native/android/native-audio-so.cpp new file mode 100644 index 0000000000..901fdeea22 --- /dev/null +++ b/ext/native/android/native-audio-so.cpp @@ -0,0 +1,190 @@ +// Minimal audio streaming using OpenSL. +// +// Loosely based on the Android NDK sample code. + +#include +#include +#include + +// for native audio +#include +#include + +#include "../base/logging.h" +#include "native-audio-so.h" + +// This is kinda ugly, but for simplicity I've left these as globals just like in the sample, +// as there's not really any use case for this where we have multiple audio devices yet. + +// engine interfaces +static SLObjectItf engineObject; +static SLEngineItf engineEngine; +static SLObjectItf outputMixObject; + +// buffer queue player interfaces +static SLObjectItf bqPlayerObject = NULL; +static SLPlayItf bqPlayerPlay; +static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; +static SLMuteSoloItf bqPlayerMuteSolo; +static SLVolumeItf bqPlayerVolume; + +// Double buffering. +static short *buffer[2]; +static int curBuffer = 0; +static int framesPerBuffer; +int sampleRate; + +static AndroidAudioCallback audioCallback; + +// This callback handler is called every time a buffer finishes playing. +// The documentation available is very unclear about how to best manage buffers. +// I've chosen to this approach: Instantly enqueue a buffer that was rendered to the last time, +// and then render the next. Hopefully it's okay to spend time in this callback after having enqueued. +static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { + if (bq != bqPlayerBufferQueue) { + ELOG("Wrong bq!"); + return; + } + + int renderedFrames = audioCallback(buffer[curBuffer], framesPerBuffer); + + int sizeInBytes = framesPerBuffer * 2 * sizeof(short); + int byteCount = (framesPerBuffer - renderedFrames) * 4; + if (byteCount > 0) { + memset(buffer[curBuffer] + renderedFrames * 2, 0, byteCount); + } + SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeInBytes); + + // Comment from sample code: + // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, + // which for this code example would indicate a programming error + if (result != SL_RESULT_SUCCESS) { + ELOG("OpenSL ES: Failed to enqueue! %i %i", renderedFrames, sizeInBytes); + } + + curBuffer ^= 1; // Switch buffer +} + +// create the engine and output mix objects +bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate) { + audioCallback = cb; + framesPerBuffer = _FramesPerBuffer; + if (framesPerBuffer == 0) + framesPerBuffer = 256; + if (framesPerBuffer < 32) + framesPerBuffer = 32; + sampleRate = _SampleRate; + if (sampleRate != 44100 && sampleRate != 48000) { + ELOG("Invalid sample rate %i - choosing 44100", sampleRate); + sampleRate = 44100; + } + + buffer[0] = new short[framesPerBuffer * 2]; + buffer[1] = new short[framesPerBuffer * 2]; + + SLresult result; + // create engine + result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); + assert(SL_RESULT_SUCCESS == result); + result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); + assert(SL_RESULT_SUCCESS == result); + result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); + assert(SL_RESULT_SUCCESS == result); + result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0); + assert(SL_RESULT_SUCCESS == result); + result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); + assert(SL_RESULT_SUCCESS == result); + + SLuint32 sr = SL_SAMPLINGRATE_44_1; + if (sampleRate == 48000) { + sr = SL_SAMPLINGRATE_48; + } + + SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; + SLDataFormat_PCM format_pcm = { + SL_DATAFORMAT_PCM, + 2, + sr, + SL_PCMSAMPLEFORMAT_FIXED_16, + SL_PCMSAMPLEFORMAT_FIXED_16, + SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, + SL_BYTEORDER_LITTLEENDIAN + }; + + SLDataSource audioSrc = {&loc_bufq, &format_pcm}; + + // configure audio sink + SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject}; + SLDataSink audioSnk = {&loc_outmix, NULL}; + + // create audio player + const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME}; + const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; + result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req); + assert(SL_RESULT_SUCCESS == result); + + result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, + &bqPlayerBufferQueue); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); + assert(SL_RESULT_SUCCESS == result); + + // Render and enqueue a first buffer. (or should we just play the buffer empty?) + curBuffer = 0; + audioCallback(buffer[curBuffer], framesPerBuffer); + + result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[curBuffer])); + if (SL_RESULT_SUCCESS != result) { + return false; + } + curBuffer ^= 1; + return true; +} + +// shut down the native audio system +void OpenSLWrap_Shutdown() { + SLresult result; + ILOG("OpenSLWrap_Shutdown - stopping playback"); + result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED); + if (SL_RESULT_SUCCESS != result) { + ELOG("SetPlayState failed"); + } + + ILOG("OpenSLWrap_Shutdown - deleting player object"); + + if (bqPlayerObject != NULL) { + (*bqPlayerObject)->Destroy(bqPlayerObject); + bqPlayerObject = NULL; + bqPlayerPlay = NULL; + bqPlayerBufferQueue = NULL; + bqPlayerMuteSolo = NULL; + bqPlayerVolume = NULL; + } + + ILOG("OpenSLWrap_Shutdown - deleting mix object"); + + if (outputMixObject != NULL) { + (*outputMixObject)->Destroy(outputMixObject); + outputMixObject = NULL; + } + + ILOG("OpenSLWrap_Shutdown - deleting engine object"); + + if (engineObject != NULL) { + (*engineObject)->Destroy(engineObject); + engineObject = NULL; + engineEngine = NULL; + } + delete [] buffer[0]; + delete [] buffer[1]; + ILOG("OpenSLWrap_Shutdown - finished"); +} + diff --git a/ext/native/android/native-audio-so.h b/ext/native/android/native-audio-so.h new file mode 100644 index 0000000000..72d36db6a5 --- /dev/null +++ b/ext/native/android/native-audio-so.h @@ -0,0 +1,6 @@ +#pragma once + +typedef int (*AndroidAudioCallback)(short *buffer, int num_samples); + +bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate); +void OpenSLWrap_Shutdown(); \ No newline at end of file diff --git a/ext/native/android/native_audio.cpp b/ext/native/android/native_audio.cpp new file mode 100644 index 0000000000..a96dc1bf02 --- /dev/null +++ b/ext/native/android/native_audio.cpp @@ -0,0 +1,71 @@ +#include "base/logging.h" +#include "android/native_audio.h" +#include "android/native-audio-so.h" + +struct AudioState { + void *so; + AndroidAudioCallback callback; + bool playing; + int frames_per_buffer; + int sample_rate; +}; + +static AudioState *state = 0; + +bool AndroidAudio_Init(AndroidAudioCallback callback, std::string libraryDir, int optimalFramesPerBuffer, int optimalSampleRate) { + if (state != 0) { + ELOG("Audio state already exists"); + return false; + } + + state = new AudioState(); + state->callback = callback; + state->playing = false; + state->frames_per_buffer = optimalFramesPerBuffer ? optimalFramesPerBuffer : 256; + state->sample_rate = optimalSampleRate ? optimalSampleRate : 44100; + + return true; +} + +bool AndroidAudio_Resume() { + if (!state) { + ELOG("Audio was shutdown, cannot resume!"); + return false; + } + if (!state->playing) { + ILOG("Calling OpenSLWrap_Init_T..."); + bool init_retval = OpenSLWrap_Init(state->callback, state->frames_per_buffer, state->sample_rate); + ILOG("Returned from OpenSLWrap_Init_T"); + state->playing = true; + return init_retval; + } + return false; +} + +bool AndroidAudio_Pause() { + if (!state) { + ELOG("Audio was shutdown, cannot pause!"); + return false; + } + if (state->playing) { + ILOG("Calling OpenSLWrap_Shutdown_T..."); + OpenSLWrap_Shutdown(); + ILOG("Returned from OpenSLWrap_Shutdown_T ..."); + state->playing = false; + return true; + } + return false; +} + +void AndroidAudio_Shutdown() { + if (!state) { + ELOG("Audio already shutdown!"); + return; + } + if (state->playing) { + ELOG("Should not shut down when playing! Something is wrong!"); + } + delete state; + state = 0; + ILOG("OpenSLWrap completely unloaded."); +} diff --git a/ext/native/android/native_audio.h b/ext/native/android/native_audio.h new file mode 100644 index 0000000000..82b3de7ee2 --- /dev/null +++ b/ext/native/android/native_audio.h @@ -0,0 +1,16 @@ +#pragma once + +#include "native-audio-so.h" +#include + +// This is the file you should include from your program. It dynamically loads +// the native_audio.so shared object and sets up the function pointers. + +// Do not call this if you have detected that the android version is below +// 2.2, as it will fail miserably. + +// It's okay for optimalFramesPerBuffer and optimalSampleRate to be 0. Defaults will be used. +bool AndroidAudio_Init(AndroidAudioCallback cb, std::string libraryDir, int optimalFramesPerBuffer, int optimalSampleRate); +bool AndroidAudio_Pause(); +bool AndroidAudio_Resume(); +void AndroidAudio_Shutdown(); diff --git a/ext/native/android/proguard-project.txt b/ext/native/android/proguard-project.txt new file mode 100644 index 0000000000..f2fe1559a2 --- /dev/null +++ b/ext/native/android/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/ext/native/android/project.properties b/ext/native/android/project.properties new file mode 100644 index 0000000000..9f2199fbd5 --- /dev/null +++ b/ext/native/android/project.properties @@ -0,0 +1,15 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}\tools\proguard\proguard-android.txt:proguard-project.txt + +# Project target. +target=android-22 +android.library=true diff --git a/ext/native/android/res/drawable-hdpi/ic_launcher.png b/ext/native/android/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000..96a442e5b8 Binary files /dev/null and b/ext/native/android/res/drawable-hdpi/ic_launcher.png differ diff --git a/ext/native/android/res/drawable-ldpi/ic_launcher.png b/ext/native/android/res/drawable-ldpi/ic_launcher.png new file mode 100644 index 0000000000..99238729d8 Binary files /dev/null and b/ext/native/android/res/drawable-ldpi/ic_launcher.png differ diff --git a/ext/native/android/res/drawable-mdpi/ic_launcher.png b/ext/native/android/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000..359047dfa4 Binary files /dev/null and b/ext/native/android/res/drawable-mdpi/ic_launcher.png differ diff --git a/ext/native/android/res/drawable-xhdpi/ic_launcher.png b/ext/native/android/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000..71c6d760f0 Binary files /dev/null and b/ext/native/android/res/drawable-xhdpi/ic_launcher.png differ diff --git a/ext/native/android/src/com/henrikrydgard/libnative/AudioFocusChangeListener.java b/ext/native/android/src/com/henrikrydgard/libnative/AudioFocusChangeListener.java new file mode 100644 index 0000000000..1415e704ff --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/AudioFocusChangeListener.java @@ -0,0 +1,26 @@ +package com.henrikrydgard.libnative; +import android.media.AudioManager; +import android.media.AudioManager.OnAudioFocusChangeListener; + +public class AudioFocusChangeListener implements OnAudioFocusChangeListener{ + // not used right now, but we may need to use it sometime. So just store it + // for now. + private boolean hasAudioFocus = false; + + @Override + public void onAudioFocusChange(int focusChange) { + switch (focusChange){ + case AudioManager.AUDIOFOCUS_GAIN: + hasAudioFocus = true; + break; + + case AudioManager.AUDIOFOCUS_LOSS: + hasAudioFocus = false; + break; + } + } + + public boolean hasAudioFocus() { + return hasAudioFocus; + } +} diff --git a/ext/native/android/src/com/henrikrydgard/libnative/InputDeviceState.java b/ext/native/android/src/com/henrikrydgard/libnative/InputDeviceState.java new file mode 100644 index 0000000000..f572c44dee --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/InputDeviceState.java @@ -0,0 +1,93 @@ +package com.henrikrydgard.libnative; + +import android.annotation.TargetApi; +import android.os.Build; +import android.util.Log; +import android.view.InputDevice; +import android.view.InputDevice.MotionRange; +import android.view.KeyEvent; +import android.view.MotionEvent; + +@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) +public class InputDeviceState { + private static final String TAG = "InputDeviceState"; + + private static final int deviceId = NativeApp.DEVICE_ID_PAD_0; + + private InputDevice mDevice; + private int[] mAxes; + + InputDevice getDevice() { return mDevice; } + + @TargetApi(19) + void logAdvanced(InputDevice device) { + Log.i(TAG, "Vendor ID:" + device.getVendorId() + " productId: " + device.getProductId()); + } + + public InputDeviceState(InputDevice device) { + mDevice = device; + int numAxes = 0; + for (MotionRange range : device.getMotionRanges()) { + if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { + numAxes += 1; + } + } + + mAxes = new int[numAxes]; + + int i = 0; + for (MotionRange range : device.getMotionRanges()) { + if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { + mAxes[i++] = range.getAxis(); + } + } + + Log.i(TAG, "Registering input device with " + numAxes + " axes: " + device.getName()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + logAdvanced(device); + } + NativeApp.sendMessage("inputDeviceConnected", device.getName()); + } + + public static float ProcessAxis(InputDevice.MotionRange range, float axisvalue) { + float absaxisvalue = Math.abs(axisvalue); + float deadzone = range.getFlat(); + if (absaxisvalue <= deadzone) { + return 0.0f; + } + float normalizedvalue; + if (axisvalue < 0.0f) { + normalizedvalue = absaxisvalue / range.getMin(); + } else { + normalizedvalue = absaxisvalue / range.getMax(); + } + + return normalizedvalue; + } + + public boolean onKeyDown(KeyEvent event) { + int keyCode = event.getKeyCode(); + boolean repeat = event.getRepeatCount() > 0; + return NativeApp.keyDown(deviceId, keyCode, repeat); + } + + public boolean onKeyUp(KeyEvent event) { + int keyCode = event.getKeyCode(); + return NativeApp.keyUp(deviceId, keyCode); + } + + public boolean onJoystickMotion(MotionEvent event) { + if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0) { + return false; + } + NativeApp.beginJoystickEvent(); + for (int i = 0; i < mAxes.length; i++) { + int axisId = mAxes[i]; + float value = event.getAxisValue(axisId); + // TODO: Use processAxis or move that to the C++ code + NativeApp.joystickAxis(deviceId, axisId, value); + } + NativeApp.endJoystickEvent(); + return true; + } +} diff --git a/ext/native/android/src/com/henrikrydgard/libnative/Installation.java b/ext/native/android/src/com/henrikrydgard/libnative/Installation.java new file mode 100644 index 0000000000..dffa7cc441 --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/Installation.java @@ -0,0 +1,46 @@ +package com.henrikrydgard.libnative; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.UUID; + +import android.content.Context; + + +public class Installation { + private static String sID = null; + private static final String INSTALLATION = "INSTALLATION"; + + public synchronized static String id(Context context) { + if (sID == null) { + File installation = new File(context.getFilesDir(), INSTALLATION); + try { + if (!installation.exists()) + writeInstallationFile(installation); + sID = readInstallationFile(installation); + } catch (Exception e) { + // We can't even open a file for writing? Then we can't get a unique-ish installation id. + return "BROKENAPPUSERFILESYSTEM"; + } + } + return sID; + } + + private static String readInstallationFile(File installation) throws IOException { + RandomAccessFile f = new RandomAccessFile(installation, "r"); + byte[] bytes = new byte[(int) f.length()]; + f.readFully(bytes); + f.close(); + return new String(bytes); + } + + private static void writeInstallationFile(File installation) throws IOException { + FileOutputStream out = new FileOutputStream(installation); + String id = UUID.randomUUID().toString(); + out.write(id.getBytes()); + out.close(); + } +} + \ No newline at end of file diff --git a/ext/native/android/src/com/henrikrydgard/libnative/MogaHack.java b/ext/native/android/src/com/henrikrydgard/libnative/MogaHack.java new file mode 100644 index 0000000000..74bda85f79 --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/MogaHack.java @@ -0,0 +1,118 @@ +/** + * Mupen64PlusAE, an N64 emulator for the Android platform + * + * Copyright (C) 2013 Paul Lamb + * + * This file is part of Mupen64PlusAE. + * + * Mupen64PlusAE 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. + * + * Mupen64PlusAE is distributed in the hope that 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 Mupen64PlusAE. If + * not, see . + * + * Authors: Paul Lamb + */ +package com.henrikrydgard.libnative; + +import java.util.List; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.os.Build; +import android.util.Log; + +import com.bda.controller.Controller; +import com.bda.controller.IControllerService; + +/** + * Temporary hack for crash in MOGA library on Lollipop. This hack can be removed once MOGA fixes + * their library. The actual issue is caused by the use of implicit service intents, which are + * illegal in Lollipop, as seen in the logcat message below. + * + *
+ * {@code Service Intent must be explicit: Intent { act=com.bda.controller.IControllerService } }
+ * 
+ * + * @see MOGA developer site + * @see + * Discussion on explicit intents + */ +public class MogaHack +{ + public static void init(Controller controller, Context context ) + { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) + { + boolean mIsBound = false; + java.lang.reflect.Field fIsBound = null; + android.content.ServiceConnection mServiceConnection = null; + java.lang.reflect.Field fServiceConnection = null; + try + { + Class cMogaController = controller.getClass(); + fIsBound = cMogaController.getDeclaredField( "mIsBound" ); + fIsBound.setAccessible( true ); + mIsBound = fIsBound.getBoolean( controller ); + fServiceConnection = cMogaController.getDeclaredField( "mServiceConnection" ); + fServiceConnection.setAccessible( true ); + mServiceConnection = ( android.content.ServiceConnection ) fServiceConnection.get( controller ); + } + catch( NoSuchFieldException e ) + { + Log.e( "MogaHack", "MOGA Lollipop Hack NoSuchFieldException (get)", e ); + } + catch( IllegalAccessException e ) + { + Log.e( "MogaHack", "MOGA Lollipop Hack IllegalAccessException (get)", e ); + } + catch( IllegalArgumentException e ) + { + Log.e( "MogaHack", "MOGA Lollipop Hack IllegalArgumentException (get)", e ); + } + if( ( !mIsBound ) && ( mServiceConnection != null ) ) + { + // Convert implicit intent to explicit intent, see http://stackoverflow.com/a/26318757 + Intent intent = new Intent( IControllerService.class.getName() ); + List resolveInfos = context.getPackageManager().queryIntentServices( intent, 0 ); + if( resolveInfos == null || resolveInfos.size() != 1 ) + { + // What? this doesn't do anything. + // Log.e( "MogaHack", "Somebody is trying to intercept our intent. Disabling MOGA controller for security." ); + } + ServiceInfo serviceInfo = resolveInfos.get( 0 ).serviceInfo; + String packageName = serviceInfo.packageName; + String className = serviceInfo.name; + intent.setComponent( new ComponentName( packageName, className ) ); + + // Start the service explicitly + context.startService( intent ); + context.bindService( intent, mServiceConnection, 1 ); + try + { + fIsBound.setBoolean( controller, true ); + } + catch( IllegalAccessException e ) + { + Log.e( "MogaHack", "MOGA Lollipop Hack IllegalAccessException (set)", e ); + } + catch( IllegalArgumentException e ) + { + Log.e( "MogaHack", "MOGA Lollipop Hack IllegalArgumentException (set)", e ); + } + } + } + else + { + controller.init(); + } + } +} diff --git a/ext/native/android/src/com/henrikrydgard/libnative/NativeActivity.java b/ext/native/android/src/com/henrikrydgard/libnative/NativeActivity.java new file mode 100644 index 0000000000..9bc0648411 --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/NativeActivity.java @@ -0,0 +1,875 @@ +package com.henrikrydgard.libnative; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Locale; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.ActivityManager; +import android.app.AlertDialog; +import android.app.UiModeManager; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.ConfigurationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Configuration; +import android.graphics.PixelFormat; +import android.graphics.Point; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Vibrator; +import android.text.InputType; +import android.util.Log; +import android.view.Display; +import android.view.Gravity; +import android.view.InputDevice; +import android.view.InputEvent; +import android.view.KeyEvent; +import android.view.HapticFeedbackConstants; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnSystemUiVisibilityChangeListener; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.Toast; + +public class NativeActivity extends Activity { + // Remember to loadLibrary your JNI .so in a static {} block + + // Adjust these as necessary + private static String TAG = "NativeActivity"; + + // Allows us to skip a lot of initialization on secondary calls to onCreate. + private static boolean initialized = false; + + // Graphics and audio interfaces + private NativeGLView mGLSurfaceView; + protected NativeRenderer nativeRenderer; + + private String shortcutParam = ""; + + public static String runCommand; + public static String commandParameter; + public static String installID; + + // Remember settings for best audio latency + private int optimalFramesPerBuffer; + private int optimalSampleRate; + + // audioFocusChangeListener to listen to changes in audio state + private AudioFocusChangeListener audioFocusChangeListener; + private AudioManager audioManager; + + private Vibrator vibrator; + + private boolean isXperiaPlay; + + // Allow for multiple connected gamepads but just consider them the same for now. + // Actually this is not entirely true, see the code. + InputDeviceState inputPlayerA; + InputDeviceState inputPlayerB; + InputDeviceState inputPlayerC; + String inputPlayerADesc; + + // Functions for the app activity to override to change behaviour. + + public boolean useLowProfileButtons() { + return true; + } + + NativeRenderer getRenderer() { + return nativeRenderer; + } + + @TargetApi(17) + private void detectOptimalAudioSettings() { + try { + optimalFramesPerBuffer = Integer.parseInt(this.audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)); + } catch (NumberFormatException e) { + // Ignore, if we can't parse it it's bogus and zero is a fine value (means we couldn't detect it). + } + try { + optimalSampleRate = Integer.parseInt(this.audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); + } catch (NumberFormatException e) { + // Ignore, if we can't parse it it's bogus and zero is a fine value (means we couldn't detect it). + } + } + + String getApplicationLibraryDir(ApplicationInfo application) { + String libdir = null; + try { + // Starting from Android 2.3, nativeLibraryDir is available: + Field field = ApplicationInfo.class.getField("nativeLibraryDir"); + libdir = (String) field.get(application); + } catch (SecurityException e1) { + } catch (NoSuchFieldException e1) { + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } + if (libdir == null) { + // Fallback for Android < 2.3: + libdir = application.dataDir + "/lib"; + } + return libdir; + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) + void GetScreenSizeJB(Point size, boolean real) { + WindowManager w = getWindowManager(); + if (real) { + w.getDefaultDisplay().getRealSize(size); + } + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) + void GetScreenSizeHC(Point size, boolean real) { + WindowManager w = getWindowManager(); + if (real && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + GetScreenSizeJB(size, real); + } else { + w.getDefaultDisplay().getSize(size); + } + } + + @SuppressWarnings("deprecation") + public void GetScreenSize(Point size) { + boolean real = useImmersive(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { + GetScreenSizeHC(size, real); + } else { + WindowManager w = getWindowManager(); + Display d = w.getDefaultDisplay(); + size.x = d.getWidth(); + size.y = d.getHeight(); + } + } + + public void setShortcutParam(String shortcutParam) { + this.shortcutParam = ((shortcutParam == null) ? "" : shortcutParam); + } + + public void Initialize() { + // Initialize audio classes. Do this here since detectOptimalAudioSettings() + // needs audioManager + this.audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE); + this.audioFocusChangeListener = new AudioFocusChangeListener(); + + if (Build.VERSION.SDK_INT >= 17) { + // Get the optimal buffer sz + detectOptimalAudioSettings(); + } + + // isLandscape is used to trigger GetAppInfo currently, we + boolean landscape = NativeApp.isLandscape(); + Log.d(TAG, "Landscape: " + landscape); + + // Get system information + ApplicationInfo appInfo = null; + PackageManager packMgmr = getPackageManager(); + String packageName = getPackageName(); + try { + appInfo = packMgmr.getApplicationInfo(packageName, 0); + } catch (NameNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException("Unable to locate assets, aborting..."); + } + + int deviceType = NativeApp.DEVICE_TYPE_MOBILE; + UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE); + switch (uiModeManager.getCurrentModeType()) { + case Configuration.UI_MODE_TYPE_TELEVISION: + deviceType = NativeApp.DEVICE_TYPE_TV; + Log.i(TAG, "Running on an Android TV Device"); + break; + case Configuration.UI_MODE_TYPE_DESK: + deviceType = NativeApp.DEVICE_TYPE_DESKTOP; + Log.i(TAG, "Running on an Android desktop computer (!)"); + break; + // All other device types are treated the same. + } + + isXperiaPlay = IsXperiaPlay(); + + String libraryDir = getApplicationLibraryDir(appInfo); + File sdcard = Environment.getExternalStorageDirectory(); + + String externalStorageDir = sdcard.getAbsolutePath(); + String dataDir = this.getFilesDir().getAbsolutePath(); + String apkFilePath = appInfo.sourceDir; + + String model = Build.MANUFACTURER + ":" + Build.MODEL; + String languageRegion = Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry(); + + Point displaySize = new Point(); + GetScreenSize(displaySize); + NativeApp.audioConfig(optimalFramesPerBuffer, optimalSampleRate); + NativeApp.init(model, deviceType, displaySize.x, displaySize.y, languageRegion, apkFilePath, dataDir, externalStorageDir, libraryDir, shortcutParam, installID, Build.VERSION.SDK_INT); + + NativeApp.sendMessage("cacheDir", getCacheDir().getAbsolutePath()); + + // OK, config should be initialized, we can query for screen rotation. + if (Build.VERSION.SDK_INT >= 9) { + updateScreenRotation(); + } + + // Detect OpenGL support. + // We don't currently use this detection for anything but good to have in the log. + if (!detectOpenGLES20()) { + Log.i(TAG, "OpenGL ES 2.0 NOT detected. Things will likely go badly."); + } else { + if (detectOpenGLES30()) { + Log.i(TAG, "OpenGL ES 3.0 detected."); + } + else { + Log.i(TAG, "OpenGL ES 2.0 detected."); + } + } + + vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE); + if (Build.VERSION.SDK_INT >= 11) { + checkForVibrator(); + } + } + + @TargetApi(9) + private void updateScreenRotation() { + // Query the native application on the desired rotation. + int rot = 0; + String rotString = NativeApp.queryConfig("screenRotation"); + try { + rot = Integer.parseInt(rotString); + } catch (NumberFormatException e) { + Log.e(TAG, "Invalid rotation: " + rotString); + return; + } + switch (rot) { + case 0: + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + break; + case 1: + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + break; + case 2: + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + break; + case 3: + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); + break; + case 4: + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); + break; + } + } + + private boolean useImmersive() { + String immersive = NativeApp.queryConfig("immersiveMode"); + return immersive.equals("1") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + } + + @SuppressLint("InlinedApi") + @TargetApi(14) + private void updateSystemUiVisibility() { + int flags = 0; + if (useLowProfileButtons()) { + flags |= View.SYSTEM_UI_FLAG_LOW_PROFILE; + } + if (useImmersive()) { + flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + } + if (getWindow().getDecorView() != null) { + getWindow().getDecorView().setSystemUiVisibility(flags); + } else { + Log.e(TAG, "updateSystemUiVisibility: decor view not yet created, ignoring"); + } + } + + // Need API 11 to check for existence of a vibrator? Zany. + @TargetApi(11) + public void checkForVibrator() { + if (Build.VERSION.SDK_INT >= 11) { + if (!vibrator.hasVibrator()) { + vibrator = null; + } + } + } + + // Override this to scale the backbuffer (use the Android hardware scaler) + public void getDesiredBackbufferSize(Point sz) { + sz.x = 0; + sz.y = 0; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + installID = Installation.id(this); + + if (!initialized) { + Initialize(); + initialized = true; + } + // Keep the screen bright - very annoying if it goes dark when tilting away + Window window = this.getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + setVolumeControlStream(AudioManager.STREAM_MUSIC); + + gainAudioFocus(this.audioManager, this.audioFocusChangeListener); + NativeApp.audioInit(); + + mGLSurfaceView = new NativeGLView(this); + nativeRenderer = new NativeRenderer(this); + + Point sz = new Point(); + getDesiredBackbufferSize(sz); + if (sz.x > 0) { + Log.i(TAG, "Requesting fixed size buffer: " + sz.x + "x" + sz.y); + // Auto-calculates new DPI and forwards to the correct call on mGLSurfaceView.getHolder() + nativeRenderer.setFixedSize(sz.x, sz.y, mGLSurfaceView); + } + mGLSurfaceView.setEGLContextClientVersion(2); + + // Setup the GLSurface and ask android for the correct + // Number of bits for r, g, b, a, depth and stencil components + // The PSP only has 16-bit Z so that should be enough. + // Might want to change this for other apps (24-bit might be useful). + // Actually, we might be able to do without both stencil and depth in + // the back buffer, but that would kill non-buffered rendering. + + // It appears some gingerbread devices blow up if you use a config chooser at all ???? (Xperia Play) + //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + + // On some (especially older devices), things blow up later (EGL_BAD_MATCH) if we don't set the format here, + // if we specify that we want destination alpha in the config chooser, which we do. + // http://grokbase.com/t/gg/android-developers/11bj40jm4w/fall-back + + + // Needed to avoid banding on Ouya? + if (Build.MANUFACTURER == "OUYA") { + mGLSurfaceView.getHolder().setFormat(PixelFormat.RGBX_8888); + mGLSurfaceView.setEGLConfigChooser(new NativeEGLConfigChooser()); + } + + mGLSurfaceView.setRenderer(nativeRenderer); + setContentView(mGLSurfaceView); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + updateSystemUiVisibility(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + setupSystemUiCallback(); + } + } + } + + @TargetApi(19) + void setupSystemUiCallback() { + getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() { + @Override + public void onSystemUiVisibilityChange(int visibility) { + if (visibility == 0) { + updateSystemUiVisibility(); + } + } + }); + } + + @Override + protected void onStop() { + super.onStop(); + Log.i(TAG, "onStop - do nothing special"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.i(TAG, "onDestroy"); + mGLSurfaceView.onDestroy(); + nativeRenderer.onDestroyed(); + NativeApp.audioShutdown(); + // Probably vain attempt to help the garbage collector... + mGLSurfaceView = null; + audioFocusChangeListener = null; + audioManager = null; + } + + private boolean detectOpenGLES20() { + ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return info.reqGlEsVersion >= 0x20000; + } + + private boolean detectOpenGLES30() { + ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return info.reqGlEsVersion >= 0x30000; + } + + @Override + protected void onPause() { + super.onPause(); + Log.i(TAG, "onPause"); + loseAudioFocus(this.audioManager, this.audioFocusChangeListener); + NativeApp.pause(); + mGLSurfaceView.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + updateSystemUiVisibility(); + } + // OK, config should be initialized, we can query for screen rotation. + if (Build.VERSION.SDK_INT >= 9) { + updateScreenRotation(); + } + + Log.i(TAG, "onResume"); + if (mGLSurfaceView != null) { + mGLSurfaceView.onResume(); + } else { + Log.e(TAG, "mGLSurfaceView really shouldn't be null in onResume"); + } + + gainAudioFocus(this.audioManager, this.audioFocusChangeListener); + NativeApp.resume(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + updateSystemUiVisibility(); + } + + Point sz = new Point(); + getDesiredBackbufferSize(sz); + if (sz.x > 0) { + mGLSurfaceView.getHolder().setFixedSize(sz.x/2, sz.y/2); + } + } + + //keep this static so we can call this even if we don't + //instantiate NativeAudioPlayer + public static void gainAudioFocus(AudioManager audioManager, AudioFocusChangeListener focusChangeListener) { + if (audioManager != null) { + audioManager.requestAudioFocus(focusChangeListener, + AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); + } + } + + //keep this static so we can call this even if we don't + //instantiate NativeAudioPlayer + public static void loseAudioFocus(AudioManager audioManager,AudioFocusChangeListener focusChangeListener){ + if (audioManager != null) { + audioManager.abandonAudioFocus(focusChangeListener); + } + } + + // We simply grab the first input device to produce an event and ignore all others that are connected. + @TargetApi(Build.VERSION_CODES.GINGERBREAD) + private InputDeviceState getInputDeviceState(InputEvent event) { + InputDevice device = event.getDevice(); + if (device == null) { + return null; + } + if (inputPlayerA == null) { + inputPlayerADesc = getInputDesc(device); + Log.i(TAG, "Input player A registered: desc = " + inputPlayerADesc); + inputPlayerA = new InputDeviceState(device); + } + + if (inputPlayerA.getDevice() == device) { + return inputPlayerA; + } + + if (inputPlayerB == null) { + Log.i(TAG, "Input player B registered: desc = " + getInputDesc(device)); + inputPlayerB = new InputDeviceState(device); + } + + if (inputPlayerB.getDevice() == device) { + return inputPlayerB; + } + + if (inputPlayerC == null) { + Log.i(TAG, "Input player C registered"); + inputPlayerC = new InputDeviceState(device); + } + + if (inputPlayerC.getDevice() == device) { + return inputPlayerC; + } + + return inputPlayerA; + } + + public boolean IsXperiaPlay() { + return android.os.Build.MODEL.equals("R800a") || android.os.Build.MODEL.equals("R800i") || android.os.Build.MODEL.equals("R800x") || android.os.Build.MODEL.equals("R800at") || android.os.Build.MODEL.equals("SO-01D") || android.os.Build.MODEL.equals("zeus"); + } + + // We grab the keys before onKeyDown/... even see them. This is also better because it lets us + // distinguish devices. + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && !isXperiaPlay) { + InputDeviceState state = getInputDeviceState(event); + if (state == null) { + return super.dispatchKeyEvent(event); + } + + // Let's let back and menu through to dispatchKeyEvent. + boolean passThrough = false; + + switch (event.getKeyCode()) { + case KeyEvent.KEYCODE_BACK: + case KeyEvent.KEYCODE_MENU: + passThrough = true; + break; + default: + break; + } + + // Don't passthrough back button if gamepad. + int sources = event.getSource(); + switch (sources) { + case InputDevice.SOURCE_GAMEPAD: + case InputDevice.SOURCE_JOYSTICK: + case InputDevice.SOURCE_DPAD: + passThrough = false; + break; + } + + if (!passThrough) { + switch (event.getAction()) { + case KeyEvent.ACTION_DOWN: + if (state.onKeyDown(event)) { + return true; + } + break; + + case KeyEvent.ACTION_UP: + if (state.onKeyUp(event)) { + return true; + } + break; + } + } + } + + // Let's go through the old path (onKeyUp, onKeyDown). + return super.dispatchKeyEvent(event); + } + + @TargetApi(16) + static public String getInputDesc(InputDevice input) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + return input.getDescriptor(); + } else { + List motions = input.getMotionRanges(); + String fakeid = ""; + for (InputDevice.MotionRange range : motions) + fakeid += range.getAxis(); + return fakeid; + } + } + + @Override + @TargetApi(12) + public boolean onGenericMotionEvent(MotionEvent event) { + // Log.d(TAG, "onGenericMotionEvent: " + event); + if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) { + if (Build.VERSION.SDK_INT >= 12) { + InputDeviceState state = getInputDeviceState(event); + if (state == null) { + Log.w(TAG, "Joystick event but failed to get input device state."); + return super.onGenericMotionEvent(event); + } + state.onJoystickMotion(event); + return true; + } + } + + if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { + switch (event.getAction()) { + case MotionEvent.ACTION_HOVER_MOVE: + // process the mouse hover movement... + return true; + case MotionEvent.ACTION_SCROLL: + NativeApp.mouseWheelEvent(event.getX(), event.getY()); + return true; + } + } + return super.onGenericMotionEvent(event); + } + + @SuppressLint("NewApi") + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + // Eat these keys, to avoid accidental exits / other screwups. + // Maybe there's even more we need to eat on tablets? + boolean repeat = event.getRepeatCount() > 0; + switch (keyCode) { + case KeyEvent.KEYCODE_BACK: + if (event.isAltPressed()) { + NativeApp.keyDown(0, 1004, repeat); // special custom keycode for the O button on Xperia Play + } else if (NativeApp.isAtTopLevel()) { + Log.i(TAG, "IsAtTopLevel returned true."); + // Pass through the back event. + return super.onKeyDown(keyCode, event); + } else { + NativeApp.keyDown(0, keyCode, repeat); + } + return true; + case KeyEvent.KEYCODE_MENU: + case KeyEvent.KEYCODE_SEARCH: + NativeApp.keyDown(0, keyCode, repeat); + return true; + + case KeyEvent.KEYCODE_DPAD_UP: + case KeyEvent.KEYCODE_DPAD_DOWN: + case KeyEvent.KEYCODE_DPAD_LEFT: + case KeyEvent.KEYCODE_DPAD_RIGHT: + // Joysticks are supported in Honeycomb MR1 and later via the onGenericMotionEvent method. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && event.getSource() == InputDevice.SOURCE_JOYSTICK) { + return super.onKeyDown(keyCode, event); + } + // Fall through + default: + // send the rest of the keys through. + // TODO: get rid of the three special cases above by adjusting the native side of the code. + // Log.d(TAG, "Key down: " + keyCode + ", KeyEvent: " + event); + return NativeApp.keyDown(0, keyCode, repeat); + } + } + + @SuppressLint("NewApi") + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) { + switch (keyCode) { + case KeyEvent.KEYCODE_BACK: + if (event.isAltPressed()) { + NativeApp.keyUp(0, 1004); // special custom keycode + } else if (NativeApp.isAtTopLevel()) { + Log.i(TAG, "IsAtTopLevel returned true."); + return super.onKeyUp(keyCode, event); + } else { + NativeApp.keyUp(0, keyCode); + } + return true; + case KeyEvent.KEYCODE_MENU: + case KeyEvent.KEYCODE_SEARCH: + // Search probably should also be ignored. We send it to the app. + NativeApp.keyUp(0, keyCode); + return true; + + case KeyEvent.KEYCODE_DPAD_UP: + case KeyEvent.KEYCODE_DPAD_DOWN: + case KeyEvent.KEYCODE_DPAD_LEFT: + case KeyEvent.KEYCODE_DPAD_RIGHT: + // Joysticks are supported in Honeycomb MR1 and later via the onGenericMotionEvent method. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && event.getSource() == InputDevice.SOURCE_JOYSTICK) { + return super.onKeyUp(keyCode, event); + } + // Fall through + default: + // send the rest of the keys through. + // TODO: get rid of the three special cases above by adjusting the native side of the code. + // Log.d(TAG, "Key down: " + keyCode + ", KeyEvent: " + event); + return NativeApp.keyUp(0, keyCode); + } + } + + + @TargetApi(11) + private AlertDialog.Builder createDialogBuilderWithTheme() { + return new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_DARK); + } + + // The return value is sent elsewhere. TODO in java, in SendMessage in C++. + public void inputBox(String title, String defaultText, String defaultAction) { + final FrameLayout fl = new FrameLayout(this); + final EditText input = new EditText(this); + input.setGravity(Gravity.CENTER); + + FrameLayout.LayoutParams editBoxLayout = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); + editBoxLayout.setMargins(2, 20, 2, 20); + fl.addView(input, editBoxLayout); + + input.setInputType(InputType.TYPE_CLASS_TEXT); + input.setText(defaultText); + input.selectAll(); + + AlertDialog.Builder bld = null; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) + bld = new AlertDialog.Builder(this); + else + bld = createDialogBuilderWithTheme(); + + AlertDialog dlg = bld + .setView(fl) + .setTitle(title) + .setPositiveButton(defaultAction, new DialogInterface.OnClickListener(){ + public void onClick(DialogInterface d, int which) { + NativeApp.sendMessage("inputbox_completed", input.getText().toString()); + d.dismiss(); + } + }) + .setNegativeButton("Cancel", new DialogInterface.OnClickListener(){ + public void onClick(DialogInterface d, int which) { + NativeApp.sendMessage("inputbox_failed", ""); + d.cancel(); + } + }).create(); + + dlg.setCancelable(true); + dlg.show(); + } + + public boolean processCommand(String command, String params) { + if (command.equals("launchBrowser")) { + Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(params)); + startActivity(i); + return true; + } else if (command.equals("launchEmail")) { + Intent send = new Intent(Intent.ACTION_SENDTO); + String uriText; + uriText = "mailto:email@gmail.com" + "?subject=Your app is..." + + "&body=great! Or?"; + uriText = uriText.replace(" ", "%20"); + Uri uri = Uri.parse(uriText); + send.setData(uri); + startActivity(Intent.createChooser(send, "E-mail the app author!")); + return true; + } else if (command.equals("sharejpeg")) { + Intent share = new Intent(Intent.ACTION_SEND); + share.setType("image/jpeg"); + share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + params)); + startActivity(Intent.createChooser(share, "Share Picture")); + } else if (command.equals("sharetext")) { + Intent sendIntent = new Intent(); + sendIntent.setType("text/plain"); + sendIntent.putExtra(Intent.EXTRA_TEXT, params); + sendIntent.setAction(Intent.ACTION_SEND); + startActivity(sendIntent); + } else if (command.equals("showTwitter")) { + String twitter_user_name = params; + try { + startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("twitter://user?screen_name=" + + twitter_user_name))); + } catch (Exception e) { + startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("https://twitter.com/#!/" + twitter_user_name))); + } + } else if (command.equals("launchMarket")) { + // Don't need this, can just use launchBrowser with a market: + // http://stackoverflow.com/questions/3442366/android-link-to-market-from-inside-another-app + // http://developer.android.com/guide/publishing/publishing.html#marketintent + return false; + } else if (command.equals("toast")) { + Toast toast = Toast.makeText(this, params, Toast.LENGTH_SHORT); + toast.show(); + Log.i(TAG, params); + return true; + } else if (command.equals("showKeyboard")) { + InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + // No idea what the point of the ApplicationWindowToken is or if it + // matters where we get it from... + inputMethodManager.toggleSoftInputFromWindow( + mGLSurfaceView.getApplicationWindowToken(), + InputMethodManager.SHOW_FORCED, 0); + return true; + } else if (command.equals("hideKeyboard")) { + InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + inputMethodManager.toggleSoftInputFromWindow( + mGLSurfaceView.getApplicationWindowToken(), + InputMethodManager.SHOW_FORCED, 0); + return true; + } else if (command.equals("inputbox")) { + String title = "Input"; + String defString = ""; + String[] param = params.split(":"); + if (param[0].length() > 0) + title = param[0]; + if (param.length > 1) + defString = param[1]; + Log.i(TAG, "Launching inputbox: " + title + " " + defString); + inputBox(title, defString, "OK"); + return true; + } else if (command.equals("vibrate")) { + int milliseconds = -1; + if (params != "") { + try { + milliseconds = Integer.parseInt(params); + } catch (NumberFormatException e) { + } + } + // Special parameters to perform standard haptic feedback + // operations + // -1 = Standard keyboard press feedback + // -2 = Virtual key press + // -3 = Long press feedback + // Note that these three do not require the VIBRATE Android + // permission. + switch (milliseconds) { + case -1: + mGLSurfaceView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); + break; + case -2: + mGLSurfaceView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + break; + case -3: + mGLSurfaceView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + break; + default: + if (vibrator != null) { + vibrator.vibrate(milliseconds); + } + break; + } + return true; + } else if (command.equals("finish")) { + finish(); + } else if (command.equals("rotate")) { + if (Build.VERSION.SDK_INT >= 9) { + updateScreenRotation(); + } + } else if (command.equals("immersive")) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + updateSystemUiVisibility(); + } + } else if (command.equals("recreate")) { + recreate(); + } + return false; + } + + @SuppressLint("NewApi") + @Override + public void recreate() + { + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) + { + super.recreate(); + } + else + { + startActivity(getIntent()); + finish(); + } + } +} \ No newline at end of file diff --git a/ext/native/android/src/com/henrikrydgard/libnative/NativeApp.java b/ext/native/android/src/com/henrikrydgard/libnative/NativeApp.java new file mode 100644 index 0000000000..a392f5b61a --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/NativeApp.java @@ -0,0 +1,53 @@ +package com.henrikrydgard.libnative; + + +// Note that the display* methods are in NativeRenderer.java + +public class NativeApp { + public final static int DEVICE_ID_DEFAULT = 0; + public final static int DEVICE_ID_KEYBOARD = 1; + public final static int DEVICE_ID_MOUSE = 2; + public final static int DEVICE_ID_PAD_0 = 10; + + public final static int DEVICE_TYPE_MOBILE = 0; + public final static int DEVICE_TYPE_TV = 1; + public final static int DEVICE_TYPE_DESKTOP = 2; + + public static native void init(String model, int deviceType, int xres, int yres, String languageRegion, String apkPath, String dataDir, String externalDir, String libraryDir, String shortcutParam, String installID, int androidVersion); + + public static native void audioInit(); + public static native void audioShutdown(); + public static native void audioConfig(int optimalFramesPerBuffer, int optimalSampleRate); + + public static native boolean isLandscape(); + public static native boolean isAtTopLevel(); + + // These have Android semantics: Resume is always called on bootup, after init + public static native void pause(); + public static native void resume(); + + // There's not really any reason to ever call shutdown as we can recover from a killed activity. + public static native void shutdown(); + + public static native boolean keyDown(int deviceId, int key, boolean isRepeat); + public static native boolean keyUp(int deviceId, int key); + + public static native void beginJoystickEvent(); + public static native void joystickAxis(int deviceId, int axis, float value); + public static native void endJoystickEvent(); + + public static native boolean mouseWheelEvent(float x, float y); + + // will only be called between init() and shutdown() + public static native int audioRender(short[] buffer); + + // Sensor/input data. These are asynchronous, beware! + public static native boolean touch(float x, float y, int data, int pointerId); + + public static native boolean accelerometer(float x, float y, float z); + + public static native void sendMessage(String msg, String arg); + + public static native String queryConfig(String queryName); +} + \ No newline at end of file diff --git a/ext/native/android/src/com/henrikrydgard/libnative/NativeEGLConfigChooser.java b/ext/native/android/src/com/henrikrydgard/libnative/NativeEGLConfigChooser.java new file mode 100644 index 0000000000..0b0a62986e --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/NativeEGLConfigChooser.java @@ -0,0 +1,206 @@ +package com.henrikrydgard.libnative; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLDisplay; + +import android.opengl.GLSurfaceView.EGLConfigChooser; +import android.util.Log; + +public class NativeEGLConfigChooser implements EGLConfigChooser { + private static final String TAG = "NativeEGLConfigChooser"; + + private static final int EGL_OPENGL_ES2_BIT = 4; + + private class ConfigAttribs { + EGLConfig config; + public int red; + public int green; + public int blue; + public int alpha; + public int stencil; + public int depth; + public int samples; + public void Log() { + Log.i(TAG, "EGLConfig: red=" + red + " green=" + green + " blue=" + blue + " alpha=" + alpha + " depth=" + depth + " stencil=" + stencil + " samples=" + samples); + } + } + + int getEglConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attr) { + int[] value = new int[1]; + try { + if (egl.eglGetConfigAttrib(display, config, attr, value)) + return value[0]; + else + return -1; + } catch (IllegalArgumentException e) { + if (config == null) { + Log.e(TAG, "Called getEglConfigAttrib with null config. Bad developer."); + } else { + Log.e(TAG, "Illegal argument to getEglConfigAttrib: attr=" + attr); + } + return -1; + } + } + + ConfigAttribs[] getConfigAttribs(EGL10 egl, EGLDisplay display, EGLConfig[] configs) { + ConfigAttribs[] attr = new ConfigAttribs[configs.length]; + for (int i = 0; i < configs.length; i++) { + ConfigAttribs cfg = new ConfigAttribs(); + cfg.config = configs[i]; + cfg.red = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_RED_SIZE); + cfg.green = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_GREEN_SIZE); + cfg.blue = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_BLUE_SIZE); + cfg.alpha = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_ALPHA_SIZE); + cfg.depth = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_DEPTH_SIZE); + cfg.stencil = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_STENCIL_SIZE); + cfg.samples = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_SAMPLES); + attr[i] = cfg; + } + return attr; + } + + @Override + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + // The absolute minimum. We will do our best to choose a better config though. + int[] configSpec = { + EGL10.EGL_RED_SIZE, 5, + EGL10.EGL_GREEN_SIZE, 6, + EGL10.EGL_BLUE_SIZE, 5, + EGL10.EGL_DEPTH_SIZE, 16, + EGL10.EGL_STENCIL_SIZE, 0, + EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + }; + + int[] num_config = new int[1]; + if (!egl.eglChooseConfig(display, configSpec, null, 0, num_config)) { + throw new IllegalArgumentException("eglChooseConfig failed when counting"); + } + + int numConfigs = num_config[0]; + Log.i(TAG, "There are " + numConfigs + " egl configs"); + if (numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + + EGLConfig[] eglConfigs = new EGLConfig[numConfigs]; + if (!egl.eglChooseConfig(display, configSpec, eglConfigs, numConfigs, num_config)) { + throw new IllegalArgumentException("eglChooseConfig failed when retrieving"); + } + + ConfigAttribs [] configs = getConfigAttribs(egl, display, eglConfigs); + + ConfigAttribs chosen = null; + + // Log them all. + for (int i = 0; i < configs.length; i++) { + configs[i].Log(); + } + + // We now ignore destination alpha as a workaround for the Mali issue + // where we get badly composited if we use it. + + // First, find our ideal configuration. Prefer depth. + for (int i = 0; i < configs.length; i++) { + ConfigAttribs c = configs[i]; + if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 0 && c.stencil >= 8 && c.depth >= 24) { + chosen = c; + break; + } + } + + if (chosen == null) { + // Then, prefer one with 20-bit depth (Tegra 3) + for (int i = 0; i < configs.length; i++) { + ConfigAttribs c = configs[i]; + if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 0 && c.stencil >= 8 && c.depth >= 20) { + chosen = c; + break; + } + } + } + + if (chosen == null) { + // Second, accept one with 16-bit depth. + for (int i = 0; i < configs.length; i++) { + ConfigAttribs c = configs[i]; + if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 0 && c.stencil >= 8 && c.depth >= 16) { + chosen = c; + break; + } + } + } + + if (chosen == null) { + // Third, accept one with no stencil. + for (int i = 0; i < configs.length; i++) { + ConfigAttribs c = configs[i]; + if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 0 && c.depth >= 16) { + chosen = c; + break; + } + } + } + + if (chosen == null) { + // Third, accept one with alpha but with stencil. + for (int i = 0; i < configs.length; i++) { + ConfigAttribs c = configs[i]; + if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 8 && c.stencil >= 8 && c.depth >= 24) { + chosen = c; + break; + } + } + } + + if (chosen == null) { + // Third, accept one with alpha but with stencil. + for (int i = 0; i < configs.length; i++) { + ConfigAttribs c = configs[i]; + if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 8 && c.stencil >= 8 && c.depth >= 16) { + chosen = c; + break; + } + } + } + + if (chosen == null) { + // Fourth, accept one with 16-bit color but depth and stencil required. + for (int i = 0; i < configs.length; i++) { + ConfigAttribs c = configs[i]; + if (c.red >= 5 && c.green >= 6 && c.blue >= 5 && c.depth >= 16 && c.stencil >= 8) { + chosen = c; + break; + } + } + } + + if (chosen == null) { + // Fifth, accept one with 16-bit color but depth required. + for (int i = 0; i < configs.length; i++) { + ConfigAttribs c = configs[i]; + if (c.red >= 5 && c.green >= 6 && c.blue >= 5 && c.depth >= 16) { + chosen = c; + break; + } + } + } + + if (chosen == null) { + // Final, accept the first one in the list. + if (configs.length > 0) + chosen = configs[0]; + } + + if (chosen == null) { + throw new IllegalArgumentException("Failed to find a valid EGL config"); + } + + Log.i(TAG, "Final chosen config: "); + chosen.Log(); + return chosen.config; + } + +} diff --git a/ext/native/android/src/com/henrikrydgard/libnative/NativeGLView.java b/ext/native/android/src/com/henrikrydgard/libnative/NativeGLView.java new file mode 100644 index 0000000000..65046d08ee --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/NativeGLView.java @@ -0,0 +1,235 @@ +package com.henrikrydgard.libnative; + +// Touch- and sensor-enabled GLSurfaceView. +// Supports simple multitouch and pressure. + +import android.annotation.TargetApi; +import android.app.Activity; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.opengl.GLSurfaceView; +import android.os.Build; +import android.os.Handler; +// import android.os.Build; +// import android.util.Log; +import android.util.Log; +import android.view.MotionEvent; +import com.bda.controller.*; + +public class NativeGLView extends GLSurfaceView implements SensorEventListener, ControllerListener { + private static String TAG = "NativeGLView"; + private SensorManager mSensorManager; + private Sensor mAccelerometer; + private NativeActivity mActivity; + + // Moga controller + private Controller mController = null; + private boolean isMogaPro = false; + + public NativeGLView(NativeActivity activity) { + super(activity); + mActivity = activity; + + /*// TODO: This would be nice. + if (Build.VERSION.SDK_INT >= 11) { + try { + Method method_setPreserveEGLContextOnPause = GLSurfaceView.class.getMethod( + "setPreserveEGLContextOnPause", new Class[] { Boolean.class }); + Log.i(TAG, "Invoking setPreserveEGLContextOnPause"); + method_setPreserveEGLContextOnPause.invoke(this, true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + }*/ + + mSensorManager = (SensorManager)activity.getSystemService(Activity.SENSOR_SERVICE); + mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + + mController = Controller.getInstance(activity); + try { + MogaHack.init(mController, activity); + Log.i(TAG, "MOGA initialized"); + mController.setListener(this, new Handler()); + } catch (Exception e) { + Log.i(TAG, "Moga failed to initialize"); + } + } + + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) + private int getToolType(final MotionEvent ev, int pointer) { + return ev.getToolType(pointer); + } + + public boolean onTouchEvent(final MotionEvent ev) { + boolean canReadToolType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH; + + int numTouchesHandled = 0; + float scaleX = (float)mActivity.getRenderer().getDpiScaleX(); + float scaleY = (float)mActivity.getRenderer().getDpiScaleY(); + for (int i = 0; i < ev.getPointerCount(); i++) { + int pid = ev.getPointerId(i); + int code = 0; + + final int action = ev.getActionMasked(); + + // These code bits are now the same as the constants in input_state.h. + switch (action) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_POINTER_DOWN: + if (ev.getActionIndex() == i) + code = 2; + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_UP: + if (ev.getActionIndex() == i) + code = 4; + break; + case MotionEvent.ACTION_MOVE: + code = 1; + break; + default: + break; + } + + if (code != 0) { + if (canReadToolType) { + int tool = getToolType(ev, i); + code |= tool << 10; // We use the Android tool type codes + } + // Can't use || due to short circuit evaluation + numTouchesHandled += NativeApp.touch(scaleX * ev.getX(i), scaleY * ev.getY(i), code, pid) ? 1 : 0; + } + } + return numTouchesHandled > 0; + } + + // Sensor management + public void onAccuracyChanged(Sensor sensor, int arg1) { + } + + public void onSensorChanged(SensorEvent event) { + if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) { + return; + } + // Can also look at event.timestamp for accuracy magic + NativeApp.accelerometer(event.values[0], event.values[1], event.values[2]); + } + + @Override + public void onPause() { + super.onPause(); + mSensorManager.unregisterListener(this); + if (mController != null) { + mController.onPause(); + } + } + + @Override + public void onResume() { + super.onResume(); + mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); + if (mController != null) { + mController.onResume(); + + // According to the docs, the Moga's state can be inconsistent here. + // We should do a one time poll. TODO + } + } + + public void onDestroy() { + if (mController != null) { + mController.exit(); + } + } + + // MOGA Controller - from ControllerListener + @Override + public void onKeyEvent(KeyEvent event) { + // The Moga left stick doubles as a D-pad. This creates mapping conflicts so let's turn it off. + // Unfortunately this breaks menu navigation in PPSSPP currently but meh. + // This is different on Moga Pro though. + + if (!isMogaPro) { + switch (event.getKeyCode()) { + case KeyEvent.KEYCODE_DPAD_DOWN: + case KeyEvent.KEYCODE_DPAD_UP: + case KeyEvent.KEYCODE_DPAD_LEFT: + case KeyEvent.KEYCODE_DPAD_RIGHT: + return; + default: + break; + } + } + + boolean repeat = false; // Moga has no repeats? + switch (event.getAction()) { + case KeyEvent.ACTION_DOWN: + NativeApp.keyDown(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode(), repeat); + break; + case KeyEvent.ACTION_UP: + NativeApp.keyUp(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode()); + break; + } + } + + // MOGA Controller - from ControllerListener + @Override + public void onMotionEvent(com.bda.controller.MotionEvent event) { + NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_X, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_X)); + NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_Y, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_Y)); + NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_Z, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_Z)); + NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_RZ, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_RZ)); + NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_LTRIGGER, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_LTRIGGER)); + NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_RTRIGGER, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_RTRIGGER)); + } + + // MOGA Controller - from ControllerListener + @Override + public void onStateEvent(StateEvent state) { + switch (state.getState()) { + case StateEvent.STATE_CONNECTION: + switch (state.getAction()) { + case StateEvent.ACTION_CONNECTED: + Log.i(TAG, "Moga Connected"); + if (mController.getState(Controller.STATE_CURRENT_PRODUCT_VERSION) == Controller.ACTION_VERSION_MOGA) { + NativeApp.sendMessage("moga", "Moga"); + } else { + Log.i(TAG, "MOGA Pro detected"); + isMogaPro = true; + NativeApp.sendMessage("moga", "MogaPro"); + } + break; + case StateEvent.ACTION_CONNECTING: + Log.i(TAG, "Moga Connecting..."); + break; + case StateEvent.ACTION_DISCONNECTED: + Log.i(TAG, "Moga Disconnected (or simply Not connected)"); + NativeApp.sendMessage("moga", ""); + break; + } + break; + + case StateEvent.STATE_POWER_LOW: + switch (state.getAction()) { + case StateEvent.ACTION_TRUE: + Log.i(TAG, "Moga Power Low"); + break; + case StateEvent.ACTION_FALSE: + Log.i(TAG, "Moga Power OK"); + break; + } + break; + + default: + break; + } + } +} diff --git a/ext/native/android/src/com/henrikrydgard/libnative/NativeRenderer.java b/ext/native/android/src/com/henrikrydgard/libnative/NativeRenderer.java new file mode 100644 index 0000000000..658eacc5e8 --- /dev/null +++ b/ext/native/android/src/com/henrikrydgard/libnative/NativeRenderer.java @@ -0,0 +1,109 @@ +package com.henrikrydgard.libnative; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.graphics.Point; +import android.opengl.GLES20; +import android.opengl.GLSurfaceView; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.Display; + +public class NativeRenderer implements GLSurfaceView.Renderer { + private static String TAG = "NativeRenderer"; + private NativeActivity mActivity; + private boolean isDark = false; + private int dpi; + private float refreshRate; + + private double dpi_scale_x; + private double dpi_scale_y; + + int last_width, last_height; + + NativeRenderer(NativeActivity act) { + mActivity = act; + DisplayMetrics metrics = new DisplayMetrics(); + Display display = act.getWindowManager().getDefaultDisplay(); + display.getMetrics(metrics); + dpi = metrics.densityDpi; + + refreshRate = display.getRefreshRate(); + } + + double getDpiScaleX() { + return dpi_scale_x; + } + double getDpiScaleY() { + return dpi_scale_y; + } + + public void setDark(boolean d) { + isDark = d; + } + + public void setFixedSize(int xres, int yres, GLSurfaceView surfaceView) { + Log.i(TAG, "Setting surface to fixed size " + xres + "x" + yres); + surfaceView.getHolder().setFixedSize(xres, yres); + } + + @Override + public void onDrawFrame(GL10 unused /*use GLES20*/) { + if (isDark) { + GLES20.glDisable(GLES20.GL_SCISSOR_TEST); + GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT); + } else { + displayRender(); + } + } + + @Override + public void onSurfaceCreated(GL10 unused, EGLConfig config) { + // Log.i(TAG, "onSurfaceCreated - EGL context is new or was lost"); + // Actually, it seems that it is here we should recreate lost GL objects. + displayInit(); + } + + @Override + public void onSurfaceChanged(GL10 unused, int width, int height) { + Point sz = new Point(); + mActivity.GetScreenSize(sz); + double actualW = sz.x; + double actualH = sz.y; + dpi_scale_x = ((double)width / (double)actualW); + dpi_scale_y = ((double)height / (double)actualH); + Log.i(TAG, "onSurfaceChanged: " + dpi_scale_x + "x" + dpi_scale_y + " (width=" + width + ", actualW=" + actualW); + int scaled_dpi = (int)((double)dpi * dpi_scale_x); + displayResize(width, height, scaled_dpi, refreshRate); + last_width = width; + last_height = height; + } + + // Not override, it's custom. + public void onDestroyed() { + displayShutdown(); + } + + // NATIVE METHODS + + // Note: This also means "device lost" and you should reload + // all buffered objects. + public native void displayInit(); + public native void displayResize(int w, int h, int dpi, float refreshRate); + public native void displayRender(); + public native void displayShutdown(); + + // called by the C++ code through JNI. Dispatch anything we can't directly handle + // on the gfx thread to the UI thread. + public void postCommand(String command, String parameter) { + final String cmd = command; + final String param = parameter; + mActivity.runOnUiThread(new Runnable() { + public void run() { + NativeRenderer.this.mActivity.processCommand(cmd, param); + } + }); + } +} \ No newline at end of file diff --git a/ext/native/audio/CMakeLists.txt b/ext/native/audio/CMakeLists.txt new file mode 100644 index 0000000000..3d742499b2 --- /dev/null +++ b/ext/native/audio/CMakeLists.txt @@ -0,0 +1,11 @@ +set(SRCS + mixer.cpp + wav_read.cpp) + +set(SRCS ${SRCS}) + +add_library(mixer STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/audio/mixer.cpp b/ext/native/audio/mixer.cpp new file mode 100644 index 0000000000..ac621cd380 --- /dev/null +++ b/ext/native/audio/mixer.cpp @@ -0,0 +1,201 @@ +#include + +#include "audio/mixer.h" +#include "audio/wav_read.h" +#include "base/logging.h" +#include "ext/stb_vorbis/stb_vorbis.h" +#include "file/vfs.h" + +// TODO: +// * Vorbis streaming playback + +struct ChannelEffectState { + // Filter state +}; + +enum CLIP_TYPE { + CT_PCM16, + CT_SYNTHFX, + CT_VORBIS, + // CT_PHOENIX? +}; + +struct Clip { + int type; + + short *data; + int length; + int num_channels; // this is NOT stereo vs mono + int sample_rate; + int loop_start; + int loop_end; +}; + +// If current_clip == 0, the channel is free. + +enum ClipPlaybackState { + PB_STOPPED = 0, + PB_PLAYING = 1, +}; + + +struct Channel { + const Clip *current_clip; + // Playback state + ClipPlaybackState state; + int pos; + PlayParams params; + // Effect state + ChannelEffectState effect_state; +}; + +struct Mixer { + Channel *channels; + int sample_rate; + int num_channels; + int num_fixed_channels; +}; + +Mixer *mixer_create(int sample_rate, int channels, int fixed_channels) { + Mixer *mixer = new Mixer(); + memset(mixer, 0, sizeof(Mixer)); + mixer->channels = new Channel[channels]; + memset(mixer->channels, 0, sizeof(Channel) * channels); + mixer->sample_rate = sample_rate; + mixer->num_channels = channels; + mixer->num_fixed_channels = fixed_channels; + return mixer; +} + +void mixer_destroy(Mixer *mixer) { + delete [] mixer->channels; + delete mixer; +} + +static int get_free_channel(Mixer *mixer) { + int chan_with_biggest_pos = -1; + int biggest_pos = -1; + for (int i = mixer->num_fixed_channels; i < mixer->num_channels; i++) { + Channel *chan = &mixer->channels[i]; + if (!chan->current_clip) { + return i; + } + if (chan->pos > biggest_pos) { + biggest_pos = chan->pos; + chan_with_biggest_pos = i; + } + } + return chan_with_biggest_pos; +} + +Clip *clip_load(const char *filename) { + short *data; + int num_samples; + int sample_rate, num_channels; + + if (!strcmp(filename + strlen(filename) - 4, ".ogg")) { + // Ogg file. For now, directly decompress, no streaming support. + uint8_t *filedata; + size_t size; + filedata = VFSReadFile(filename, &size); + num_samples = (int)stb_vorbis_decode_memory(filedata, (int)size, &num_channels, &data); + if (num_samples <= 0) + return NULL; + sample_rate = 44100; + ILOG("read ogg %s, length %i, rate %i", filename, num_samples, sample_rate); + } else { + // Wav file. Easy peasy. + data = wav_read(filename, &num_samples, &sample_rate, &num_channels); + if (!data) { + return NULL; + } + } + + Clip *clip = new Clip(); + clip->type = CT_PCM16; + clip->data = data; + clip->length = num_samples; + clip->num_channels = num_channels; + clip->sample_rate = sample_rate; + clip->loop_start = 0; + clip->loop_end = 0; + return clip; +} + +void clip_destroy(Clip *clip) { + if (clip) { + free(clip->data); + delete clip; + } else { + ELOG("Can't destroy zero clip"); + } +} + +const short *clip_data(const Clip *clip) +{ + return clip->data; +} + +size_t clip_length(const Clip *clip) { + return clip->length; +} + +void clip_set_loop(Clip *clip, int start, int end) { + clip->loop_start = start; + clip->loop_end = end; +} + +PlayParams *mixer_play_clip(Mixer *mixer, const Clip *clip, int channel) { + if (channel == -1) { + channel = get_free_channel(mixer); + } + + Channel *chan = &mixer->channels[channel]; + // Think about this order and make sure it's thread"safe" (not perfect but should not cause crashes). + chan->pos = 0; + chan->current_clip = clip; + chan->state = PB_PLAYING; + PlayParams *params = &chan->params; + params->volume = 128; + params->pan = 128; + return params; +} + +void mixer_mix(Mixer *mixer, short *buffer, int num_samples) { + // Clear the buffer. + memset(buffer, 0, num_samples * sizeof(short) * 2); + for (int i = 0; i < mixer->num_channels; i++) { + Channel *chan = &mixer->channels[i]; + if (chan->state == PB_PLAYING) { + const Clip *clip = chan->current_clip; + if (clip->type == CT_PCM16) { + // For now, only allow mono PCM + CHECK(clip->num_channels == 1); + if (true || chan->params.delta == 0) { + // Fast playback of non pitched clips + int cnt = num_samples; + if (clip->length - chan->pos < cnt) { + cnt = clip->length - chan->pos; + } + // TODO: Take pan into account. + int left_volume = chan->params.volume; + int right_volume = chan->params.volume; + // TODO: NEONize. Can also make special loops for left_volume == right_volume etc. + for (int s = 0; s < cnt; s++) { + int cdata = clip->data[chan->pos]; + buffer[s * 2 + 0] += cdata * left_volume >> 8; + buffer[s * 2 + 1] += cdata * right_volume >> 8; + chan->pos++; + } + if (chan->pos >= clip->length) { + chan->state = PB_STOPPED; + chan->current_clip = 0; + break; + } + } + } else if (clip->type == CT_VORBIS) { + // For music + } + } + } +} diff --git a/ext/native/audio/mixer.h b/ext/native/audio/mixer.h new file mode 100644 index 0000000000..69127df8a5 --- /dev/null +++ b/ext/native/audio/mixer.h @@ -0,0 +1,43 @@ +#pragma once + +#include "base/basictypes.h" + +// Simple mixer intended for sound effects for games. +// The clip loading code supports ogg SFX. + +struct Mixer; +struct Clip; +struct Channel; + +// This struct is public for easy manipulation of running channels. +struct PlayParams { + uint8_t volume; // 0-255 + uint8_t pan; // 0-255, 127 is dead center. + int32_t delta; +}; + +// Mixer +// ========================== +// For now, channels is required to be 2 (it specifies L/R, not mixing channels) +Mixer *mixer_create(int sample_rate, int channels, int fixed_channels); +void mixer_destroy(Mixer *mixer); + +// Buffer must be r/w. +void mixer_mix(Mixer *mixer, short *buffer, int num_samples); + + +// Clip +// ========================== +Clip *clip_load(const char *filename); +void clip_destroy(Clip *clip); + +const short *clip_data(const Clip *clip); +size_t clip_length(const Clip *clip); +void clip_set_loop(int start, int end); + + +// The returned PlayState pointer can be used to set the playback parameters, +// but must not be kept around unless you are using a fixed channel. +// Channel must be either -1 for auto assignment to a free channel, or less +// than the number of fixed channels that the mixer was created with. +PlayParams *mixer_play_clip(Mixer *mixer, const Clip *clip, int channel); diff --git a/ext/native/audio/wav_read.cpp b/ext/native/audio/wav_read.cpp new file mode 100644 index 0000000000..6a827ece36 --- /dev/null +++ b/ext/native/audio/wav_read.cpp @@ -0,0 +1,70 @@ +#include "base/basictypes.h" +#include "base/logging.h" +#include "audio/wav_read.h" +#include "file/chunk_file.h" + +short *wav_read(const char *filename, + int *num_samples, int *sample_rate, + int *num_channels) +{ + ChunkFile cf(filename, true); + if (cf.failed()) { + WLOG("ERROR: Wave file %s could not be opened", filename); + return 0; + } + + short *data = 0; + int samplesPerSec, avgBytesPerSec,wBlockAlign,wBytesPerSample; + if (cf.descend('RIFF')) { + cf.readInt(); //get past 'WAVE' + if (cf.descend('fmt ')) { //enter the format chunk + int temp = cf.readInt(); + int format = temp & 0xFFFF; + if (format != 1) { + cf.ascend(); + cf.ascend(); + ELOG("Error - bad format"); + return NULL; + } + *num_channels = temp >> 16; + samplesPerSec = cf.readInt(); + avgBytesPerSec = cf.readInt(); + + temp = cf.readInt(); + wBlockAlign = temp & 0xFFFF; + wBytesPerSample = temp >> 16; + cf.ascend(); + // ILOG("got fmt data: %i", samplesPerSec); + } else { + ELOG("Error - no format chunk in wav"); + cf.ascend(); + return NULL; + } + + if (cf.descend('data')) { //enter the data chunk + int numBytes = cf.getCurrentChunkSize(); + int numSamples = numBytes / wBlockAlign; + data = (short *)malloc(sizeof(short) * numSamples * *num_channels); + *num_samples = numSamples; + if (wBlockAlign == 2 && *num_channels == 1) { + cf.readData((uint8_t *)data,numBytes); + } else { + ELOG("Error - bad blockalign or channels"); + free(data); + return NULL; + } + cf.ascend(); + } else { + ELOG("Error - no data chunk in wav"); + cf.ascend(); + return NULL; + } + cf.ascend(); + } else { + ELOG("Could not descend into RIFF file"); + return NULL; + } + *sample_rate = samplesPerSec; + ILOG("read wav %s, length %i, rate %i", filename, *num_samples, *sample_rate); + return data; +} diff --git a/ext/native/audio/wav_read.h b/ext/native/audio/wav_read.h new file mode 100644 index 0000000000..1929688cbd --- /dev/null +++ b/ext/native/audio/wav_read.h @@ -0,0 +1,7 @@ +#include "base/basictypes.h" + +// Allocates a buffer that should be freed using free(). +short *wav_read(const char *filename, + int *num_samples, int *sample_rate, + int *num_channels); +// TODO: Non-allocating version. diff --git a/ext/native/base/BlackberryAudio.h b/ext/native/base/BlackberryAudio.h new file mode 100644 index 0000000000..7c604354dc --- /dev/null +++ b/ext/native/base/BlackberryAudio.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013 Sacha Refshauge + * + */ +// Blackberry implementation of the framework. +#ifndef BLACKBERRYAUDIO_H +#define BLACKBERRYAUDIO_H + +#include +#include +#include + +#include "base/NativeApp.h" + +#define AUDIO_FREQ 44100 +#define SAMPLE_SIZE 2048 +class BlackberryAudio +{ +public: + BlackberryAudio() + { + alcDevice = alcOpenDevice(NULL); + if (alContext = alcCreateContext(alcDevice, NULL)) + alcMakeContextCurrent(alContext); + alGenSources(1, &source); + alGenBuffers(1, &buffer); + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&thread_handle, &attr, &BlackberryAudio::staticThreadProc, this); + } + ~BlackberryAudio() + { + pthread_cancel(thread_handle); + alcMakeContextCurrent(NULL); + if (alContext) + { + alcDestroyContext(alContext); + alContext = NULL; + } + if (alcDevice) + { + alcCloseDevice(alcDevice); + alcDevice = NULL; + } + } + static void* staticThreadProc(void* arg) + { + return reinterpret_cast(arg)->RunAudio(); + } +private: + void* RunAudio() + { + while(true) + { + size_t frames_ready; + alGetSourcei(source, AL_SOURCE_STATE, &state); + if (state != AL_PLAYING) { + frames_ready = NativeMix((short*)stream, 5*SAMPLE_SIZE); + } + else + frames_ready = 0; + if (frames_ready > 0) + { + const size_t bytes_ready = frames_ready * sizeof(short) * 2; + alSourcei(source, AL_BUFFER, 0); + alBufferData(buffer, AL_FORMAT_STEREO16, stream, bytes_ready, AUDIO_FREQ); + alSourcei(source, AL_BUFFER, buffer); + alSourcePlay(source); + // TODO: Maybe this could get behind? + usleep((1000000 * SAMPLE_SIZE) / AUDIO_FREQ); + } + else + usleep(10000); + } + } + ALCdevice *alcDevice; + ALCcontext *alContext; + ALenum state; + ALuint buffer; + ALuint source; + char stream[20*SAMPLE_SIZE]; + pthread_t thread_handle; +}; +#endif + diff --git a/ext/native/base/BlackberryDisplay.cpp b/ext/native/base/BlackberryDisplay.cpp new file mode 100644 index 0000000000..e4bbdcaf6d --- /dev/null +++ b/ext/native/base/BlackberryDisplay.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013 Sacha Refshauge + * + */ +// Blackberry implementation of the framework. +#include "BlackberryMain.h" + +const char* BlackberryMain::displayTypeString(int type) +{ + switch (type) + { + case SCREEN_DISPLAY_TYPE_INTERNAL: + return "Internal"; break; + case SCREEN_DISPLAY_TYPE_COMPOSITE: + return "Composite"; break; + case SCREEN_DISPLAY_TYPE_DVI: + return "DVI"; break; + case SCREEN_DISPLAY_TYPE_HDMI: + return "HDMI"; break; + case SCREEN_DISPLAY_TYPE_DISPLAYPORT: + return "DisplayPort"; break; + case SCREEN_DISPLAY_TYPE_OTHER: + default: + break; + } + return "Unknown Port"; +} + +void BlackberryMain::startDisplays() { + int num_configs; + EGLint attrib_list[]= { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE}; + + const EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + + screen_get_context_property_iv(screen_cxt, SCREEN_PROPERTY_DISPLAY_COUNT, &ndisplays); + egl_disp = (EGLDisplay*)calloc(ndisplays, sizeof(EGLDisplay)); + egl_surf = (EGLSurface*)calloc(ndisplays, sizeof(EGLSurface)); + displays = (dispdata_t*)calloc(ndisplays, sizeof(dispdata_t)); + screen_win = (screen_window_t *)calloc(ndisplays, sizeof(screen_window_t )); + screen_dpy = (screen_display_t*)calloc(ndisplays, sizeof(screen_display_t)); + screen_get_context_property_pv(screen_cxt, SCREEN_PROPERTY_DISPLAYS, (void **)screen_dpy); + + // Common data + int usage = SCREEN_USAGE_ROTATION | SCREEN_USAGE_OPENGL_ES2; + int format = SCREEN_FORMAT_RGBX8888; + int sensitivity = SCREEN_SENSITIVITY_ALWAYS; + + // Initialise every display + for (int i = 0; i < ndisplays; i++) { + screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_TYPE, &(displays[i].type)); + screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_ATTACHED, &(displays[i].attached)); + + screen_create_window(&screen_win[i], screen_cxt); + screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_FORMAT, &format); + screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_USAGE, &usage); + screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_SENSITIVITY, &sensitivity); + screen_set_window_property_pv(screen_win[i], SCREEN_PROPERTY_DISPLAY, (void **)&screen_dpy[i]); + + egl_disp[i] = eglGetDisplay((EGLNativeDisplayType)i); + eglInitialize(egl_disp[i], NULL, NULL); + if (egl_cont == EGL_NO_CONTEXT) { + eglChooseConfig(egl_disp[0], attrib_list, &egl_conf, 1, &num_configs); + egl_cont = eglCreateContext(egl_disp[0], egl_conf, EGL_NO_CONTEXT, attributes); + } + + fprintf(stderr, "Display %i: %s, %s\n", i, displayTypeString(displays[i].type), displays[i].attached ? "Attached" : "Detached"); + if (displays[i].attached) + realiseDisplay(i); + } +#ifdef ARM + screen_get_display_property_iv(screen_dpy[0], SCREEN_PROPERTY_DPI, &dpi); // Only internal display has DPI + // We only use dpi to calculate the width. Smaller aspect ratios have giant text despite high DPI. + dpi = dpi * (((float)displays[0].width/(float)displays[0].height) / (16.0/9.0)); // Adjust to 16:9 +#else + dpi = 340.0f; +#endif + g_dpi_scale = 210.0f / dpi; + switchDisplay(screen_ui); +} + +void BlackberryMain::realiseDisplay(int idx) { + const EGLint egl_surfaceAttr[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE }; + int size[2] = { atoi(getenv("WIDTH")), atoi(getenv("HEIGHT")) }; + if (idx != 0) + screen_get_display_property_iv(screen_dpy[idx], SCREEN_PROPERTY_SIZE, size); + + displays[idx].width = size[0]; + displays[idx].height = size[1]; + screen_set_window_property_iv(screen_win[idx], SCREEN_PROPERTY_BUFFER_SIZE, size); + screen_create_window_buffers(screen_win[idx], 2); // Double buffered + fprintf(stderr, "Display %i realised with %ix%i\n", idx, size[0], size[1]); + + egl_surf[idx] = eglCreateWindowSurface(egl_disp[idx], egl_conf, screen_win[idx], egl_surfaceAttr); + + // Only enable for devices with hardware QWERTY, 1:1 aspect ratio + if ((pixel_xres == pixel_yres) && displays[idx].type != SCREEN_DISPLAY_TYPE_INTERNAL) + { + screen_emu = idx; + if (emulating) + switchDisplay(idx); + } + + displays[idx].realised = true; +} + +void BlackberryMain::unrealiseDisplay(int idx) { + if (displays[idx].type != SCREEN_DISPLAY_TYPE_INTERNAL) // Always true, only external can unrealise + { + screen_emu = screen_ui; + if (emulating) + switchDisplay(screen_ui); + } + killDisplay(idx, false); + displays[idx].realised = false; +} + +void BlackberryMain::switchDisplay(int idx) { + static int screen_curr = -1; + if (idx != screen_curr) { + pixel_xres = displays[idx].width; + pixel_yres = displays[idx].height; + dp_xres = (int)(pixel_xres * g_dpi_scale); + dp_yres = (int)(pixel_yres * g_dpi_scale); + screen_curr = idx; + eglMakeCurrent(egl_disp[idx], egl_surf[idx], egl_surf[idx], egl_cont); + } + if (emulating) { + PSP_CoreParameter().pixelWidth = pixel_xres; + PSP_CoreParameter().pixelHeight = pixel_yres; + } +} + +void BlackberryMain::killDisplays() { + for (int i = 0; i < ndisplays; i++) { + killDisplay(i, true); + } + if (egl_cont != EGL_NO_CONTEXT) { + eglDestroyContext(egl_disp[0], egl_cont); + egl_cont = EGL_NO_CONTEXT; + } + free(egl_disp); + free(egl_surf); + eglReleaseThread(); + free(screen_dpy); +} + +void BlackberryMain::killDisplay(int idx, bool killContext) { + if (egl_disp[idx] != EGL_NO_DISPLAY) { + if (killContext) + eglMakeCurrent(egl_disp[idx], EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (egl_surf[idx] != EGL_NO_SURFACE) { + eglDestroySurface(egl_disp[idx], egl_surf[idx]); + egl_surf[idx] = EGL_NO_SURFACE; + } + if (killContext) + { + eglTerminate(egl_disp[idx]); + egl_disp[idx] = EGL_NO_DISPLAY; + } + } + if (killContext && screen_win[idx] != NULL) { + screen_destroy_window(screen_win[idx]); + screen_win[idx] = NULL; + } + screen_destroy_window_buffers(screen_win[idx]); +} + diff --git a/ext/native/base/BlackberryMain.cpp b/ext/native/base/BlackberryMain.cpp new file mode 100644 index 0000000000..f6bc2ece11 --- /dev/null +++ b/ext/native/base/BlackberryMain.cpp @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2013 Sacha Refshauge + * + */ +// Blackberry implementation of the framework. + +#include +#include +#include +#include + +#include // Get locale +#include // Receive invocation messages +#include "BlackberryMain.h" +#include "base/NKCodeFromBlackberry.h" + +// Bad: PPSSPP includes from native +#include "Core/System.h" +#include "Core/Config.h" +#include "Core/Core.h" +#include "UI/MiscScreens.h" + +static bool g_quitRequested = false; + +// Simple implementations of System functions + +std::string System_GetProperty(SystemProperty prop) { + switch (prop) { + case SYSPROP_NAME: { + std::string name = "Blackberry:"; +#ifdef ARM + return name + ((pixel_xres != pixel_yres) ? "Touch" : "QWERTY"); +#else + return name + "Simulator"; +#endif + } + case SYSPROP_LANGREGION: { + char *locale = 0; + locale_get_locale(&locale); + return std::string(locale); + } + default: + return ""; + } +} + +int System_GetPropertyInt(SystemProperty prop) { + switch (prop) { + case SYSPROP_AUDIO_SAMPLE_RATE: + return 44100; + case SYSPROP_DISPLAY_REFRESH_RATE: + return 60000; + case SYSPROP_DEVICE_TYPE: + return DEVICE_TYPE_MOBILE; + default: + return -1; + } +} + +void System_SendMessage(const char *command, const char *parameter) { + if (!strcmp(command, "finish")) { + g_quitRequested = true; + } +} + +void SystemToast(const char *text) { + dialog_instance_t dialog = 0; + dialog_create_toast(&dialog); + dialog_set_toast_message_text(dialog, text); + dialog_set_toast_position(dialog, DIALOG_POSITION_TOP_CENTER); + dialog_show(dialog); +} + +void ShowAd(int x, int y, bool center_x) { +} + +void ShowKeyboard() { + virtualkeyboard_show(); +} + +void Vibrate(int length_ms) { + // Vibration: intensity strength(1-100), duration ms(0-5000) + // Intensity: LOW = 1, MEDIUM = 10, HIGH = 100 + switch (length_ms) { + case -1: // Keyboard Tap + vibration_request(VIBRATION_INTENSITY_LOW, 50); + break; + case -2: // Virtual Key + vibration_request(VIBRATION_INTENSITY_LOW, 25); + break; + case -3: // Long Press + vibration_request(VIBRATION_INTENSITY_LOW, 50); + break; + default: + vibration_request(VIBRATION_INTENSITY_LOW, length_ms); + break; + } +} + +void LaunchBrowser(const char *url) +{ + char* error; + navigator_invoke(url, &error); +} + +void LaunchMarket(const char *url) +{ + char* error; + navigator_invoke(url, &error); +} + +void LaunchEmail(const char *email_address) +{ + char* error; + navigator_invoke((std::string("mailto:") + email_address).c_str(), &error); +} + +InputState input_state; + +void BlackberryMain::handleInput(screen_event_t screen_event) +{ + TouchInput input; + KeyInput key; + int val, buttons, pointerId; + int pair[2]; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &val); + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pair); + + input_state.mouse_valid = true; + switch(val) + { + // Touchscreen + case SCREEN_EVENT_MTOUCH_TOUCH: + case SCREEN_EVENT_MTOUCH_RELEASE: // Up, down + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pointerId); + input_state.pointer_down[pointerId] = (val == SCREEN_EVENT_MTOUCH_TOUCH); + input_state.pointer_x[pointerId] = pair[0] * g_dpi_scale; + input_state.pointer_y[pointerId] = pair[1] * g_dpi_scale; + + input.x = pair[0] * g_dpi_scale; + input.y = pair[1] * g_dpi_scale; + input.flags = (val == SCREEN_EVENT_MTOUCH_TOUCH) ? TOUCH_DOWN : TOUCH_UP; + input.id = pointerId; + NativeTouch(input); + break; + case SCREEN_EVENT_MTOUCH_MOVE: + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pointerId); + input_state.pointer_x[pointerId] = pair[0] * g_dpi_scale; + input_state.pointer_y[pointerId] = pair[1] * g_dpi_scale; + + input.x = pair[0] * g_dpi_scale; + input.y = pair[1] * g_dpi_scale; + input.flags = TOUCH_MOVE; + input.id = pointerId; + NativeTouch(input); + break; + // Mouse, Simulator + case SCREEN_EVENT_POINTER: + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &buttons); + if (buttons == SCREEN_LEFT_MOUSE_BUTTON) { // Down + input_state.pointer_x[0] = pair[0] * g_dpi_scale; + input_state.pointer_y[0] = pair[1] * g_dpi_scale; + input_state.pointer_down[0] = true; + + input.x = pair[0] * g_dpi_scale; + input.y = pair[1] * g_dpi_scale; + input.flags = TOUCH_DOWN; + input.id = 0; + NativeTouch(input); + } else if (input_state.pointer_down[0]) { // Up + input_state.pointer_x[0] = pair[0] * g_dpi_scale; + input_state.pointer_y[0] = pair[1] * g_dpi_scale; + input_state.pointer_down[0] = false; + + input.x = pair[0] * g_dpi_scale; + input.y = pair[1] * g_dpi_scale; + input.flags = TOUCH_UP; + input.id = 0; + NativeTouch(input); + } + break; + // Keyboard + case SCREEN_EVENT_KEYBOARD: + int flags, value; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags); + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &value); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawBlackberrytoNative.find(value)->second, (flags & KEY_DOWN) ? KEY_DOWN : KEY_UP)); + break; + // Gamepad + case SCREEN_EVENT_GAMEPAD: + case SCREEN_EVENT_JOYSTICK: + int analog0[3]; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &buttons); + for (int i = 0; i < 32; i++) { + int mask = 1 << i; + if ((old_buttons & mask) != (buttons & mask)) + NativeKey(KeyInput(DEVICE_ID_PAD_0, KeyMapPadBlackberrytoNative.find(mask)->second, (buttons & mask) ? KEY_DOWN : KEY_UP)); + } + if (!screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ANALOG0, analog0)) { + for (int i = 0; i < 2; i++) { + AxisInput axis; + axis.axisId = JOYSTICK_AXIS_X + i; + // 1.2 to try to approximate the PSP's clamped rectangular range. + axis.value = 1.2 * analog0[i] / 128.0f; + if (axis.value > 1.0f) axis.value = 1.0f; + if (axis.value < -1.0f) axis.value = -1.0f; + axis.deviceId = DEVICE_ID_PAD_0; + axis.flags = 0; + NativeAxis(axis); + } + } + old_buttons = buttons; + break; + case SCREEN_EVENT_DISPLAY: + screen_display_t new_dpy = NULL; + screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_DISPLAY, (void **)&new_dpy); + for (int i = 0; i < ndisplays; i++) { + if (new_dpy != screen_dpy[i]) + continue; + int active = 0; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ATTACHED, &active); + if (active) { + int size[2]; + screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_SIZE, size); + if (size[0] == 0 || size[1] == 0) + active = 0; + } + if (active && !displays[i].attached) + realiseDisplay(i); + else if (!active && displays[i].attached && displays[i].realised) + unrealiseDisplay(i); + displays[i].attached = active; + } + break; + } +} + +void BlackberryMain::startMain(int argc, char *argv[]) { + g_quitRequested = false; + // Receive events from window manager + screen_create_context(&screen_cxt, 0); + // Initialise Blackberry Platform Services + bps_initialize(); + // TODO: Enable/disable based on setting + sensor_set_rate(SENSOR_TYPE_ACCELEROMETER, 25000); + sensor_request_events(SENSOR_TYPE_ACCELEROMETER); + + net::Init(); + startDisplays(); + screen_request_events(screen_cxt); + navigator_request_events(0); + dialog_request_events(0); + vibration_request_events(0); + NativeInit(argc, (const char **)argv, "/accounts/1000/shared/misc/", "app/native/assets/", "BADCOFFEE"); + NativeInitGraphics(); + audio = new BlackberryAudio(); + runMain(); +} + +void BlackberryMain::runMain() { + bool running = true; + while (running && !g_quitRequested) { + input_state.mouse_valid = false; + input_state.accelerometer_valid = false; + while (true) { + // Handle Blackberry events + bps_event_t *event = NULL; + bps_get_event(&event, 0); + if (event == NULL) + break; // Ran out of events + int domain = bps_event_get_domain(event); + if (domain == screen_get_domain()) { + handleInput(screen_event_get_event(event)); + } else if (domain == navigator_get_domain()) { + switch(bps_event_get_code(event)) + { + case NAVIGATOR_INVOKE_TARGET: + { + const navigator_invoke_invocation_t *invoke = navigator_invoke_event_get_invocation(event); + if(invoke) { + boot_filename = navigator_invoke_invocation_get_uri(invoke)+7; // Remove file:// + } + } + break; + case NAVIGATOR_ORIENTATION: + sensor_remap_coordinates(navigator_event_get_orientation_angle(event)); + break; + case NAVIGATOR_WINDOW_STATE: + Core_NotifyWindowHidden(navigator_event_get_window_state(event) != NAVIGATOR_WINDOW_FULLSCREEN); + break; + case NAVIGATOR_BACK: + case NAVIGATOR_SWIPE_DOWN: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_BACK, KEY_DOWN)); + break; + case NAVIGATOR_EXIT: + return; + } + } else if (domain == sensor_get_domain()) { + if (SENSOR_ACCELEROMETER_READING == bps_event_get_code(event)) { + sensor_event_get_xyz(event, &(input_state.acc.y), &(input_state.acc.x), &(input_state.acc.z)); + AxisInput axis; + axis.deviceId = DEVICE_ID_ACCELEROMETER; + axis.flags = 0; + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X; + axis.value = input_state.acc.x; + NativeAxis(axis); + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y; + axis.value = input_state.acc.y; + NativeAxis(axis); + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z; + axis.value = input_state.acc.z; + NativeAxis(axis); + } + } + } + UpdateInputState(&input_state); + // Work in Progress + // Currently: Render to HDMI port (eg. 1080p) when in game. Render to device when in menu. + // Idea: Render to all displays. Controls go to internal, game goes to external(s). + if (GetUIState() == UISTATE_INGAME && !emulating) { + emulating = true; + switchDisplay(screen_emu); + if (g_Config.iShowFPSCounter == 4) { + int options = SCREEN_DEBUG_STATISTICS; + screen_set_window_property_iv(screen_win[0], SCREEN_PROPERTY_DEBUG, &options); + } + } else if (GetUIState() != UISTATE_INGAME && emulating) { + emulating = false; + switchDisplay(screen_ui); + } + time_update(); + UpdateRunLoop(); + // This handles VSync + if (emulating) + eglSwapBuffers(egl_disp[screen_emu], egl_surf[screen_emu]); + else + eglSwapBuffers(egl_disp[screen_ui], egl_surf[screen_ui]); + } +} + +void BlackberryMain::endMain() { + screen_stop_events(screen_cxt); + bps_shutdown(); + NativeShutdownGraphics(); + delete audio; + NativeShutdown(); + killDisplays(); + net::Shutdown(); + screen_destroy_context(screen_cxt); +} + +// Entry Point +int main(int argc, char *argv[]) { + delete new BlackberryMain(argc, argv); + return 0; +} diff --git a/ext/native/base/BlackberryMain.h b/ext/native/base/BlackberryMain.h new file mode 100644 index 0000000000..fe4af41d4c --- /dev/null +++ b/ext/native/base/BlackberryMain.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013 Sacha Refshauge + * + */ +// Blackberry implementation of the framework. +#ifndef BLACKBERRYMAIN_H +#define BLACKBERRYMAIN_H + +// Blackberry specific +#include // Blackberry Platform Services +#include // Blackberry Window Manager +#include // Invoke Service +#include // Keyboard Service +#include // Accelerometer +#include // Dialog Service (Toast=BB10) +#include // Vibrate Service (BB10) +#include "sys/keycodes.h" +#include "input/keycodes.h" + +// Display +#include +#include +#include +#include +#include "Core/System.h" + +// Native +#include "base/timeutil.h" +#include "gfx_es2/glsl_program.h" +#include "file/zip_read.h" +#include "base/NativeApp.h" +#include "input/input_state.h" +#include "net/resolve.h" +#include "base/display.h" + +#include "BlackberryAudio.h" + +struct dispdata_t { + int attached; + int type; + bool realised; + int width, height; +}; + +class BlackberryMain +{ +public: + BlackberryMain(int argc, char *argv[]) : + emulating(false), + screen_ui(0), screen_emu(0), + old_buttons(0), + egl_cont(EGL_NO_CONTEXT) + { + startMain(argc, argv); + } + ~BlackberryMain() { + endMain(); + } + void startMain(int argc, char *argv[]); + +private: + void runMain(); + void endMain(); + + void handleInput(screen_event_t screen_event); + + const char* displayTypeString(int type); + void startDisplays(); + void* startDisplay(int idx); + void realiseDisplay(int idx); + void unrealiseDisplay(int idx); + void switchDisplay(int idx); + void killDisplays(); + void killDisplay(int idx, bool killContext); + + BlackberryAudio* audio; + dispdata_t *displays; + int dpi; + int ndisplays; + int screen_ui, screen_emu; + bool emulating; + int old_buttons; + EGLDisplay* egl_disp; + EGLSurface* egl_surf; + EGLContext egl_cont; + EGLConfig egl_conf; + screen_context_t screen_cxt; + screen_display_t *screen_dpy; + screen_window_t *screen_win; +}; + +#endif + diff --git a/ext/native/base/CMakeLists.txt b/ext/native/base/CMakeLists.txt new file mode 100644 index 0000000000..54b0cd67f8 --- /dev/null +++ b/ext/native/base/CMakeLists.txt @@ -0,0 +1,20 @@ +set(SRCS + colorutil.cpp + timeutil.cpp + ../thread/threadutil.cpp + error_context.cpp + display.cpp + buffer.cpp + backtrace.cpp) + +add_library(base STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) + +add_library(timeutil STATIC timeutil.cpp) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/base/NKCodeFromBlackberry.h b/ext/native/base/NKCodeFromBlackberry.h new file mode 100644 index 0000000000..d32f39bd9e --- /dev/null +++ b/ext/native/base/NKCodeFromBlackberry.h @@ -0,0 +1,100 @@ +#include +#include "util/const_map.h" + +static const std::map KeyMapPadBlackberrytoNative = InitConstMap + (SCREEN_A_GAME_BUTTON, NKCODE_BUTTON_A) + (SCREEN_B_GAME_BUTTON, NKCODE_BUTTON_B) + (SCREEN_C_GAME_BUTTON, NKCODE_BUTTON_C) + (SCREEN_X_GAME_BUTTON, NKCODE_BUTTON_X) + (SCREEN_Y_GAME_BUTTON, NKCODE_BUTTON_Y) + (SCREEN_Z_GAME_BUTTON, NKCODE_BUTTON_Z) + (SCREEN_MENU1_GAME_BUTTON, NKCODE_BUTTON_START) + (SCREEN_MENU2_GAME_BUTTON, NKCODE_BUTTON_SELECT) + (SCREEN_MENU3_GAME_BUTTON, NKCODE_MENU) + (SCREEN_MENU4_GAME_BUTTON, NKCODE_BACK) + (SCREEN_L1_GAME_BUTTON, NKCODE_BUTTON_L1) + (SCREEN_L2_GAME_BUTTON, NKCODE_BUTTON_L2) + (SCREEN_L3_GAME_BUTTON, NKCODE_OUYA_BUTTON_L3) + (SCREEN_R1_GAME_BUTTON, NKCODE_BUTTON_R1) + (SCREEN_R2_GAME_BUTTON, NKCODE_BUTTON_R2) + (SCREEN_R3_GAME_BUTTON, NKCODE_OUYA_BUTTON_R3) + (SCREEN_DPAD_UP_GAME_BUTTON, NKCODE_DPAD_UP) + (SCREEN_DPAD_DOWN_GAME_BUTTON, NKCODE_DPAD_DOWN) + (SCREEN_DPAD_LEFT_GAME_BUTTON, NKCODE_DPAD_LEFT) + (SCREEN_DPAD_RIGHT_GAME_BUTTON, NKCODE_DPAD_RIGHT); + +// TODO: Add any missing keys +static const std::map KeyMapRawBlackberrytoNative = InitConstMap + (KEYCODE_P, NKCODE_P) + (KEYCODE_O, NKCODE_O) + (KEYCODE_I, NKCODE_I) + (KEYCODE_U, NKCODE_U) + (KEYCODE_Y, NKCODE_Y) + (KEYCODE_T, NKCODE_T) + (KEYCODE_R, NKCODE_R) + (KEYCODE_E, NKCODE_E) + (KEYCODE_W, NKCODE_W) + (KEYCODE_Q, NKCODE_Q) + (KEYCODE_L, NKCODE_L) + (KEYCODE_K, NKCODE_K) + (KEYCODE_J, NKCODE_J) + (KEYCODE_H, NKCODE_H) + (KEYCODE_G, NKCODE_G) + (KEYCODE_F, NKCODE_F) + (KEYCODE_D, NKCODE_D) + (KEYCODE_S, NKCODE_S) + (KEYCODE_A, NKCODE_A) + (KEYCODE_M, NKCODE_M) + (KEYCODE_N, NKCODE_N) + (KEYCODE_B, NKCODE_B) + (KEYCODE_V, NKCODE_V) + (KEYCODE_C, NKCODE_C) + (KEYCODE_X, NKCODE_X) + (KEYCODE_Z, NKCODE_Z) + (KEYCODE_COMMA, NKCODE_COMMA) + (KEYCODE_PERIOD, NKCODE_PERIOD) + (KEYCODE_LEFT_ALT, NKCODE_ALT_LEFT) + (KEYCODE_RIGHT_ALT, NKCODE_ALT_RIGHT) + (KEYCODE_LEFT_SHIFT, NKCODE_SHIFT_LEFT) + (KEYCODE_RIGHT_SHIFT, NKCODE_SHIFT_RIGHT) + (KEYCODE_TAB, NKCODE_TAB) + (KEYCODE_SPACE, NKCODE_SPACE) + (KEYCODE_RETURN, NKCODE_ENTER) + (KEYCODE_MINUS, NKCODE_MINUS) + (KEYCODE_EQUAL, NKCODE_EQUALS) + (KEYCODE_LEFT_BRACKET, NKCODE_LEFT_BRACKET) + (KEYCODE_RIGHT_BRACKET, NKCODE_RIGHT_BRACKET) + (KEYCODE_BACK_SLASH, NKCODE_BACKSLASH) + (KEYCODE_SEMICOLON, NKCODE_SEMICOLON) + (KEYCODE_APOSTROPHE, NKCODE_APOSTROPHE) + (KEYCODE_SLASH, NKCODE_SLASH) + (KEYCODE_AT, NKCODE_AT) + (KEYCODE_PLUS, NKCODE_PLUS) + (KEYCODE_ESCAPE, NKCODE_ESCAPE) + (KEYCODE_DELETE, NKCODE_FORWARD_DEL) + (KEYCODE_LEFT_CTRL, NKCODE_CTRL_LEFT) + (KEYCODE_RIGHT_CTRL, NKCODE_CTRL_RIGHT) + (KEYCODE_CAPS_LOCK, NKCODE_CAPS_LOCK) + (KEYCODE_HOME, NKCODE_MOVE_HOME) + (KEYCODE_END, NKCODE_MOVE_END) + (KEYCODE_INSERT, NKCODE_INSERT) + (KEYCODE_ZERO, NKCODE_0) + (KEYCODE_ONE, NKCODE_1) + (KEYCODE_TWO, NKCODE_2) + (KEYCODE_THREE, NKCODE_3) + (KEYCODE_FOUR, NKCODE_4) + (KEYCODE_FIVE, NKCODE_5) + (KEYCODE_SIX, NKCODE_6) + (KEYCODE_SEVEN, NKCODE_7) + (KEYCODE_EIGHT, NKCODE_8) + (KEYCODE_NINE, NKCODE_9) + (KEYCODE_KP_DIVIDE, NKCODE_NUMPAD_DIVIDE) + (KEYCODE_KP_MULTIPLY, NKCODE_NUMPAD_MULTIPLY) + (KEYCODE_KP_MINUS, NKCODE_NUMPAD_SUBTRACT) + (KEYCODE_KP_PLUS, NKCODE_NUMPAD_ADD) + (KEYCODE_KP_ENTER, NKCODE_NUMPAD_ENTER) + (KEYCODE_LEFT, NKCODE_DPAD_LEFT) + (KEYCODE_UP, NKCODE_DPAD_UP) + (KEYCODE_RIGHT, NKCODE_DPAD_RIGHT) + (KEYCODE_DOWN, NKCODE_DPAD_DOWN); + diff --git a/ext/native/base/NKCodeFromQt.h b/ext/native/base/NKCodeFromQt.h new file mode 100644 index 0000000000..cb6a79da84 --- /dev/null +++ b/ext/native/base/NKCodeFromQt.h @@ -0,0 +1,101 @@ +#include "util/const_map.h" +#include + +// TODO: Add any missing keys +static const std::map KeyMapRawQttoNative = InitConstMap + (Qt::Key_P, NKCODE_P) + (Qt::Key_O, NKCODE_O) + (Qt::Key_I, NKCODE_I) + (Qt::Key_U, NKCODE_U) + (Qt::Key_Y, NKCODE_Y) + (Qt::Key_T, NKCODE_T) + (Qt::Key_R, NKCODE_R) + (Qt::Key_E, NKCODE_E) + (Qt::Key_W, NKCODE_W) + (Qt::Key_Q, NKCODE_Q) + (Qt::Key_L, NKCODE_L) + (Qt::Key_K, NKCODE_K) + (Qt::Key_J, NKCODE_J) + (Qt::Key_H, NKCODE_H) + (Qt::Key_G, NKCODE_G) + (Qt::Key_F, NKCODE_F) + (Qt::Key_D, NKCODE_D) + (Qt::Key_S, NKCODE_S) + (Qt::Key_A, NKCODE_A) + (Qt::Key_M, NKCODE_M) + (Qt::Key_N, NKCODE_N) + (Qt::Key_B, NKCODE_B) + (Qt::Key_V, NKCODE_V) + (Qt::Key_C, NKCODE_C) + (Qt::Key_X, NKCODE_X) + (Qt::Key_Z, NKCODE_Z) + (Qt::Key_P + 0x20, NKCODE_P) + (Qt::Key_O + 0x20, NKCODE_O) + (Qt::Key_I + 0x20, NKCODE_I) + (Qt::Key_U + 0x20, NKCODE_U) + (Qt::Key_Y + 0x20, NKCODE_Y) + (Qt::Key_T + 0x20, NKCODE_T) + (Qt::Key_R + 0x20, NKCODE_R) + (Qt::Key_E + 0x20, NKCODE_E) + (Qt::Key_W + 0x20, NKCODE_W) + (Qt::Key_Q + 0x20, NKCODE_Q) + (Qt::Key_L + 0x20, NKCODE_L) + (Qt::Key_K + 0x20, NKCODE_K) + (Qt::Key_J + 0x20, NKCODE_J) + (Qt::Key_H + 0x20, NKCODE_H) + (Qt::Key_G + 0x20, NKCODE_G) + (Qt::Key_F + 0x20, NKCODE_F) + (Qt::Key_D + 0x20, NKCODE_D) + (Qt::Key_S + 0x20, NKCODE_S) + (Qt::Key_A + 0x20, NKCODE_A) + (Qt::Key_M + 0x20, NKCODE_M) + (Qt::Key_N + 0x20, NKCODE_N) + (Qt::Key_B + 0x20, NKCODE_B) + (Qt::Key_V + 0x20, NKCODE_V) + (Qt::Key_C + 0x20, NKCODE_C) + (Qt::Key_X + 0x20, NKCODE_X) + (Qt::Key_Z + 0x20, NKCODE_Z) + (Qt::Key_Comma, NKCODE_COMMA) + (Qt::Key_Period, NKCODE_PERIOD) + (Qt::Key_Alt, NKCODE_ALT_LEFT) + (Qt::Key_Shift, NKCODE_SHIFT_LEFT) + (Qt::Key_Tab, NKCODE_TAB) + (Qt::Key_Space, NKCODE_SPACE) + (Qt::Key_Return, NKCODE_ENTER) + (Qt::Key_Minus, NKCODE_MINUS) + (Qt::Key_Minus, NKCODE_PLUS) + (Qt::Key_Equal, NKCODE_EQUALS) + (Qt::Key_BracketLeft, NKCODE_LEFT_BRACKET) + (Qt::Key_BracketRight, NKCODE_RIGHT_BRACKET) + (Qt::Key_Backslash, NKCODE_BACKSLASH) + (Qt::Key_Semicolon, NKCODE_SEMICOLON) + (Qt::Key_Apostrophe, NKCODE_APOSTROPHE) + (Qt::Key_Slash, NKCODE_SLASH) + (Qt::Key_At, NKCODE_AT) + (Qt::Key_PageUp, NKCODE_PAGE_UP) + (Qt::Key_PageDown, NKCODE_PAGE_DOWN) + (Qt::Key_Escape, NKCODE_ESCAPE) + (Qt::Key_Delete, NKCODE_FORWARD_DEL) + (Qt::Key_Control, NKCODE_CTRL_LEFT) + (Qt::Key_CapsLock, NKCODE_CAPS_LOCK) + (Qt::Key_Home, NKCODE_MOVE_HOME) + (Qt::Key_End, NKCODE_MOVE_END) + (Qt::Key_Insert, NKCODE_INSERT) + (Qt::Key_Period, NKCODE_NUMPAD_DOT) + (Qt::Key_Enter, NKCODE_NUMPAD_ENTER) + (Qt::Key_1, NKCODE_1) + (Qt::Key_2, NKCODE_2) + (Qt::Key_3, NKCODE_3) + (Qt::Key_4, NKCODE_4) + (Qt::Key_5, NKCODE_5) + (Qt::Key_6, NKCODE_6) + (Qt::Key_7, NKCODE_7) + (Qt::Key_8, NKCODE_8) + (Qt::Key_9, NKCODE_9) + (Qt::Key_0, NKCODE_0) + (Qt::Key_Left, NKCODE_DPAD_LEFT) + (Qt::Key_Up, NKCODE_DPAD_UP) + (Qt::Key_Right, NKCODE_DPAD_RIGHT) + (Qt::Key_Down, NKCODE_DPAD_DOWN) + (Qt::Key_Back, NKCODE_BACK); + diff --git a/ext/native/base/NKCodeFromSDL.h b/ext/native/base/NKCodeFromSDL.h new file mode 100644 index 0000000000..62cb8cd6dd --- /dev/null +++ b/ext/native/base/NKCodeFromSDL.h @@ -0,0 +1,111 @@ +#pragma once + +#include "util/const_map.h" +#include + +// TODO: Add any missing keys +static const std::map KeyMapRawSDLtoNative = InitConstMap + (SDLK_p, NKCODE_P) + (SDLK_o, NKCODE_O) + (SDLK_i, NKCODE_I) + (SDLK_u, NKCODE_U) + (SDLK_y, NKCODE_Y) + (SDLK_t, NKCODE_T) + (SDLK_r, NKCODE_R) + (SDLK_e, NKCODE_E) + (SDLK_w, NKCODE_W) + (SDLK_q, NKCODE_Q) + (SDLK_l, NKCODE_L) + (SDLK_k, NKCODE_K) + (SDLK_j, NKCODE_J) + (SDLK_h, NKCODE_H) + (SDLK_g, NKCODE_G) + (SDLK_f, NKCODE_F) + (SDLK_d, NKCODE_D) + (SDLK_s, NKCODE_S) + (SDLK_a, NKCODE_A) + (SDLK_m, NKCODE_M) + (SDLK_n, NKCODE_N) + (SDLK_b, NKCODE_B) + (SDLK_v, NKCODE_V) + (SDLK_c, NKCODE_C) + (SDLK_x, NKCODE_X) + (SDLK_z, NKCODE_Z) + (SDLK_COMMA, NKCODE_COMMA) + (SDLK_PERIOD, NKCODE_PERIOD) + (SDLK_LALT, NKCODE_ALT_LEFT) + (SDLK_RALT, NKCODE_ALT_RIGHT) + (SDLK_LSHIFT, NKCODE_SHIFT_LEFT) + (SDLK_RSHIFT, NKCODE_SHIFT_RIGHT) + (SDLK_TAB, NKCODE_TAB) + (SDLK_SPACE, NKCODE_SPACE) + (SDLK_RETURN, NKCODE_ENTER) + (SDLK_MINUS, NKCODE_MINUS) + (SDLK_EQUALS, NKCODE_EQUALS) + (SDLK_LEFTBRACKET, NKCODE_LEFT_BRACKET) + (SDLK_RIGHTBRACKET, NKCODE_RIGHT_BRACKET) + (SDLK_BACKSLASH, NKCODE_BACKSLASH) + (SDLK_SEMICOLON, NKCODE_SEMICOLON) + // (SDLK_, NKCODE_APOSTROPHE) // I cannot find the SDL equiv + (SDLK_SLASH, NKCODE_SLASH) + (SDLK_AT, NKCODE_AT) + (SDLK_PLUS, NKCODE_PLUS) + (SDLK_PAGEUP, NKCODE_PAGE_UP) + (SDLK_PAGEDOWN, NKCODE_PAGE_DOWN) +#ifdef MAEMO + (SDLK_BACKSPACE, NKCODE_ESCAPE) +#else + (SDLK_ESCAPE, NKCODE_ESCAPE) + (SDLK_BACKSPACE, NKCODE_DEL) +#endif + (SDLK_DELETE, NKCODE_FORWARD_DEL) + (SDLK_LCTRL, NKCODE_CTRL_LEFT) + (SDLK_RCTRL, NKCODE_CTRL_RIGHT) + (SDLK_CAPSLOCK, NKCODE_CAPS_LOCK) + (SDLK_HOME, NKCODE_MOVE_HOME) + (SDLK_END, NKCODE_MOVE_END) + (SDLK_INSERT, NKCODE_INSERT) + (SDLK_KP_0, NKCODE_NUMPAD_0) + (SDLK_KP_1, NKCODE_NUMPAD_1) + (SDLK_KP_2, NKCODE_NUMPAD_2) + (SDLK_KP_3, NKCODE_NUMPAD_3) + (SDLK_KP_4, NKCODE_NUMPAD_4) + (SDLK_KP_5, NKCODE_NUMPAD_5) + (SDLK_KP_6, NKCODE_NUMPAD_6) + (SDLK_KP_7, NKCODE_NUMPAD_7) + (SDLK_KP_8, NKCODE_NUMPAD_8) + (SDLK_KP_9, NKCODE_NUMPAD_9) + (SDLK_KP_DIVIDE, NKCODE_NUMPAD_DIVIDE) + (SDLK_KP_MULTIPLY, NKCODE_NUMPAD_MULTIPLY) + (SDLK_KP_MINUS, NKCODE_NUMPAD_SUBTRACT) + (SDLK_KP_PLUS, NKCODE_NUMPAD_ADD) + (SDLK_KP_PERIOD, NKCODE_NUMPAD_DOT) + (SDLK_KP_ENTER, NKCODE_NUMPAD_ENTER) + (SDLK_KP_EQUALS, NKCODE_NUMPAD_EQUALS) + (SDLK_1, NKCODE_1) + (SDLK_2, NKCODE_2) + (SDLK_3, NKCODE_3) + (SDLK_4, NKCODE_4) + (SDLK_5, NKCODE_5) + (SDLK_6, NKCODE_6) + (SDLK_7, NKCODE_7) + (SDLK_8, NKCODE_8) + (SDLK_9, NKCODE_9) + (SDLK_0, NKCODE_0) + (SDLK_F1, NKCODE_F1) + (SDLK_F2, NKCODE_F2) + (SDLK_F3, NKCODE_F3) + (SDLK_F4, NKCODE_F4) + (SDLK_F5, NKCODE_F5) + (SDLK_F6, NKCODE_F6) + (SDLK_F7, NKCODE_F7) + (SDLK_F8, NKCODE_F8) + (SDLK_F9, NKCODE_F9) + (SDLK_F10, NKCODE_F10) + (SDLK_F11, NKCODE_F11) + (SDLK_F12, NKCODE_F12) + (SDLK_LEFT, NKCODE_DPAD_LEFT) + (SDLK_UP, NKCODE_DPAD_UP) + (SDLK_RIGHT, NKCODE_DPAD_RIGHT) + (SDLK_DOWN, NKCODE_DPAD_DOWN); + diff --git a/ext/native/base/NativeApp.h b/ext/native/base/NativeApp.h new file mode 100644 index 0000000000..7eb3eb43c5 --- /dev/null +++ b/ext/native/base/NativeApp.h @@ -0,0 +1,155 @@ +#pragma once + +#include + +// The Native App API. +// +// Implement these functions and you've got a native app. These are called +// from the framework, which exposes the native JNI api which is a bit +// more complicated. + +// This is defined in input/input_state.h. +struct InputState; +struct TouchInput; +struct KeyInput; +struct AxisInput; + +// The first function to get called, just write strings to the two pointers. +// This might get called multiple times in some implementations, you must be able to handle that. +void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name, bool *landscape, std::string *version); + +// Generic host->C++ messaging, used for functionality like system-native popup input boxes. +void NativeMessageReceived(const char *message, const char *value); + +// Easy way for the Java side to ask the C++ side for configuration options, such as +// the rotation lock which must be controlled from Java on Android. +// It is currently not called on non-Android platforms. +std::string NativeQueryConfig(std::string query); + +// For the back button to work right, this should return true on your main or title screen. +// Otherwise, just return false. +bool NativeIsAtTopLevel(); + +// The very first function to be called after NativeGetAppInfo. Even NativeMix is not called +// before this, although it may be called at any point in time afterwards (on any thread!) +// This functions must NOT call OpenGL. Main thread. +void NativeInit(int argc, const char *argv[], const char *savegame_directory, const char *external_directory, const char *installID, bool fs=false); + +// Runs after NativeInit() at some point. May (and probably should) call OpenGL. +// Should not initialize anything screen-size-dependent - do that in NativeResized. +void NativeInitGraphics(); + +// Signals that you need to destroy and recreate all buffered OpenGL resources, +// like textures, vbo etc. +void NativeDeviceLost(); + +// If you want to change DPI stuff (such as modifying dp_xres and dp_yres), this is the +// place to do it. You should only read g_dpi_scale and pixel_xres and pixel_yres in this, +// and only write dp_xres and dp_yres. +void NativeResized(); + +// Called ~sixty times a second, delivers the current input state. +// Main thread. +void NativeUpdate(InputState &input); + +// Delivers touch events "instantly", without waiting for the next frame so that NativeUpdate can deliver. +// Useful for triggering audio events, saving a few ms. +// If you don't care about touch latency, just do a no-op implementation of this. +// time is not yet implemented. finger can be from 0 to 7, inclusive. +bool NativeTouch(const TouchInput &touch); +bool NativeKey(const KeyInput &key); +bool NativeAxis(const AxisInput &axis); + +// Called when it's time to render. If the device can keep up, this +// will also be called sixty times per second. Main thread. +void NativeRender(); + +// This should render num_samples 44khz stereo samples. +// Try not to make too many assumptions on the granularity +// of num_samples. +// This function may be called from a totally separate thread from +// the rest of the game, so be careful with synchronization. +// Returns the number of samples actually output. The app should do everything it can +// to fill the buffer completely. +int NativeMix(short *audio, int num_samples); +void NativeSetMixer(void* mixer); + +// Called when it's time to shutdown. After this has been called, +// no more calls to any other function will be made from the framework +// before process exit. +// The graphics context should still be active when calling this, as freeing +// of graphics resources happens here. +// Main thread. +void NativeShutdownGraphics(); +void NativeShutdown(); + +// Called on app.onCreate and app.onDestroy (?). Tells the app to save/restore +// light state. If app was fully rebooted between these calls, it's okay if some minor +// state is lost (position in level) but the level currently playihg, or the song +// currently being edited, or whatever, should be restored properly. In this case, +// firstTime will be set so that appropriate action can be taken (or not taken when +// it's not set). +// +// Note that NativeRestore is always called on bootup. +void NativeRestoreState(bool firstTime); // onCreate +void NativeSaveState(); // onDestroy + +// Calls back into Java / SDL +// These APIs must be implemented by every port (for example app-android.cpp, PCMain.cpp). +// You are free to call these. +void SystemToast(const char *text); +void ShowKeyboard(); +void ShowAd(int x, int y, bool center_x); + +// Vibrate either takes a number of milliseconds to vibrate unconditionally, +// or you can specify these constants for "standard" feedback. On Android, +// these will only be performed if haptic feedback is enabled globally. +// Also, on Android, these will work even if you don't have the VIBRATE permission, +// while generic vibration will not if you don't have it. +enum { + HAPTIC_SOFT_KEYBOARD = -1, + HAPTIC_VIRTUAL_KEY = -2, + HAPTIC_LONG_PRESS_ACTIVATED = -3, +}; +void Vibrate(int length_ms); +void LaunchBrowser(const char *url); +void LaunchMarket(const char *url); +void LaunchEmail(const char *email_address); +bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outlength); +bool System_InputBoxGetWString(const wchar_t *title, const std::wstring &defaultValue, std::wstring &outValue); +void System_SendMessage(const char *command, const char *parameter); + +// This will get muddy with multi-screen support :/ But this will always be the type of the main device. +enum SystemDeviceType { + DEVICE_TYPE_MOBILE = 0, // phones and pads + DEVICE_TYPE_TV = 1, // Android TV and similar + DEVICE_TYPE_DESKTOP = 2, // Desktop computer +}; + +enum SystemProperty { + SYSPROP_NAME, + SYSPROP_LANGREGION, + SYSPROP_CPUINFO, + SYSPROP_CLIPBOARD_TEXT, + SYSPROP_GPUDRIVER_VERSION, + + // Available as Int: + SYSPROP_SYSTEMVERSION, + SYSPROP_DISPLAY_XRES, + SYSPROP_DISPLAY_YRES, + SYSPROP_DISPLAY_REFRESH_RATE, // returns 1000*the refresh rate in Hz as it can be non-integer + SYSPROP_MOGA_VERSION, + + SYSPROP_DEVICE_TYPE, + + // Exposed on Android. Choosing the optimal sample rate for audio + // will result in lower latencies. Buffer size is automatically matched + // by the OpenSL audio backend, only exposed here for debugging/info. + SYSPROP_AUDIO_SAMPLE_RATE, + SYSPROP_AUDIO_FRAMES_PER_BUFFER, + SYSPROP_AUDIO_OPTIMAL_SAMPLE_RATE, + SYSPROP_AUDIO_OPTIMAL_FRAMES_PER_BUFFER, +}; + +std::string System_GetProperty(SystemProperty prop); +int System_GetPropertyInt(SystemProperty prop); diff --git a/ext/native/base/PCMain.cpp b/ext/native/base/PCMain.cpp new file mode 100644 index 0000000000..aad89d1bee --- /dev/null +++ b/ext/native/base/PCMain.cpp @@ -0,0 +1,898 @@ +// SDL/EGL implementation of the framework. +// This is quite messy due to platform-specific implementations and #ifdef's. +// Note: SDL1.2 implementation is deprecated and will soon be replaced by SDL2.0. +// If your platform is not supported, it is suggested to use Qt instead. + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#else +#include +#include +#endif + +#include "SDL.h" +#ifndef _WIN32 +#include "SDL/SDLJoystick.h" +SDLJoystick *joystick = NULL; +#endif + +#ifdef RPI +#include +#endif + +#include + +#include "base/display.h" +#include "base/logging.h" +#include "base/timeutil.h" +#include "gfx/gl_common.h" +#include "gfx_es2/gpu_features.h" +#include "input/input_state.h" +#include "input/keycodes.h" +#include "net/resolve.h" +#include "base/NKCodeFromSDL.h" +#include "util/const_map.h" +#include "util/text/utf8.h" +#include "math/math_util.h" + +#ifdef PPSSPP +// Bad: PPSSPP includes from native +#include "Core/System.h" +#include "Core/Core.h" +#include "Core/Config.h" + +GlobalUIState lastUIState = UISTATE_MENU; +GlobalUIState GetUIState(); +#endif + +static SDL_Window* g_Screen = NULL; +static bool g_ToggleFullScreenNextFrame = false; +static int g_QuitRequested = 0; + +static int g_DesktopWidth = 0; +static int g_DesktopHeight = 0; + +#if defined(USING_EGL) +#include "EGL/egl.h" + +#if !defined(USING_FBDEV) +#include +#include +#endif + +#include "SDL_syswm.h" +#include "math.h" + +static EGLDisplay g_eglDisplay = NULL; +static EGLContext g_eglContext = NULL; +static EGLSurface g_eglSurface = NULL; +#ifdef USING_FBDEV +static EGLNativeDisplayType g_Display = NULL; +#else +static Display* g_Display = NULL; +#endif +static NativeWindowType g_Window = (NativeWindowType)NULL; + +int8_t CheckEGLErrors(const std::string& file, uint16_t line) { + EGLenum error; + std::string errortext; + + error = eglGetError(); + switch (error) + { + case EGL_SUCCESS: case 0: return 0; + case EGL_NOT_INITIALIZED: errortext = "EGL_NOT_INITIALIZED"; break; + case EGL_BAD_ACCESS: errortext = "EGL_BAD_ACCESS"; break; + case EGL_BAD_ALLOC: errortext = "EGL_BAD_ALLOC"; break; + case EGL_BAD_ATTRIBUTE: errortext = "EGL_BAD_ATTRIBUTE"; break; + case EGL_BAD_CONTEXT: errortext = "EGL_BAD_CONTEXT"; break; + case EGL_BAD_CONFIG: errortext = "EGL_BAD_CONFIG"; break; + case EGL_BAD_CURRENT_SURFACE: errortext = "EGL_BAD_CURRENT_SURFACE"; break; + case EGL_BAD_DISPLAY: errortext = "EGL_BAD_DISPLAY"; break; + case EGL_BAD_SURFACE: errortext = "EGL_BAD_SURFACE"; break; + case EGL_BAD_MATCH: errortext = "EGL_BAD_MATCH"; break; + case EGL_BAD_PARAMETER: errortext = "EGL_BAD_PARAMETER"; break; + case EGL_BAD_NATIVE_PIXMAP: errortext = "EGL_BAD_NATIVE_PIXMAP"; break; + case EGL_BAD_NATIVE_WINDOW: errortext = "EGL_BAD_NATIVE_WINDOW"; break; + default: errortext = "unknown"; break; + } + printf( "ERROR: EGL Error detected in file %s at line %d: %s (0x%X)\n", file.c_str(), line, errortext.c_str(), error ); + return 1; +} +#define EGL_ERROR(str, check) { \ + if (check) CheckEGLErrors( __FILE__, __LINE__ ); \ + printf("EGL ERROR: " str "\n"); \ + return 1; \ + } + +int8_t EGL_Open() { +#ifdef USING_FBDEV + g_Display = ((EGLNativeDisplayType)0); +#else + if ((g_Display = XOpenDisplay(NULL)) == NULL) + EGL_ERROR("Unable to get display!", false); +#endif + if ((g_eglDisplay = eglGetDisplay((NativeDisplayType)g_Display)) == EGL_NO_DISPLAY) + EGL_ERROR("Unable to create EGL display.", true); + if (eglInitialize(g_eglDisplay, NULL, NULL) != EGL_TRUE) + EGL_ERROR("Unable to initialize EGL display.", true); + return 0; +} + +int8_t EGL_Init() { + EGLConfig g_eglConfig; + EGLint g_numConfigs = 0; + EGLint attrib_list[]= { + // TODO: Should cycle through fallbacks, like on Android +#ifdef USING_FBDEV + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 6, + EGL_BLUE_SIZE, 5, +#endif + EGL_DEPTH_SIZE, 16, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, +#ifdef USING_GLES2 + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, +#else + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, +#endif + EGL_SAMPLE_BUFFERS, 0, + EGL_SAMPLES, 0, +#ifdef MAEMO + EGL_BUFFER_SIZE, 16, +#endif + EGL_NONE}; + + const EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + + EGLBoolean result = eglChooseConfig(g_eglDisplay, attrib_list, &g_eglConfig, 1, &g_numConfigs); + if (result != EGL_TRUE || g_numConfigs == 0) EGL_ERROR("Unable to query for available configs.", true); + + g_eglContext = eglCreateContext(g_eglDisplay, g_eglConfig, NULL, attributes ); + if (g_eglContext == EGL_NO_CONTEXT) EGL_ERROR("Unable to create GLES context!", true); + +#if !defined(USING_FBDEV) + //Get the SDL window handle + SDL_SysWMinfo sysInfo; //Will hold our Window information + SDL_VERSION(&sysInfo.version); //Set SDL version +#endif + +#ifdef USING_FBDEV + g_Window = (NativeWindowType)NULL; +#else + g_Window = (NativeWindowType)sysInfo.info.x11.window; +#endif + g_eglSurface = eglCreateWindowSurface(g_eglDisplay, g_eglConfig, g_Window, 0); + if (g_eglSurface == EGL_NO_SURFACE) + EGL_ERROR("Unable to create EGL surface!", true); + + if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) != EGL_TRUE) + EGL_ERROR("Unable to make GLES context current.", true); + + return 0; +} + +void EGL_Close() { + if (g_eglDisplay != NULL) { + eglMakeCurrent(g_eglDisplay, NULL, NULL, EGL_NO_CONTEXT); + if (g_eglContext != NULL) { + eglDestroyContext(g_eglDisplay, g_eglContext); + } + if (g_eglSurface != NULL) { + eglDestroySurface(g_eglDisplay, g_eglSurface); + } + eglTerminate(g_eglDisplay); + g_eglDisplay = NULL; + } + if (g_Display != NULL) { +#if !defined(USING_FBDEV) + XCloseDisplay(g_Display); +#endif + g_Display = NULL; + } + g_eglSurface = NULL; + g_eglContext = NULL; +} +#endif + +int getDisplayNumber(void) +{ + int displayNumber = 0; + char * displayNumberStr; + + //get environment + displayNumberStr=getenv("SDL_VIDEO_FULLSCREEN_HEAD"); + + if (displayNumberStr) + { + displayNumber = atoi(displayNumberStr); + } + + return displayNumber; +} + +// Simple implementations of System functions + + +void SystemToast(const char *text) { +#ifdef _WIN32 + MessageBox(0, text, "Toast!", MB_ICONINFORMATION); +#else + puts(text); +#endif +} + +void ShowKeyboard() { + // Irrelevant on PC +} + +void Vibrate(int length_ms) { + // Ignore on PC +} + +void System_SendMessage(const char *command, const char *parameter) { + if (!strcmp(command, "toggle_fullscreen")) { + g_ToggleFullScreenNextFrame = true; + } else if (!strcmp(command, "finish")) { + // Do a clean exit + g_QuitRequested = true; + } +} + +void LaunchBrowser(const char *url) { +#if defined(MOBILE_DEVICE) + ILOG("Would have gone to %s but LaunchBrowser is not implemented on this platform", url); +#elif defined(_WIN32) + ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); +#elif defined(__APPLE__) + std::string command = std::string("open ") + url; + system(command.c_str()); +#else + std::string command = std::string("xdg-open ") + url; + int err = system(command.c_str()); + if (err) { + ILOG("Would have gone to %s but xdg-utils seems not to be installed", url) + } +#endif +} + +void LaunchMarket(const char *url) { +#if defined(MOBILE_DEVICE) + ILOG("Would have gone to %s but LaunchMarket is not implemented on this platform", url); +#elif defined(_WIN32) + ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); +#elif defined(__APPLE__) + std::string command = std::string("open ") + url; + system(command.c_str()); +#else + std::string command = std::string("xdg-open ") + url; + int err = system(command.c_str()); + if (err) { + ILOG("Would have gone to %s but xdg-utils seems not to be installed", url) + } +#endif +} + +void LaunchEmail(const char *email_address) { +#if defined(MOBILE_DEVICE) + ILOG("Would have opened your email client for %s but LaunchEmail is not implemented on this platform", email_address); +#elif defined(_WIN32) + ShellExecute(NULL, "open", (std::string("mailto:") + email_address).c_str(), NULL, NULL, SW_SHOWNORMAL); +#elif defined(__APPLE__) + std::string command = std::string("open mailto:") + email_address; + system(command.c_str()); +#else + std::string command = std::string("xdg-email ") + email_address; + int err = system(command.c_str()); + if (err) { + ILOG("Would have gone to %s but xdg-utils seems not to be installed", email_address) + } +#endif +} + +std::string System_GetProperty(SystemProperty prop) { + switch (prop) { + case SYSPROP_NAME: +#ifdef _WIN32 + return "SDL:Windows"; +#elif __linux__ + return "SDL:Linux"; +#elif __APPLE__ + return "SDL:OSX"; +#else + return "SDL:"; +#endif + case SYSPROP_LANGREGION: + return "en_US"; + default: + return ""; + } +} + +int System_GetPropertyInt(SystemProperty prop) { + switch (prop) { + case SYSPROP_AUDIO_SAMPLE_RATE: + return 44100; + case SYSPROP_DISPLAY_REFRESH_RATE: + return 60000; + case SYSPROP_DEVICE_TYPE: +#if defined(MOBILE_DEVICE) + return DEVICE_TYPE_MOBILE; +#else + return DEVICE_TYPE_DESKTOP; +#endif + default: + return -1; + } +} + +InputState input_state; + +static const int legacyKeyMap[] { + NKCODE_X, //A + NKCODE_S, //B + NKCODE_Z, //X + NKCODE_A, //Y + NKCODE_W, //LBUMPER + NKCODE_Q, //RBUMPER + NKCODE_1, //START + NKCODE_2, //SELECT + NKCODE_DPAD_UP, //UP + NKCODE_DPAD_DOWN, //DOWN + NKCODE_DPAD_LEFT, //LEFT + NKCODE_DPAD_RIGHT, //RIGHT + 0, //MENU (SwipeDown) + NKCODE_ESCAPE, //BACK + NKCODE_I, //JOY UP + NKCODE_K, //JOY DOWN + NKCODE_J, //JOY LEFT + NKCODE_L, //JOY RIGHT +}; + +void SimulateGamepad(const uint8_t *keys, InputState *input) { + // Legacy key mapping. + input->pad_buttons = 0; + input->pad_lstick_x = 0; + input->pad_lstick_y = 0; + input->pad_rstick_x = 0; + input->pad_rstick_y = 0; +} + +extern void mixaudio(void *userdata, Uint8 *stream, int len) { + NativeMix((short *)stream, len / 4); +} + +// returns -1 on failure +static int parseInt(const char *str) { + int val; + int retval = sscanf(str, "%d", &val); + printf("%i = scanf %s\n", retval, str); + if (retval != 1) { + return -1; + } else { + return val; + } +} + +static float parseFloat(const char *str) { + float val; + int retval = sscanf(str, "%f", &val); + printf("%i = sscanf %s\n", retval, str); + if (retval != 1) { + return -1.0f; + } else { + return val; + } +} + +void ToggleFullScreenIfFlagSet() { + if (g_ToggleFullScreenNextFrame) { + g_ToggleFullScreenNextFrame = false; + + Uint32 window_flags = SDL_GetWindowFlags(g_Screen); + SDL_SetWindowFullscreen(g_Screen, window_flags ^ SDL_WINDOW_FULLSCREEN_DESKTOP); + } +} + +#ifdef _WIN32 +#undef main +#endif +int main(int argc, char *argv[]) { +#ifdef RPI + bcm_host_init(); +#endif + putenv((char*)"SDL_VIDEO_CENTERED=1"); + + std::string app_name; + std::string app_name_nice; + std::string version; + bool landscape; + NativeGetAppInfo(&app_name, &app_name_nice, &landscape, &version); + + net::Init(); + + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0) { + fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + +#ifdef __APPLE__ + // Make sure to request a somewhat modern GL context at least - the + // latest supported by MacOSX (really, really sad...) + // Requires SDL 2.0 + // We really should upgrade to SDL 2.0 soon. + //SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); +#endif + +#ifdef USING_EGL + if (EGL_Open()) + return 1; +#endif + + // Get the video info before doing anything else, so we don't get skewed resolution results. + // TODO: support multiple displays correctly + SDL_DisplayMode displayMode; + int should_be_zero = SDL_GetCurrentDisplayMode(0, &displayMode); + if (should_be_zero != 0) { + fprintf(stderr, "Could not get display mode: %s\n", SDL_GetError()); + return 1; + } + g_DesktopWidth = displayMode.w; + g_DesktopHeight = displayMode.h; + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetSwapInterval(1); + + Uint32 mode; +#ifdef USING_GLES2 + mode = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN; +#else + mode = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; +#endif + int set_xres = -1; + int set_yres = -1; + bool portrait = false; + bool set_ipad = false; + float set_dpi = 1.0f; + float set_scale = 1.0f; + + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i],"--fullscreen")) + mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; + if (set_xres == -2) { + set_xres = parseInt(argv[i]); + } else if (set_yres == -2) { + set_yres = parseInt(argv[i]); + } + if (set_dpi == -2) + set_dpi = parseFloat(argv[i]); + if (set_scale == -2) + set_scale = parseFloat(argv[i]); + + if (!strcmp(argv[i],"--xres")) + set_xres = -2; + if (!strcmp(argv[i],"--yres")) + set_yres = -2; + if (!strcmp(argv[i],"--dpi")) + set_dpi = -2; + if (!strcmp(argv[i],"--scale")) + set_scale = -2; + + if (!strcmp(argv[i],"--ipad")) + set_ipad = true; + if (!strcmp(argv[i],"--portrait")) + portrait = true; + } + + // Is resolution is too low to run windowed + if (g_DesktopWidth < 480 * 2 && g_DesktopHeight < 272 * 2) { + mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; + } + + if (mode & SDL_WINDOW_FULLSCREEN_DESKTOP) { + pixel_xres = g_DesktopWidth; + pixel_yres = g_DesktopHeight; +#ifdef PPSSPP + g_Config.bFullScreen = true; +#endif + } else { + // set a sensible default resolution (2x) + pixel_xres = 480 * 2 * set_scale; + pixel_yres = 272 * 2 * set_scale; + if (portrait) { + std::swap(pixel_xres, pixel_yres); + } +#ifdef PPSSPP + g_Config.bFullScreen = false; +#endif + } + + set_dpi = 1.0f / set_dpi; + + if (set_ipad) { + pixel_xres = 1024; + pixel_yres = 768; + } + if (!landscape) { + std::swap(pixel_xres, pixel_yres); + } + + if (set_xres > 0) { + pixel_xres = set_xres; + } + if (set_yres > 0) { + pixel_yres = set_yres; + } + float dpi_scale = 1.0f; + if (set_dpi > 0) { + dpi_scale = set_dpi; + } + + dp_xres = (float)pixel_xres * dpi_scale; + dp_yres = (float)pixel_yres * dpi_scale; + + g_Screen = SDL_CreateWindow(app_name_nice.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber()),\ + SDL_WINDOWPOS_UNDEFINED, pixel_xres, pixel_yres, mode); + + if (g_Screen == NULL) { + fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); + SDL_Quit(); + return 2; + } + + SDL_GLContext glContext = SDL_GL_CreateContext(g_Screen); + if (glContext == NULL) { + fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError()); + SDL_Quit(); + return 2; + } + +#ifdef USING_EGL + EGL_Init(); +#endif + +#ifdef PPSSPP + SDL_SetWindowTitle(g_Screen, (app_name_nice + " " + PPSSPP_GIT_VERSION).c_str()); +#endif + +#ifdef MOBILE_DEVICE + SDL_ShowCursor(SDL_DISABLE); +#endif + + +#ifndef USING_GLES2 + if (GLEW_OK != glewInit()) { + printf("Failed to initialize glew!\n"); + return 1; + } + + if (GLEW_VERSION_2_0) { + printf("OpenGL 2.0 or higher.\n"); + } else { + printf("Sorry, this program requires OpenGL 2.0.\n"); + return 1; + } +#endif + +#ifdef _MSC_VER + // VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\")); + TCHAR path[MAX_PATH]; + SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path); + PathAppend(path, (app_name + "\\").c_str()); +#else + // Mac / Linux + char path[2048]; + const char *the_path = getenv("HOME"); + if (!the_path) { + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + the_path = pwd->pw_dir; + } + strcpy(path, the_path); + if (path[strlen(path)-1] != '/') + strcat(path, "/"); +#endif + +#ifdef _WIN32 + NativeInit(argc, (const char **)argv, path, "D:\\", "BADCOFFEE"); +#else + NativeInit(argc, (const char **)argv, path, "/tmp", "BADCOFFEE"); +#endif + + pixel_in_dps = (float)pixel_xres / dp_xres; + g_dpi_scale = dp_xres / (float)pixel_xres; + + printf("Pixels: %i x %i\n", pixel_xres, pixel_yres); + printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres); + + NativeInitGraphics(); + NativeResized(); + + SDL_AudioSpec fmt, ret_fmt; + memset(&fmt, 0, sizeof(fmt)); + fmt.freq = 44100; + fmt.format = AUDIO_S16; + fmt.channels = 2; + fmt.samples = 2048; + fmt.callback = &mixaudio; + fmt.userdata = (void *)0; + + if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) { + ELOG("Failed to open audio: %s", SDL_GetError()); + } else { + if (ret_fmt.samples != fmt.samples) // Notify, but still use it + ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples); + if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) { + ELOG("Sound buffer format does not match requested format."); + ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq); + ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format); + ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels); + ELOG("Provided output format does not match requirement, turning audio off"); + SDL_CloseAudio(); + } + } + + // Audio must be unpaused _after_ NativeInit() + SDL_PauseAudio(0); +#ifndef _WIN32 + joystick = new SDLJoystick(); +#endif + EnableFZ(); + + int framecount = 0; + float t = 0; + float lastT = 0; + uint32_t pad_buttons = 0; // legacy pad buttons + while (true) { + input_state.accelerometer_valid = false; + input_state.mouse_valid = true; + + SDL_Event event; + while (SDL_PollEvent(&event)) { + float mx = event.motion.x * g_dpi_scale; + float my = event.motion.y * g_dpi_scale; + + switch (event.type) { + case SDL_QUIT: + g_QuitRequested = 1; + break; +#if !defined(MOBILE_DEVICE) + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_RESIZED: + { + Uint32 window_flags = SDL_GetWindowFlags(g_Screen); + bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN); + + pixel_xres = event.window.data1; + pixel_yres = event.window.data2; + dp_xres = (float)pixel_xres * dpi_scale; + dp_yres = (float)pixel_yres * dpi_scale; + NativeResized(); + +#if defined(PPSSPP) + // Set variable here in case fullscreen was toggled by hotkey + g_Config.bFullScreen = fullscreen; + + // Hide/Show cursor correctly toggling fullscreen + if (lastUIState == UISTATE_INGAME && fullscreen && !g_Config.bShowTouchControls) { + SDL_ShowCursor(SDL_DISABLE); + } else if (lastUIState != UISTATE_INGAME || !fullscreen) { + SDL_ShowCursor(SDL_ENABLE); + } +#endif + break; + } + break; + } +#endif + case SDL_KEYDOWN: + { + int k = event.key.keysym.sym; + KeyInput key; + key.flags = KEY_DOWN; + key.keyCode = KeyMapRawSDLtoNative.find(k)->second; + key.deviceId = DEVICE_ID_KEYBOARD; + NativeKey(key); + + for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) { + if (legacyKeyMap[i] == key.keyCode) + pad_buttons |= 1 << i; + } + break; + } + case SDL_KEYUP: + { + int k = event.key.keysym.sym; + KeyInput key; + key.flags = KEY_UP; + key.keyCode = KeyMapRawSDLtoNative.find(k)->second; + key.deviceId = DEVICE_ID_KEYBOARD; + NativeKey(key); + for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) { + if (legacyKeyMap[i] == key.keyCode) + pad_buttons &= ~(1 << i); + } + break; + } + case SDL_TEXTINPUT: + { + int pos = 0; + int c = u8_nextchar(event.text.text, &pos); + KeyInput key; + key.flags = KEY_CHAR; + key.keyCode = c; + key.deviceId = DEVICE_ID_KEYBOARD; + NativeKey(key); + break; + } + case SDL_MOUSEBUTTONDOWN: + switch (event.button.button) { + case SDL_BUTTON_LEFT: + { + input_state.pointer_x[0] = mx; + input_state.pointer_y[0] = my; + input_state.pointer_down[0] = true; + input_state.mouse_valid = true; + TouchInput input; + input.x = mx; + input.y = my; + input.flags = TOUCH_DOWN | TOUCH_MOUSE; + input.id = 0; + NativeTouch(input); + KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_DOWN); + NativeKey(key); + } + break; + case SDL_BUTTON_RIGHT: + { + KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_DOWN); + NativeKey(key); + } + break; + } + break; + case SDL_MOUSEWHEEL: + { + KeyInput key; + key.deviceId = DEVICE_ID_MOUSE; + if (event.wheel.y > 0) { + key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP; + } else { + key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN; + } + key.flags = KEY_DOWN; + NativeKey(key); + + // SDL2 doesn't consider the mousewheel a button anymore + // so let's send the KEY_UP right away. + // Maybe KEY_UP alone will suffice? + key.flags = KEY_UP; + NativeKey(key); + } + case SDL_MOUSEMOTION: + if (input_state.pointer_down[0]) { + input_state.pointer_x[0] = mx; + input_state.pointer_y[0] = my; + input_state.mouse_valid = true; + TouchInput input; + input.x = mx; + input.y = my; + input.flags = TOUCH_MOVE | TOUCH_MOUSE; + input.id = 0; + NativeTouch(input); + } + break; + case SDL_MOUSEBUTTONUP: + switch (event.button.button) { + case SDL_BUTTON_LEFT: + { + input_state.pointer_x[0] = mx; + input_state.pointer_y[0] = my; + input_state.pointer_down[0] = false; + input_state.mouse_valid = true; + //input_state.mouse_buttons_up = 1; + TouchInput input; + input.x = mx; + input.y = my; + input.flags = TOUCH_UP | TOUCH_MOUSE; + input.id = 0; + NativeTouch(input); + KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_UP); + NativeKey(key); + } + break; + case SDL_BUTTON_RIGHT: + { + KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_UP); + NativeKey(key); + } + break; + } + break; + default: +#ifndef _WIN32 + joystick->ProcessInput(event); +#endif + break; + } + } + if (g_QuitRequested) + break; + const uint8_t *keys = SDL_GetKeyboardState(NULL); + SimulateGamepad(keys, &input_state); + input_state.pad_buttons = pad_buttons; + UpdateInputState(&input_state, true); +#ifdef PPSSPP + UpdateRunLoop(); +#else + NativeUpdate(input_state); + NativeRender(); +#endif + if (g_QuitRequested) + break; +#if defined(PPSSPP) && !defined(MOBILE_DEVICE) + if (lastUIState != GetUIState()) { + lastUIState = GetUIState(); + if (lastUIState == UISTATE_INGAME && g_Config.bFullScreen && !g_Config.bShowTouchControls) + SDL_ShowCursor(SDL_DISABLE); + if (lastUIState != UISTATE_INGAME && g_Config.bFullScreen) + SDL_ShowCursor(SDL_ENABLE); + } +#endif + + if (framecount % 60 == 0) { + // glsl_refresh(); // auto-reloads modified GLSL shaders once per second. + } + +#ifdef USING_EGL + eglSwapBuffers(g_eglDisplay, g_eglSurface); +#else + if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0) + { + SDL_GL_SwapWindow(g_Screen); + lastT = t; + } +#endif + + ToggleFullScreenIfFlagSet(); + time_update(); + t = time_now(); + framecount++; + } +#ifndef _WIN32 + delete joystick; +#endif + // Faster exit, thanks to the OS. Remove this if you want to debug shutdown + // The speed difference is only really noticable on Linux. On Windows you do notice it though +#ifndef MOBILE_DEVICE + exit(0); +#endif + NativeShutdownGraphics(); + SDL_PauseAudio(1); + SDL_CloseAudio(); + NativeShutdown(); +#ifdef USING_EGL + EGL_Close(); +#endif + SDL_GL_DeleteContext(glContext); + SDL_Quit(); + net::Shutdown(); +#ifdef RPI + bcm_host_deinit(); +#endif + + exit(0); + return 0; +} diff --git a/ext/native/base/QtMain.cpp b/ext/native/base/QtMain.cpp new file mode 100644 index 0000000000..bcc23a514e --- /dev/null +++ b/ext/native/base/QtMain.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2012 Sacha Refshauge + * + */ +// Qt 4.7+ / 5.0+ implementation of the framework. +// Currently supports: Android, Symbian, Blackberry, Maemo/Meego, Linux, Windows, Mac OSX + +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) +#include +#ifdef QT_HAS_SYSTEMINFO +#include +#endif +#endif + +#ifdef __SYMBIAN32__ +#include +#include +#include "SymbianMediaKeys.h" +#endif +#ifdef SDL +#include "SDL/SDLJoystick.h" +#include "SDL_audio.h" +#endif +#include "QtMain.h" +#include "math/math_util.h" + +#include + +InputState* input_state; + +#ifdef SDL +extern void mixaudio(void *userdata, Uint8 *stream, int len) { + NativeMix((short *)stream, len / 4); +} +#endif + +std::string System_GetProperty(SystemProperty prop) { + switch (prop) { + case SYSPROP_NAME: +#ifdef __SYMBIAN32__ + return "Qt:Symbian"; +#elif defined(BLACKBERRY) + return "Qt:Blackberry"; +#elif defined(MAEMO) + return "Qt:Maemo"; +#elif defined(ANDROID) + return "Qt:Android"; +#elif defined(Q_OS_LINUX) + return "Qt:Linux"; +#elif defined(_WIN32) + return "Qt:Windows"; +#elif defined(Q_OS_MAC) + return "Qt:Mac"; +#else + return "Qt"; +#endif + case SYSPROP_LANGREGION: + return QLocale::system().name().toStdString(); + default: + return ""; + } +} + +int System_GetPropertyInt(SystemProperty prop) { + switch (prop) { + case SYSPROP_AUDIO_SAMPLE_RATE: + return 44100; + case SYSPROP_DISPLAY_REFRESH_RATE: + return 60000; + case SYSPROP_DEVICE_TYPE: +#ifdef __SYMBIAN32__ + return DEVICE_TYPE_MOBILE; +#elif defined(BLACKBERRY) + return DEVICE_TYPE_MOBILE; +#elif defined(MAEMO) + return DEVICE_TYPE_MOBILE; +#elif defined(ANDROID) + return DEVICE_TYPE_MOBILE; +#elif defined(Q_OS_LINUX) + return DEVICE_TYPE_DESKTOP; +#elif defined(_WIN32) + return DEVICE_TYPE_DESKTOP; +#elif defined(Q_OS_MAC) + return DEVICE_TYPE_DESKTOP; +#else + return DEVICE_TYPE_DESKTOP; +#endif + default: + return -1; + } +} + +void System_SendMessage(const char *command, const char *parameter) { + if (!strcmp(command, "finish")) { + qApp->exit(0); + } +} + +bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength) +{ + QString text = emugl->InputBoxGetQString(QString(title), QString(defaultValue)); + if (text.isEmpty()) + return false; + strcpy(outValue, text.toStdString().c_str()); + return true; +} + +void Vibrate(int length_ms) { + if (length_ms == -1 || length_ms == -3) + length_ms = 50; + else if (length_ms == -2) + length_ms = 25; + // Symbian only for now +#if defined(__SYMBIAN32__) + QFeedbackHapticsEffect effect; + effect.setIntensity(0.8); + effect.setDuration(length_ms); + effect.start(); +#endif +} + +void LaunchBrowser(const char *url) +{ + QDesktopServices::openUrl(QUrl(url)); +} + +float CalculateDPIScale() +{ + // Sane default rather than check DPI +#ifdef __SYMBIAN32__ + return 1.4f; +#elif defined(USING_GLES2) + return 1.2f; +#else + return 1.0f; +#endif +} + +static int mainInternal(QApplication &a) +{ +#ifdef MOBILE_DEVICE + emugl = new MainUI(); + emugl->resize(pixel_xres, pixel_yres); + emugl->showFullScreen(); +#endif + EnableFZ(); + // Disable screensaver +#ifdef __SYMBIAN32__ + QSystemScreenSaver ssObject(emugl); + ssObject.setScreenSaverInhibit(); + QScopedPointer mediakeys(new SymbianMediaKeys()); +#elif defined(QT_HAS_SYSTEMINFO) + QScreenSaver ssObject(emugl); + ssObject.setScreenSaverEnabled(false); +#endif + +#ifdef SDL + SDLJoystick joy(true); + joy.startEventLoop(); + SDL_Init(SDL_INIT_AUDIO); + SDL_AudioSpec fmt, ret_fmt; + memset(&fmt, 0, sizeof(fmt)); + fmt.freq = 44100; + fmt.format = AUDIO_S16; + fmt.channels = 2; + fmt.samples = 2048; + fmt.callback = &mixaudio; + fmt.userdata = (void *)0; + + if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) { + ELOG("Failed to open audio: %s", SDL_GetError()); + } else { + if (ret_fmt.samples != fmt.samples) // Notify, but still use it + ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples); + if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) { + ELOG("Sound buffer format does not match requested format."); + ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq); + ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format); + ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels); + ELOG("Provided output format does not match requirement, turning audio off"); + SDL_CloseAudio(); + } + } + SDL_PauseAudio(0); +#else + QScopedPointer audio(new MainAudio()); + audio->run(); +#endif + return a.exec(); +} + +#ifndef SDL +Q_DECL_EXPORT +#endif +int main(int argc, char *argv[]) +{ +#if defined(Q_OS_LINUX) && !defined(MAEMO) + QApplication::setAttribute(Qt::AA_X11InitThreads, true); +#endif + QApplication a(argc, argv); + QSize res = QApplication::desktop()->screenGeometry().size(); + if (res.width() < res.height()) + res.transpose(); + pixel_xres = res.width(); + pixel_yres = res.height(); + g_dpi_scale = CalculateDPIScale(); + dp_xres = (int)(pixel_xres * g_dpi_scale); dp_yres = (int)(pixel_yres * g_dpi_scale); + net::Init(); + std::string savegame_dir = "."; + std::string assets_dir = "."; +#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) + savegame_dir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString(); + assets_dir = QStandardPaths::writableLocation(QStandardPaths::DataLocation).toStdString(); +#elif defined(__SYMBIAN32__) + savegame_dir = "E:/PPSSPP"; + assets_dir = "E:/PPSSPP"; +#elif defined(BLACKBERRY) + savegame_dir = "/accounts/1000/shared/misc"; + assets_dir = "app/native/assets"; +#elif defined(MAEMO) + savegame_dir = "/home/user/MyDocs/PPSSPP"; + assets_dir = "/opt/PPSSPP"; +#endif + savegame_dir += "/"; + assets_dir += "/"; + + bool fullscreenCLI=false; + for (int i = 1; i < argc; i++) + { + if (!strcmp(argv[i],"--fullscreen")) + fullscreenCLI=true; + } + NativeInit(argc, (const char **)argv, savegame_dir.c_str(), assets_dir.c_str(), "BADCOFFEE",fullscreenCLI); + + int ret = mainInternal(a); + +#ifndef MOBILE_DEVICE + exit(0); +#endif + NativeShutdownGraphics(); +#ifdef SDL + SDL_PauseAudio(1); + SDL_CloseAudio(); +#endif + NativeShutdown(); + net::Shutdown(); + return ret; +} + diff --git a/ext/native/base/QtMain.h b/ext/native/base/QtMain.h new file mode 100644 index 0000000000..cf56875f65 --- /dev/null +++ b/ext/native/base/QtMain.h @@ -0,0 +1,296 @@ +#ifndef QTMAIN_H +#define QTMAIN_H + +#include +#include +#include +#include "gfx_es2/glsl_program.h" +#include + +#ifndef SDL +#include +#include +#endif +#if defined(MOBILE_DEVICE) && !defined(MAEMO) +#include +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +QTM_USE_NAMESPACE +#endif +#endif + +#include "base/display.h" +#include "base/logging.h" +#include "base/timeutil.h" +#include "file/zip_read.h" +#include "gfx/gl_common.h" +#include "input/input_state.h" +#include "input/keycodes.h" +#include "base/NativeApp.h" +#include "net/resolve.h" +#include "base/NKCodeFromQt.h" + +// Bad: PPSSPP includes from native +#include "Core/System.h" +#include "Core/Core.h" +#include "Core/Config.h" + +// Input +void SimulateGamepad(InputState *input); + +//GUI +class MainUI : public QGLWidget +{ + Q_OBJECT +public: + explicit MainUI(QWidget *parent = 0): + QGLWidget(parent) + { + setAttribute(Qt::WA_AcceptTouchEvents); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + setAttribute(Qt::WA_LockLandscapeOrientation); +#endif +#if defined(MOBILE_DEVICE) && !defined(MAEMO) + acc = new QAccelerometer(this); + acc->start(); +#endif + setFocus(); + setFocusPolicy(Qt::StrongFocus); + startTimer(16); + } + ~MainUI() { +#if defined(MOBILE_DEVICE) && !defined(MAEMO) + delete acc; +#endif + NativeShutdownGraphics(); + } + +public slots: + QString InputBoxGetQString(QString title, QString defaultValue) { + bool ok; + QString text = QInputDialog::getText(this, title, title, QLineEdit::Normal, defaultValue, &ok); + if (!ok) + text = QString(); + return text; + } + +signals: + void doubleClick(); + void newFrame(); + +protected: + void resizeEvent(QResizeEvent * e) + { + UpdateScreenScale(e->size().width(), e->size().height(), false); + PSP_CoreParameter().pixelWidth = pixel_xres; + PSP_CoreParameter().pixelHeight = pixel_yres; + } + + void timerEvent(QTimerEvent *) { + updateGL(); + emit newFrame(); + } + void changeEvent(QEvent *e) + { + QGLWidget::changeEvent(e); + if(e->type() == QEvent::WindowStateChange) + Core_NotifyWindowHidden(isMinimized()); + } + bool event(QEvent *e) + { + TouchInput input; + QList touchPoints; + switch(e->type()) + { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + touchPoints = static_cast(e)->touchPoints(); + foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) { + switch (touchPoint.state()) { + case Qt::TouchPointStationary: + break; + case Qt::TouchPointPressed: + case Qt::TouchPointReleased: + input_state.pointer_down[touchPoint.id()] = (touchPoint.state() == Qt::TouchPointPressed); + input_state.pointer_x[touchPoint.id()] = touchPoint.pos().x() * g_dpi_scale; + input_state.pointer_y[touchPoint.id()] = touchPoint.pos().y() * g_dpi_scale; + + input.x = touchPoint.pos().x() * g_dpi_scale; + input.y = touchPoint.pos().y() * g_dpi_scale; + input.flags = (touchPoint.state() == Qt::TouchPointPressed) ? TOUCH_DOWN : TOUCH_UP; + input.id = touchPoint.id(); + NativeTouch(input); + break; + case Qt::TouchPointMoved: + input_state.pointer_x[touchPoint.id()] = touchPoint.pos().x() * g_dpi_scale; + input_state.pointer_y[touchPoint.id()] = touchPoint.pos().y() * g_dpi_scale; + + input.x = touchPoint.pos().x() * g_dpi_scale; + input.y = touchPoint.pos().y() * g_dpi_scale; + input.flags = TOUCH_MOVE; + input.id = touchPoint.id(); + NativeTouch(input); + break; + default: + break; + } + } + break; + case QEvent::MouseButtonDblClick: + if (!g_Config.bShowTouchControls || GetUIState() != UISTATE_INGAME) + emit doubleClick(); + break; + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + input_state.pointer_down[0] = (e->type() == QEvent::MouseButtonPress); + input_state.pointer_x[0] = ((QMouseEvent*)e)->pos().x() * g_dpi_scale; + input_state.pointer_y[0] = ((QMouseEvent*)e)->pos().y() * g_dpi_scale; + + input.x = ((QMouseEvent*)e)->pos().x() * g_dpi_scale; + input.y = ((QMouseEvent*)e)->pos().y() * g_dpi_scale; + input.flags = (e->type() == QEvent::MouseButtonPress) ? TOUCH_DOWN : TOUCH_UP; + input.id = 0; + NativeTouch(input); + break; + case QEvent::MouseMove: + input_state.pointer_x[0] = ((QMouseEvent*)e)->pos().x() * g_dpi_scale; + input_state.pointer_y[0] = ((QMouseEvent*)e)->pos().y() * g_dpi_scale; + + input.x = ((QMouseEvent*)e)->pos().x() * g_dpi_scale; + input.y = ((QMouseEvent*)e)->pos().y() * g_dpi_scale; + input.flags = TOUCH_MOVE; + input.id = 0; + NativeTouch(input); + break; + case QEvent::Wheel: + NativeKey(KeyInput(DEVICE_ID_MOUSE, ((QWheelEvent*)e)->delta()<0 ? NKCODE_EXT_MOUSEWHEEL_DOWN : NKCODE_EXT_MOUSEWHEEL_UP, KEY_DOWN)); + break; + case QEvent::KeyPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawQttoNative.find(((QKeyEvent*)e)->key())->second, KEY_DOWN)); + break; + case QEvent::KeyRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawQttoNative.find(((QKeyEvent*)e)->key())->second, KEY_UP)); + break; + default: + return QWidget::event(e); + } + e->accept(); + return true; + } + + void initializeGL() + { +#ifndef USING_GLES2 + glewInit(); +#endif + NativeInitGraphics(); + } + + void paintGL() + { + updateAccelerometer(); + UpdateInputState(&input_state); + time_update(); + UpdateRunLoop(); + } + + void updateAccelerometer() + { +#if defined(MOBILE_DEVICE) && !defined(MAEMO) + // TODO: Toggle it depending on whether it is enabled + QAccelerometerReading *reading = acc->reading(); + if (reading) { + input_state.acc.x = reading->x(); + input_state.acc.y = reading->y(); + input_state.acc.z = reading->z(); + AxisInput axis; + axis.deviceId = DEVICE_ID_ACCELEROMETER; + axis.flags = 0; + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X; + axis.value = input_state.acc.x; + NativeAxis(axis); + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y; + axis.value = input_state.acc.y; + NativeAxis(axis); + + axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z; + axis.value = input_state.acc.z; + NativeAxis(axis); + } +#endif + } + +private: + InputState input_state; +#if defined(MOBILE_DEVICE) && !defined(MAEMO) + QAccelerometer* acc; +#endif +}; + +static MainUI* emugl = NULL; + +#ifndef SDL + +// Audio +#define AUDIO_FREQ 44100 +#define AUDIO_CHANNELS 2 +#define AUDIO_SAMPLES 2048 +#define AUDIO_SAMPLESIZE 16 +#define AUDIO_BUFFERS 5 +class MainAudio: public QObject +{ + Q_OBJECT +public: + MainAudio() { + } + ~MainAudio() { + if (feed != NULL) { + killTimer(timer); + feed->close(); + } + if (output) { + output->stop(); + delete output; + } + if (mixbuf) + free(mixbuf); + } +public slots: + void run() { + QAudioFormat fmt; + fmt.setSampleRate(AUDIO_FREQ); + fmt.setCodec("audio/pcm"); + fmt.setChannelCount(AUDIO_CHANNELS); + fmt.setSampleSize(AUDIO_SAMPLESIZE); + fmt.setByteOrder(QAudioFormat::LittleEndian); + fmt.setSampleType(QAudioFormat::SignedInt); + mixlen = sizeof(short)*AUDIO_BUFFERS*AUDIO_CHANNELS*AUDIO_SAMPLES; + mixbuf = (char*)malloc(mixlen); + output = new QAudioOutput(fmt); + output->setBufferSize(mixlen); + feed = output->start(); + if (feed != NULL) + timer = startTimer((1000*AUDIO_SAMPLES) / AUDIO_FREQ); + } + +protected: + void timerEvent(QTimerEvent *) { + memset(mixbuf, 0, mixlen); + size_t frames = NativeMix((short *)mixbuf, AUDIO_BUFFERS*AUDIO_SAMPLES); + if (frames > 0) + feed->write(mixbuf, sizeof(short) * AUDIO_CHANNELS * frames); + } +private: + QIODevice* feed; + QAudioOutput* output; + int mixlen; + char* mixbuf; + int timer; +}; + +#endif //SDL + +#endif + diff --git a/ext/native/base/SymbianMediaKeys.cpp b/ext/native/base/SymbianMediaKeys.cpp new file mode 100644 index 0000000000..8cb132c49f --- /dev/null +++ b/ext/native/base/SymbianMediaKeys.cpp @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2013 Antti Pohjola + * + */ +//Adds mediakey support for Symbian (volume up/down) + +#include +#include "SymbianMediaKeys.h" +#include "input/keycodes.h" +#include "input/input_state.h" +#include "base/NativeApp.h" + +#define KTimeOut 80 + +SymbianMediaKeys::SymbianMediaKeys() + : CActive ( EPriorityNormal ){ + CActiveScheduler::Add( this ); + iInterfaceSelector = CRemConInterfaceSelector::NewL(); + iRemConCore = CRemConCoreApiTarget::NewL(*iInterfaceSelector, *this); + iInterfaceSelector->OpenTargetL(); + + playtimer = new QTimer(this); + connect(playtimer, SIGNAL(timeout()), this, SLOT(playtimerexpired())); + stoptimer = new QTimer(this); + connect(stoptimer, SIGNAL(timeout()), this, SLOT(stoptimerexpired())); + forwardtimer = new QTimer(this); + connect(forwardtimer, SIGNAL(timeout()), this, SLOT(forwardtimerexpired())); + backwardtimer = new QTimer(this); + connect(backwardtimer, SIGNAL(timeout()), this, SLOT(backwardtimerexpired())); + voluptimer = new QTimer(this); + connect(voluptimer, SIGNAL(timeout()), this, SLOT(voluptimerexpired())); + voldowntimer = new QTimer(this); + connect(voldowntimer, SIGNAL(timeout()), this, SLOT(voldowntimerexpired())); +} + +SymbianMediaKeys::~SymbianMediaKeys(){ + delete iInterfaceSelector; + iRemConCore = NULL; //owned by interfaceselector + Cancel(); + iResponseQ.Reset(); + iResponseQ.Close(); +} + +void SymbianMediaKeys::subscribeKeyEvent(QObject* aObject ){ + receiver = aObject; +} + +/* + * it seems that it takes about 600ms to get an update after buttonpress + * */ +void SymbianMediaKeys::MrccatoCommand(TRemConCoreApiOperationId aOperationId,TRemConCoreApiButtonAction aButtonAct){ + TRequestStatus status; + switch( aOperationId ){ + case ERemConCoreApiPausePlayFunction: + { + switch (aButtonAct){ + case ERemConCoreApiButtonPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PLAY_PAUSE, KEY_DOWN)); + break; + case ERemConCoreApiButtonRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PLAY_PAUSE, KEY_UP)); + break; + case ERemConCoreApiButtonClick: + playtimer->start(KTimeOut); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PLAY_PAUSE, KEY_DOWN)); + break; + default: + // Play/Pause unknown action + break; + } + break; + } + + case ERemConCoreApiStop: + { + switch (aButtonAct){ + case ERemConCoreApiButtonPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_STOP, KEY_DOWN)); + break; + case ERemConCoreApiButtonRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_STOP, KEY_UP)); + break; + case ERemConCoreApiButtonClick: + stoptimer->start(KTimeOut); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_STOP, KEY_DOWN)); + break; + default: + break; + } + break; + } + case ERemConCoreApiRewind: + { + switch (aButtonAct){ + case ERemConCoreApiButtonPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_DOWN)); + break; + case ERemConCoreApiButtonRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_UP)); + break; + case ERemConCoreApiButtonClick: + backwardtimer->start(KTimeOut); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_DOWN)); + default: + break; + } + break; + } + case ERemConCoreApiFastForward: + { + switch (aButtonAct){ + case ERemConCoreApiButtonPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_DOWN)); + break; + case ERemConCoreApiButtonRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_UP)); + break; + case ERemConCoreApiButtonClick: + forwardtimer->start(KTimeOut); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_DOWN)); + default: + break; + } + break; + } + case ERemConCoreApiVolumeUp: + { + switch (aButtonAct){ + case ERemConCoreApiButtonPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_UP, KEY_DOWN)); + break; + case ERemConCoreApiButtonRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_UP, KEY_UP)); + break; + case ERemConCoreApiButtonClick: + voluptimer->start(KTimeOut); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_UP, KEY_DOWN)); + default: + break; + } + break; + } + case ERemConCoreApiVolumeDown: + { + switch (aButtonAct){ + case ERemConCoreApiButtonPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_DOWN, KEY_DOWN)); + break; + case ERemConCoreApiButtonRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_DOWN, KEY_UP)); + break; + case ERemConCoreApiButtonClick: + voldowntimer->start(KTimeOut); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_DOWN, KEY_DOWN)); + default: + break; + } + break; + } + case ERemConCoreApiBackward: + { + switch (aButtonAct) + { + case ERemConCoreApiButtonPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_DOWN)); + break; + case ERemConCoreApiButtonRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_UP)); + break; + case ERemConCoreApiButtonClick: + backwardtimer->start(KTimeOut); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_DOWN)); + default: + break; + } + break; + } + case ERemConCoreApiForward: + { + switch (aButtonAct) + { + case ERemConCoreApiButtonPress: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_DOWN)); + break; + case ERemConCoreApiButtonRelease: + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_UP)); + break; + case ERemConCoreApiButtonClick: + forwardtimer->start(KTimeOut); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_DOWN)); + default: + break; + } + break; + } + + default: + break; + } + //complete key event + CompleteMediaKeyEvent( aOperationId ); +} + +void SymbianMediaKeys::MrccatoPlay(TRemConCoreApiPlaybackSpeed aSpeed,TRemConCoreApiButtonAction aButtonAct){ + +} + +void SymbianMediaKeys::MrccatoTuneFunction(TBool aTwoPart, TUint aMajorChannel,TUint aMinorChannel,TRemConCoreApiButtonAction aButtonAct){ + +} + +void SymbianMediaKeys::MrccatoSelectDiskFunction(TUint aDisk, TRemConCoreApiButtonAction aButtonAct){ + +} + +void SymbianMediaKeys::MrccatoSelectAvInputFunction(TUint8 aAvInputSignalNumber,TRemConCoreApiButtonAction aButtonAct){ + +} + +void SymbianMediaKeys::MrccatoSelectAudioInputFunction(TUint8 aAudioInputSignalNumber,TRemConCoreApiButtonAction aButtonAct){ + +} + +void SymbianMediaKeys::CompleteMediaKeyEvent( TRemConCoreApiOperationId aOperationId ){ + if( !IsActive() ){ + switch ( aOperationId ) + { + case ERemConCoreApiVolumeUp: + { + iRemConCore->VolumeUpResponse( iStatus, KErrNone ); + SetActive(); + break; + } + + case ERemConCoreApiVolumeDown: + { + iRemConCore->VolumeDownResponse( iStatus, KErrNone ); + SetActive(); + break; + } + case ERemConCoreApiPlay: + { + iRemConCore-> PlayResponse(iStatus, KErrNone); + SetActive(); + break; + } + case ERemConCoreApiStop: + { + iRemConCore->StopResponse(iStatus, KErrNone); + SetActive(); + break; + } + case ERemConCoreApiPause: + { + iRemConCore->PauseResponse(iStatus, KErrNone); + SetActive(); + break; + } + case ERemConCoreApiRewind: + { + iRemConCore->RewindResponse(iStatus, KErrNone); + SetActive(); + break; + } + case ERemConCoreApiFastForward: + { + iRemConCore->FastForwardResponse(iStatus, KErrNone); + SetActive(); + break; + } + case ERemConCoreApiForward: + { + iRemConCore->ForwardResponse( iStatus, KErrNone ); + SetActive(); + break; + } + case ERemConCoreApiBackward: + { + iRemConCore->BackwardResponse(iStatus, KErrNone ); + SetActive(); + break; + } + default: + break; + } + } + else{ + //active, append to queue + iResponseQ.Append( aOperationId ); + } +} + +void SymbianMediaKeys::RunL(){ + if ( iResponseQ.Count() ){ + CompleteMediaKeyEvent( iResponseQ[0] ); + //remove old response from que + iResponseQ.Remove(0); + iResponseQ.Compress(); + } +} + +void SymbianMediaKeys::DoCancel(){ +} + +void SymbianMediaKeys::playtimerexpired(){ + playtimer->stop(); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PLAY_PAUSE, KEY_UP)); +} + +void SymbianMediaKeys::stoptimerexpired(){ + stoptimer->stop(); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_STOP, KEY_UP)); +} + +void SymbianMediaKeys::forwardtimerexpired(){ + forwardtimer->stop(); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_UP)); +} + +void SymbianMediaKeys::backwardtimerexpired(){ + backwardtimer->stop(); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_UP)); +} + +void SymbianMediaKeys::voluptimerexpired(){ + voluptimer->stop(); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_UP, KEY_UP)); +} + +void SymbianMediaKeys::voldowntimerexpired(){ + voldowntimer->stop(); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_DOWN, KEY_UP)); +} diff --git a/ext/native/base/SymbianMediaKeys.h b/ext/native/base/SymbianMediaKeys.h new file mode 100644 index 0000000000..415d00ac8c --- /dev/null +++ b/ext/native/base/SymbianMediaKeys.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013 Antti Pohjola + * + */ +//Adds mediakey support for Symbian (volume up/down) + +#ifndef SYMBIANMEDIAKEYS_H_ +#define SYMBIANMEDIAKEYS_H_ + +#include +#include +#include + +#include // link against RemConCoreApi.lib +#include // and +#include // RemConInterfaceBase.lib + +class SymbianMediaKeys: public QObject, public CActive, public MRemConCoreApiTargetObserver +{ + Q_OBJECT +public: + SymbianMediaKeys(); + virtual ~SymbianMediaKeys(); + +public: + void subscribeKeyEvent(QObject* aObject ); + +public: //From MRemConCoreApiTargetObserver + void MrccatoCommand(TRemConCoreApiOperationId aOperationId,TRemConCoreApiButtonAction aButtonAct); + + void MrccatoPlay(TRemConCoreApiPlaybackSpeed aSpeed,TRemConCoreApiButtonAction aButtonAct); + + void MrccatoTuneFunction(TBool aTwoPart,TUint aMajorChannel,TUint aMinorChannel,TRemConCoreApiButtonAction aButtonAct); + + void MrccatoSelectDiskFunction(TUint aDisk,TRemConCoreApiButtonAction aButtonAct); + + void MrccatoSelectAvInputFunction(TUint8 aAvInputSignalNumber,TRemConCoreApiButtonAction aButtonAct); + + void MrccatoSelectAudioInputFunction(TUint8 aAudioInputSignalNumber,TRemConCoreApiButtonAction aButtonAct); + +private: + void CompleteMediaKeyEvent( TRemConCoreApiOperationId aOperationId ); + void RunL(); + void DoCancel(); + +public slots: + void playtimerexpired(); + void stoptimerexpired(); + void forwardtimerexpired(); + void backwardtimerexpired(); + void voluptimerexpired(); + void voldowntimerexpired(); +private: + + RArray iResponseQ; //response queue + + CRemConCoreApiTarget* iRemConCore; //the controller + CRemConInterfaceSelector* iInterfaceSelector; + + QObject* receiver; + + QTimer* playtimer; + QTimer* stoptimer; + QTimer* forwardtimer; + QTimer* backwardtimer; + QTimer* voluptimer; + QTimer* voldowntimer; +}; + +#endif /* SYMBIANMEDIAKEYS_H_ */ diff --git a/ext/native/base/arch.h b/ext/native/base/arch.h new file mode 100644 index 0000000000..3bdce74e55 --- /dev/null +++ b/ext/native/base/arch.h @@ -0,0 +1,17 @@ +#pragma once + +// This provides MSVC's arch-detection defines on other platforms as well. + +#ifndef _WIN32 + +#if defined(__x86_64__) && !defined(_M_X64) +#define _M_X64 1 +#endif + +#if defined(__x86__) && !defined(_M_IX86) +#define _M_IX86 1 +#endif + +// TODO: ARM, ARM64 + +#endif diff --git a/ext/native/base/backtrace.cpp b/ext/native/base/backtrace.cpp new file mode 100644 index 0000000000..6c22f209ff --- /dev/null +++ b/ext/native/base/backtrace.cpp @@ -0,0 +1,22 @@ +#include "base/backtrace.h" + +#if defined(__GLIBC__) && !defined(__UCLIBC__) +#include +#include + +static void *backtrace_buffer[128]; + +void PrintBacktraceToStderr() { + int num_addrs = backtrace(backtrace_buffer, 128); + backtrace_symbols_fd(backtrace_buffer, num_addrs, STDERR_FILENO); +} + +#else + +#include + +void PrintBacktraceToStderr() { + fprintf(stderr, "No backtrace available to print on this platform\n"); +} + +#endif diff --git a/ext/native/base/backtrace.h b/ext/native/base/backtrace.h new file mode 100644 index 0000000000..4ff0917f30 --- /dev/null +++ b/ext/native/base/backtrace.h @@ -0,0 +1,3 @@ +#pragma once + +void PrintBacktraceToStderr(); diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h new file mode 100644 index 0000000000..c7cb845a99 --- /dev/null +++ b/ext/native/base/basictypes.h @@ -0,0 +1,95 @@ +#pragma once + +#include +#include // for byte swapping + +#ifdef _WIN32 +#pragma warning(disable:4244) +#pragma warning(disable:4996) +#pragma warning(disable:4305) // truncation from double to float +#endif + +#define DISALLOW_COPY_AND_ASSIGN(t) \ +private: \ + t(const t &other); \ + void operator =(const t &other); + +#ifdef _WIN32 + +typedef intptr_t ssize_t; + +#include + +#define ALIGNED16(x) __declspec(align(16)) x +#define ALIGNED32(x) __declspec(align(32)) x +#define ALIGNED64(x) __declspec(align(64)) x +#define ALIGNED16_DECL(x) __declspec(align(16)) x +#define ALIGNED64_DECL(x) __declspec(align(64)) x + +#else + +#define ALIGNED16(x) __attribute__((aligned(16))) x +#define ALIGNED32(x) __attribute__((aligned(32))) x +#define ALIGNED64(x) __attribute__((aligned(64))) x +#define ALIGNED16_DECL(x) __attribute__((aligned(16))) x +#define ALIGNED64_DECL(x) __attribute__((aligned(64))) x + +#endif // _WIN32 + +// Byteswapping +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +#endif + +inline uint8_t swap8(uint8_t _data) {return _data;} + +// Just in case this has been defined by platform +#undef swap16 +#undef swap32 +#undef swap64 + +#ifdef _WIN32 +inline uint16_t swap16(uint16_t _data) {return _byteswap_ushort(_data);} +inline uint32_t swap32(uint32_t _data) {return _byteswap_ulong (_data);} +inline uint64_t swap64(uint64_t _data) {return _byteswap_uint64(_data);} +#elif defined(ARM) +inline uint16_t swap16 (uint16_t _data) { uint32_t data = _data; __asm__ ("rev16 %0, %1\n" : "=l" (data) : "l" (data)); return (uint16_t)data;} +inline uint32_t swap32 (uint32_t _data) {__asm__ ("rev %0, %1\n" : "=l" (_data) : "l" (_data)); return _data;} +inline uint64_t swap64(uint64_t _data) {return ((uint64_t)swap32(_data) << 32) | swap32(_data >> 32);} +#elif __linux__ && !defined(ANDROID) +#include +inline uint16_t swap16(uint16_t _data) {return bswap_16(_data);} +inline uint32_t swap32(uint32_t _data) {return bswap_32(_data);} +inline uint64_t swap64(uint64_t _data) {return bswap_64(_data);} +#elif defined(__DragonFly__) || defined(__FreeBSD__) +#include +inline uint16_t swap16(uint16_t _data) {return bswap16(_data);} +inline uint32_t swap32(uint32_t _data) {return bswap32(_data);} +inline uint64_t swap64(uint64_t _data) {return bswap64(_data);} +#elif defined(__GNUC__) +inline uint16_t swap16(uint16_t _data) {return (_data >> 8) | (_data << 8);} +inline uint32_t swap32(uint32_t _data) {return __builtin_bswap32(_data);} +inline uint64_t swap64(uint64_t _data) {return __builtin_bswap64(_data);} +#else +// Slow generic implementation. Hopefully this never hits +inline uint16_t swap16(uint16_t data) {return (data >> 8) | (data << 8);} +inline uint32_t swap32(uint32_t data) {return (swap16(data) << 16) | swap16(data >> 16);} +inline uint64_t swap64(uint64_t data) {return ((uint64_t)swap32(data) << 32) | swap32(data >> 32);} +#endif + +inline uint16_t swap16(const uint8_t* _pData) {return swap16(*(const uint16_t*)_pData);} +inline uint32_t swap32(const uint8_t* _pData) {return swap32(*(const uint32_t*)_pData);} +inline uint64_t swap64(const uint8_t* _pData) {return swap64(*(const uint64_t*)_pData);} + +// Thread local storage +#ifdef _WIN32 +#define __THREAD __declspec( thread ) +#else +#define __THREAD __thread +#endif + +// For really basic windows code compat +#ifndef _TCHAR_DEFINED +typedef char TCHAR; +#endif + diff --git a/ext/native/base/buffer.cpp b/ext/native/base/buffer.cpp new file mode 100644 index 0000000000..da87602a02 --- /dev/null +++ b/ext/native/base/buffer.cpp @@ -0,0 +1,234 @@ +#include "base/buffer.h" + +#include +#include +#include + +#ifdef _WIN32 +#include +#undef min +#undef max +#else +#include +#include +#endif + +#include "base/logging.h" +#include "base/timeutil.h" +#include "file/fd_util.h" + +Buffer::Buffer() { } +Buffer::~Buffer() { } + +char *Buffer::Append(ssize_t length) { + size_t old_size = data_.size(); + data_.resize(old_size + length); + return &data_[0] + old_size; +} + +void Buffer::Append(const std::string &str) { + char *ptr = Append(str.size()); + memcpy(ptr, str.data(), str.size()); +} + +void Buffer::Append(const char *str) { + size_t len = strlen(str); + char *dest = Append(len); + memcpy(dest, str, len); +} + +void Buffer::Append(const Buffer &other) { + size_t len = other.size(); + char *dest = Append(len); + memcpy(dest, &other.data_[0], len); +} + +void Buffer::AppendValue(int value) { + char buf[16]; + // This is slow. + sprintf(buf, "%i", value); + Append(buf); +} + +void Buffer::Take(size_t length, std::string *dest) { + if (length > data_.size()) { + ELOG("Truncating length in Buffer::Take()"); + length = data_.size(); + } + dest->resize(length); + if (length > 0) { + Take(length, &(*dest)[0]); + } +} + +void Buffer::Take(size_t length, char *dest) { + memcpy(dest, &data_[0], length); + data_.erase(data_.begin(), data_.begin() + length); +} + +int Buffer::TakeLineCRLF(std::string *dest) { + int after_next_line = OffsetToAfterNextCRLF(); + if (after_next_line < 0) + return after_next_line; + else { + Take(after_next_line - 2, dest); + Skip(2); // Skip the CRLF + return after_next_line - 2; + } +} + +void Buffer::Skip(size_t length) { + if (length > data_.size()) { + ELOG("Truncating length in Buffer::Skip()"); + length = data_.size(); + } + data_.erase(data_.begin(), data_.begin() + length); +} + +int Buffer::SkipLineCRLF() { + int after_next_line = OffsetToAfterNextCRLF(); + if (after_next_line < 0) + return after_next_line; + else { + Skip(after_next_line); + return after_next_line - 2; + } +} + +int Buffer::OffsetToAfterNextCRLF() { + for (int i = 0; i < (int)data_.size() - 1; i++) { + if (data_[i] == '\r' && data_[i + 1] == '\n') { + return i + 2; + } + } + return -1; +} + +void Buffer::Printf(const char *fmt, ...) { + char buffer[2048]; + va_list vl; + va_start(vl, fmt); + ssize_t retval = vsnprintf(buffer, sizeof(buffer), fmt, vl); + if (retval >= (ssize_t)sizeof(buffer)) { + // Output was truncated. TODO: Do something. + ELOG("Buffer::Printf truncated output"); + } + if (retval < 0) { + ELOG("Buffer::Printf failed"); + } + va_end(vl); + char *ptr = Append(retval); + memcpy(ptr, buffer, retval); +} + +bool Buffer::Flush(int fd) { + // Look into using send() directly. + bool success = (ssize_t)data_.size() == fd_util::WriteLine(fd, &data_[0], data_.size()); + if (success) { + data_.resize(0); + } + return success; +} + +bool Buffer::FlushToFile(const char *filename) { + FILE *f = fopen(filename, "wb"); + if (!f) + return false; + if (data_.size()) { + fwrite(&data_[0], 1, data_.size(), f); + } + fclose(f); + return true; +} + +bool Buffer::FlushSocket(uintptr_t sock) { + for (size_t pos = 0, end = data_.size(); pos < end; ) { + int sent = send(sock, &data_[pos], (int)(end - pos), 0); + if (sent < 0) { + ELOG("FlushSocket failed"); + return false; + } + pos += sent; + + // Buffer full, don't spin. + if (sent == 0) { + sleep_ms(1); + } + } + data_.resize(0); + return true; +} + +bool Buffer::ReadAll(int fd, int hintSize) { + std::vector buf; + if (hintSize >= 65536 * 16) { + buf.resize(65536); + } else if (hintSize >= 1024 * 16) { + buf.resize(hintSize / 16); + } else { + buf.resize(1024); + } + + while (true) { + int retval = recv(fd, &buf[0], (int)buf.size(), 0); + if (retval == 0) { + break; + } else if (retval < 0) { + ELOG("Error reading from buffer: %i", retval); + return false; + } + char *p = Append((size_t)retval); + memcpy(p, &buf[0], retval); + } + return true; +} + +bool Buffer::ReadAllWithProgress(int fd, int knownSize, float *progress) { + std::vector buf; + if (knownSize >= 65536 * 16) { + buf.resize(65536); + } else if (knownSize >= 1024 * 16) { + buf.resize(knownSize / 16); + } else { + buf.resize(1024); + } + + int total = 0; + while (true) { + int retval = recv(fd, &buf[0], (int)buf.size(), 0); + if (retval == 0) { + return true; + } else if (retval < 0) { + ELOG("Error reading from buffer: %i", retval); + return false; + } + char *p = Append((size_t)retval); + memcpy(p, &buf[0], retval); + total += retval; + *progress = (float)total / (float)knownSize; + } + return true; +} + +int Buffer::Read(int fd, size_t sz) { + char buf[1024]; + int retval; + size_t received = 0; + while ((retval = recv(fd, buf, (int)std::min(sz, sizeof(buf)), 0)) > 0) { + if (retval < 0) { + return retval; + } + char *p = Append((size_t)retval); + memcpy(p, buf, retval); + sz -= retval; + received += retval; + if (sz == 0) + return 0; + } + return (int)received; +} + +void Buffer::PeekAll(std::string *dest) { + dest->resize(data_.size()); + memcpy(&(*dest)[0], &data_[0], data_.size()); +} diff --git a/ext/native/base/buffer.h b/ext/native/base/buffer.h new file mode 100644 index 0000000000..d98ca94c9f --- /dev/null +++ b/ext/native/base/buffer.h @@ -0,0 +1,88 @@ +#ifndef _IO_BUFFER_H +#define _IO_BUFFER_H + +#include +#include + +#include "base/basictypes.h" +#include "base/logging.h" + +// Acts as a queue. Intended to be as fast as possible for most uses. +// Does not do synchronization, must use external mutexes. +class Buffer { + public: + Buffer(); + ~Buffer(); + + // Write max [length] bytes to the returned pointer. + // Any other operation on this Buffer invalidates the pointer. + char *Append(ssize_t length); + char *Append(size_t length) { return Append((ssize_t)length); } + + // These work pretty much like you'd expect. + void Append(const char *str); // str null-terminated. The null is not copied. + void Append(const std::string &str); + void Append(const Buffer &other); + + // Various types. Useful for varz etc. Appends a string representation of the + // value, rather than a binary representation. + void AppendValue(int value); + + // Parsing Helpers + + // Use for easy line skipping. If no CRLF within the buffer, returns -1. + // If parsing HTML headers, this indicates that you should probably buffer up + // more data. + int OffsetToAfterNextCRLF(); + + // Takers + + void Take(size_t length, std::string *dest); + void Take(size_t length, char *dest); + void TakeAll(std::string *dest) { Take(size(), dest); } + // On failure, return value < 0 and *dest is unchanged. + // Strips off the actual CRLF from the result. + int TakeLineCRLF(std::string *dest); + + // Skippers + void Skip(size_t length); + // Returns -1 on failure (no CRLF within sight). + // Otherwise returns the length of the line skipped, not including CRLF. Can be 0. + int SkipLineCRLF(); + + // Utility functions. + void Printf(const char *fmt, ...); + + // Dumps the entire buffer to the string, but keeps it around. + // Only to be used for debugging, since it might not be fast at all. + void PeekAll(std::string *dest); + + // Simple I/O. + + // Writes the entire buffer to the file descriptor. Also resets the + // size to zero. On failure, data remains in buffer and nothing is + // written. + bool Flush(int fd); + bool FlushToFile(const char *filename); + bool FlushSocket(uintptr_t sock); // Windows portability + + bool ReadAll(int fd, int hintSize = 0); + bool ReadAllWithProgress(int fd, int knownSize, float *progress); + + // < 0: error + // >= 0: number of bytes read + int Read(int fd, size_t sz); + + // Utilities. Try to avoid checking for size. + size_t size() const { return data_.size(); } + bool empty() const { return size() == 0; } + void clear() { data_.resize(0); } + + private: + // TODO: Find a better internal representation, like a cord. + std::vector data_; + + DISALLOW_COPY_AND_ASSIGN(Buffer); +}; + +#endif // _IO_BUFFER_H diff --git a/ext/native/base/color.h b/ext/native/base/color.h new file mode 100644 index 0000000000..5a382bc15a --- /dev/null +++ b/ext/native/base/color.h @@ -0,0 +1,16 @@ +#pragma once + +typedef unsigned int Color; + +//have to use a define to ensure constant folding.. with an inline I don't get that, sucks +#define COLOR(i) (((i&0xFF) << 16) | (i & 0xFF00) | ((i & 0xFF0000) >> 16) | 0xFF000000) +inline Color darkenColor(Color color) { + return (color & 0xFF000000) | ((color >> 1)&0x7F7F7F); +} +inline Color whitenColor(Color color) { + return ((color & 0xFF000000) | ((color >> 1)&0x7F7F7F)) + 0x7F7F7F; +} +inline Color colorInterpol(Color x, Color y, int n) { + // TODO + return x; +} diff --git a/ext/native/base/colorutil.cpp b/ext/native/base/colorutil.cpp new file mode 100644 index 0000000000..ec9766296e --- /dev/null +++ b/ext/native/base/colorutil.cpp @@ -0,0 +1,101 @@ +#include "base/colorutil.h" + +uint32_t whiteAlpha(float alpha) { + if (alpha < 0.0f) alpha = 0.0f; + if (alpha > 1.0f) alpha = 1.0f; + uint32_t color = (int)(alpha*255) << 24; + color |= 0xFFFFFF; + return color; +} + +uint32_t blackAlpha(float alpha) { + if (alpha < 0.0f) alpha = 0.0f; + if (alpha > 1.0f) alpha = 1.0f; + return (int)(alpha*255)<<24; +} + +uint32_t colorAlpha(uint32_t rgb, float alpha) { + if (alpha < 0.0f) alpha = 0.0f; + if (alpha > 1.0f) alpha = 1.0f; + return ((int)(alpha*255)<<24) | (rgb & 0xFFFFFF); +} + +uint32_t alphaMul(uint32_t color, float alphaMul) { + uint32_t rgb = color & 0xFFFFFF; + uint32_t alpha = color >> 24; + alpha *= alphaMul; + if (alpha < 0.0f) alpha = 0.0f; + if (alpha > 255.0f) alpha = 255.0f; + return ((int)(alpha)<<24) | (rgb & 0xFFFFFF); +} + +uint32_t rgba(float r, float g, float b, float alpha) { + uint32_t color = (int)(alpha*255)<<24; + color |= (int)(b*255)<<16; + color |= (int)(g*255)<<8; + color |= (int)(r*255); + return color; +} + +uint32_t rgba_clamp(float r, float g, float b, float a) { + if (r > 1.0f) r = 1.0f; + if (g > 1.0f) g = 1.0f; + if (b > 1.0f) b = 1.0f; + if (a > 1.0f) a = 1.0f; + + if (r < 0.0f) r = 0.0f; + if (g < 0.0f) g = 0.0f; + if (b < 0.0f) b = 0.0f; + if (a < 0.0f) a = 0.0f; + + return rgba(r,g,b,a); +} + +/* hsv2rgb.c +* Convert Hue Saturation Value to Red Green Blue +* +* P.J. 08-Aug-98 +* +* Reference: +* D. F. Rogers +* Procedural Elements for Computer Graphics +* McGraw Hill 1985 +*/ +uint32_t hsva(float H, float S, float V, float alpha) { + /* + * Purpose: + * Convert HSV values to RGB values + * All values are in the range [0.0 .. 1.0] + */ + float F, M, N, K; + int I; + if ( S == 0.0 ) { + // Achromatic case, set level of grey + return rgba(V, V, V, alpha); + } else { + /* + * Determine levels of primary colours. + */ + if (H >= 1.0) { + H = 0.0; + } else { + H = H * 6; + } + I = (int) H; /* should be in the range 0..5 */ + F = H - I; /* fractional part */ + + M = V * (1 - S); + N = V * (1 - S * F); + K = V * (1 - S * (1 - F)); + + float r, g, b; + if (I == 0) { r = V; g = K; b = M; } + else if (I == 1) { r = N; g = V; b = M; } + else if (I == 2) { r = M; g = V; b = K; } + else if (I == 3) { r = M; g = N; b = V; } + else if (I == 4) { r = K; g = M; b = V; } + else if (I == 5) { r = V; g = M; b = N; } + else return 0; + return rgba(r, g, b, alpha); + } +} diff --git a/ext/native/base/colorutil.h b/ext/native/base/colorutil.h new file mode 100644 index 0000000000..cc5d27bcaf --- /dev/null +++ b/ext/native/base/colorutil.h @@ -0,0 +1,12 @@ +#pragma once + +#include "base/basictypes.h" + +uint32_t whiteAlpha(float alpha); +uint32_t blackAlpha(float alpha); +uint32_t colorAlpha(uint32_t color, float alpha); +uint32_t colorBlend(uint32_t color, uint32_t color2, float alpha); +uint32_t alphaMul(uint32_t color, float alphaMul); +uint32_t rgba(float r, float g, float b, float alpha); +uint32_t rgba_clamp(float r, float g, float b, float alpha); +uint32_t hsva(float h, float s, float v, float alpha); diff --git a/ext/native/base/compat.cpp b/ext/native/base/compat.cpp new file mode 100644 index 0000000000..cef9d6c008 --- /dev/null +++ b/ext/native/base/compat.cpp @@ -0,0 +1,28 @@ +#include +#include + +#include "base/compat.h" + +#if defined(_MSC_VER) && _MSC_VER < 1900 + +static int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) { + int count = -1; + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + return count; +} + +int c99_snprintf(char* str, size_t size, const char* format, ...) { + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} + +#endif \ No newline at end of file diff --git a/ext/native/base/compat.h b/ext/native/base/compat.h new file mode 100644 index 0000000000..e8e9621cf9 --- /dev/null +++ b/ext/native/base/compat.h @@ -0,0 +1,11 @@ +#pragma once + +// Implement C99 functions and similar that are missing in MSVC. + +#if defined(_MSC_VER) && _MSC_VER < 1900 + +int c99_snprintf(char* str, size_t size, const char* format, ...); +#define snprintf c99_snprintf +#define vscprintf _vscprintf + +#endif \ No newline at end of file diff --git a/ext/native/base/display.cpp b/ext/native/base/display.cpp new file mode 100644 index 0000000000..b072e1d547 --- /dev/null +++ b/ext/native/base/display.cpp @@ -0,0 +1,12 @@ +#include "base/display.h" + +int dp_xres; +int dp_yres; + +int pixel_xres; +int pixel_yres; + +int g_dpi = 1; // will be overwritten +float g_dpi_scale = 1.0f; +float pixel_in_dps = 1.0f; +float display_hz = 60.0f; \ No newline at end of file diff --git a/ext/native/base/display.h b/ext/native/base/display.h new file mode 100644 index 0000000000..930fef955a --- /dev/null +++ b/ext/native/base/display.h @@ -0,0 +1,14 @@ +#pragma once + +// This is meant to be a framework for handling DPI scaling etc. +// For now, it just consists of these ugly globals. + +extern int dp_xres; +extern int dp_yres; +extern int pixel_xres; +extern int pixel_yres; + +extern int g_dpi; +extern float g_dpi_scale; +extern float pixel_in_dps; +extern float display_hz; \ No newline at end of file diff --git a/ext/native/base/error_context.cpp b/ext/native/base/error_context.cpp new file mode 100644 index 0000000000..b9337ee396 --- /dev/null +++ b/ext/native/base/error_context.cpp @@ -0,0 +1,40 @@ +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/error_context.h" +#include + +// TODO: Fix this threadery +#ifndef _WIN32 +#undef __THREAD +#define __THREAD +#endif + +__THREAD std::vector *_error_context_name; +__THREAD std::vector *_error_context_data; + +_ErrorContext::_ErrorContext(const char *name, const char *data) { + if (!_error_context_name) { + _error_context_name = new std::vector(); + _error_context_data = new std::vector(); + _error_context_name->reserve(16); + _error_context_data->reserve(16); + } + _error_context_name->push_back(name); + _error_context_data->push_back(data); +} + +_ErrorContext::~_ErrorContext() { + _error_context_name->pop_back(); + _error_context_data->pop_back(); +} + +void _ErrorContext::Log(const char *message) { + ILOG("EC: %s", message); + for (size_t i = 0; i < _error_context_name->size(); i++) { + if ((*_error_context_data)[i] != 0) { + ILOG("EC: %s: %s", (*_error_context_name)[i], (*_error_context_data)[i]); + } else { + ILOG("EC: %s: %s", (*_error_context_name)[i], (*_error_context_data)[i]); + } + } +} diff --git a/ext/native/base/error_context.h b/ext/native/base/error_context.h new file mode 100644 index 0000000000..d5cabffbe2 --- /dev/null +++ b/ext/native/base/error_context.h @@ -0,0 +1,18 @@ +#pragma once + +// do not inherit + +// TODO: Have the crash handler investigate the error context. +// Must only be constructed on the stack - DO NOT put these on the heap. +class _ErrorContext +{ +public: + _ErrorContext(const char *name, const char *data = 0); + ~_ErrorContext(); + + // Logs the current context stack. + static void Log(const char *message); +}; + +#define ErrorContext(...) _ErrorContext __ec(__VA_ARGS__) +#define LogErrorContext(msg) _ErrorContext::Log(msg) diff --git a/ext/native/base/fastlist.h b/ext/native/base/fastlist.h new file mode 100644 index 0000000000..9a260b173a --- /dev/null +++ b/ext/native/base/fastlist.h @@ -0,0 +1,39 @@ +#pragma once + +// An inline fastlist is a fixed size array with a position counter. +// Objects stored in a fastlist must be copyable. +// [] returns the objects in consecutive order, up to and not including +// the value of .size(). +// Order is not preserved when removing objects. +template +class InlineFastList { +public: + InlineFastList() : count_(0) {} + ~InlineFastList() {} + + T& operator [](int index) { return data_[index]; } + const T& operator [](int index) const { return data_[index]; } + int size() const { return count_; } + + void Add(T t) { + data_[count_++] = t; + } + + void RemoveAt(int index) { + data_[index] = data_[count_ - 1]; + count_--; + } + + void Remove(T t) { // Requires operator== + for (int i = 0; i < count_; i++) { + if (data_[i] == t) { + RemoveAt(i); + return; + } + } + } + +private: + T data_[max_size]; + int count_; +}; diff --git a/ext/native/base/fastlist_test.cpp b/ext/native/base/fastlist_test.cpp new file mode 100644 index 0000000000..57064adcc4 --- /dev/null +++ b/ext/native/base/fastlist_test.cpp @@ -0,0 +1,19 @@ +#include "base/fastlist.h" +#include "base/logging.h" + +/* +#include + +TEST(fastlist, AddRemove) { + InlineFastList list; + list.Add(8); + list.Remove(7); + EXPECT_EQ(1, list.size()); + list.Remove(8); + EXPECT_EQ(0, list.size()); + list.Add(1); + list.Add(2); + list.Add(3); + EXPECT_EQ(3, list.size()); +} +*/ \ No newline at end of file diff --git a/ext/native/base/functional.h b/ext/native/base/functional.h new file mode 100644 index 0000000000..d85cfc4d26 --- /dev/null +++ b/ext/native/base/functional.h @@ -0,0 +1,53 @@ +// This file simply includes and applies any necessary compatibility fixes for +// strange platforms like iOS. + +// Use placeholder as the namespace for placeholders. + +#pragma once + +#include +#ifdef __SYMBIAN32__ +#include +#include +#include +#else +#include +#endif +#include + +#if defined(__SYMBIAN32__) || defined(MACGNUSTD) +#ifndef __SYMBIAN32__ +#include +#include +#endif +namespace std { +#ifdef __SYMBIAN32__ + using boost::bind; + using boost::function; + using boost::shared_ptr; +#else + using tr1::bind; + using tr1::function; + using tr1::shared_ptr; +#endif + + template + inline shared_ptr make_shared() + { + return shared_ptr(new T()); + } + + template + inline shared_ptr make_shared(Arg1& arg1) + { + return shared_ptr(new T(arg1)); + } +} +#endif + +#ifdef __SYMBIAN32__ +#define placeholder +#else +namespace placeholder = std::placeholders; +#endif + diff --git a/ext/native/base/linked_ptr.h b/ext/native/base/linked_ptr.h new file mode 100644 index 0000000000..7eec84eed6 --- /dev/null +++ b/ext/native/base/linked_ptr.h @@ -0,0 +1,60 @@ +// From http://ootips.org/yonat/4dev/linked_ptr.h + +/* +* linked_ptr - simple reference linked pointer +* (like reference counting, just using a linked list of the references +* instead of their count.) +* +* The implementation stores three pointers for every linked_ptr, but +* does not allocate anything on the free store. +*/ + +#pragma once + +template class linked_ptr +{ +public: + explicit linked_ptr(X* p = 0) throw() : itsPtr(p) {itsPrev = itsNext = this;} + ~linked_ptr() {release();} + linked_ptr(const linked_ptr& r) throw() {acquire(r);} + + linked_ptr& operator=(const linked_ptr& r) + { + if (this != &r) { + release(); + acquire(r); + } + return *this; + } + + X& operator*() const throw() {return *itsPtr;} + X* operator->() const throw() {return itsPtr;} + X* get() const throw() {return itsPtr;} + bool unique() const throw() {return itsPrev ? itsPrev==this : true;} + +private: + X* itsPtr; + mutable const linked_ptr* itsPrev; + mutable const linked_ptr* itsNext; + + void acquire(const linked_ptr& r) throw() + { // insert this to the list + itsPtr = r.itsPtr; + itsNext = r.itsNext; + itsNext->itsPrev = this; + itsPrev = &r; + r.itsNext = this; + } + + void release() + { // erase this from the list, delete if unique + if (unique()) delete itsPtr; + else { + itsPrev->itsNext = itsNext; + itsNext->itsPrev = itsPrev; + itsPrev = itsNext = 0; + } + itsPtr = 0; + } +}; + diff --git a/ext/native/base/logging.h b/ext/native/base/logging.h new file mode 100644 index 0000000000..c96a5905a8 --- /dev/null +++ b/ext/native/base/logging.h @@ -0,0 +1,144 @@ +#pragma once + +#include + +#include "base/arch.h" +#include "base/backtrace.h" +#include "base/compat.h" + +// Simple wrapper around Android's logging interface that also allows other +// implementations, and also some misc utilities. + +#ifdef _MSC_VER +// Disable annoying warnings in VS +#pragma warning (disable:4996) //strcpy may be dangerous, etc. +#endif + +#undef Crash + +#include +// Logging +#ifdef _WIN32 + +#ifdef _M_X64 +inline void Crash() { int *x = (int *)1337; *x = 1; } +#else +inline void Crash() { __asm { int 3 }; } +#endif + +#else + +#if defined(_M_IX86) || defined(_M_X64) +inline void Crash() { + PrintBacktraceToStderr(); + asm("int $0x3"); +} +#else +inline void Crash() { + PrintBacktraceToStderr(); + char *p = (char *)1337; + *p = 1; +} +#endif + +#endif + +// Just ILOGs on nonWindows. On Windows it outputs to the VS output console. +void OutputDebugStringUTF8(const char *p); + +#if defined(ANDROID) + +#include + +// Must only be used for logging +#ifndef APP_NAME +#define APP_NAME "NativeApp" +#endif + +#ifdef _DEBUG +#define DLOG(...) __android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__); +#else +#define DLOG(...) +#endif + +#define ILOG(...) __android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__); +#define WLOG(...) __android_log_print(ANDROID_LOG_WARN, APP_NAME, __VA_ARGS__); +#define ELOG(...) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__); +#define FLOG(...) { __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__); Crash(); } + +#define MessageBox(a, b, c, d) __android_log_print(ANDROID_LOG_INFO, APP_NAME, "%s %s", (b), (c)); + +#elif defined(__SYMBIAN32__) +#include +#ifdef _DEBUG +#define DLOG(...) { qDebug(__VA_ARGS__);} +#else +#define DLOG(...) +#endif +#define ILOG(...) { qDebug(__VA_ARGS__);} +#define WLOG(...) { qDebug(__VA_ARGS__);} +#define ELOG(...) { qDebug(__VA_ARGS__);} +#define FLOG(...) { qDebug(__VA_ARGS__); Crash();} + +#else + +#ifdef _WIN32 + +#define XLOG_IMPL(type, ...) do {\ + char temp[512]; \ + char *p = temp; \ + int len = snprintf(p, sizeof(temp), type ": %s:%i: ", __FILE__, __LINE__); \ + if (len < sizeof(temp)) { \ + p += len; \ + p += snprintf(p, sizeof(temp) - len - 3, type ": " __VA_ARGS__); \ + if (p > temp + sizeof(temp) - 3) \ + p = temp + sizeof(temp) - 3; \ + p += sprintf(p, "\n"); \ + OutputDebugStringUTF8(temp); \ + } \ +} while (false) + +#ifdef _DEBUG +#define DLOG(...) XLOG_IMPL("D", __VA_ARGS__) +#else +#define DLOG(...) +#endif + +#define ILOG(...) XLOG_IMPL("I", __VA_ARGS__) +#define WLOG(...) XLOG_IMPL("W", __VA_ARGS__) +#define ELOG(...) XLOG_IMPL("E", __VA_ARGS__) +#define FLOG(...) do {XLOG_IMPL("F", __VA_ARGS__); Crash();} while (false) + +// TODO: Win32 version using OutputDebugString +#else + +#include + +inline const char *removePath(const char *str) { + const char *slash = strrchr(str, '/'); + return slash ? (slash + 1) : str; +} + +#ifdef _DEBUG +#define DLOG(...) {printf("D: %s:%i: ", removePath(__FILE__), __LINE__); printf("D: " __VA_ARGS__); printf("\n");} +#else +#define DLOG(...) +#endif +#define ILOG(...) {printf("I: %s:%i: ", removePath(__FILE__), __LINE__); printf(__VA_ARGS__); printf("\n");} +#define WLOG(...) {printf("W: %s:%i: ", removePath(__FILE__), __LINE__); printf(__VA_ARGS__); printf("\n");} +#define ELOG(...) {printf("E: %s:%i: ", removePath(__FILE__), __LINE__); printf(__VA_ARGS__); printf("\n");} +#define FLOG(...) {printf("F: %s:%i: ", removePath(__FILE__), __LINE__); printf(__VA_ARGS__); printf("\n"); Crash();} + +#endif +#endif + +#undef CHECK + +#define CHECK(a) {if (!(a)) {FLOG("%i: CHECK failed on this line", __LINE__);}} +#define CHECK_P(a, ...) {if (!(a)) {FLOG("CHECK failed: " __VA_ARGS__);}} +#define CHECK_EQ(a, b) CHECK((a) == (b)); +#define CHECK_NE(a, b) CHECK((a) != (b)); +#define CHECK_GT(a, b) CHECK((a) > (b)); +#define CHECK_GE(a, b) CHECK((a) >= (b)); +#define CHECK_LT(a, b) CHECK((a) < (b)); +#define CHECK_LE(a, b) CHECK((a) <= (b)); diff --git a/ext/native/base/mutex.h b/ext/native/base/mutex.h new file mode 100644 index 0000000000..99b4260657 --- /dev/null +++ b/ext/native/base/mutex.h @@ -0,0 +1,334 @@ +#pragma once + +// Simple cross platform mutex implementation. +// Similar to the new C++11 api. + +// Windows and pthreads implementations in one. + +// TODO: Need to clean up these primitives and put them in a reasonable namespace. + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include +#include +#include + +// Zap stupid windows defines +// Should move these somewhere clever. +#undef p +#undef DrawText +#undef itoa + +#else +#include +#include +#include +#endif + +#include "base/basictypes.h" + +struct atomic_flag_init { + atomic_flag_init() : v(false) { + } + + bool v; +}; +static const atomic_flag_init NATIVE_ATOMIC_FLAG_INIT; + +class atomic_flag { +public: + atomic_flag() { + } + + atomic_flag(const atomic_flag_init &v) : value(0) { + } + + void clear() { +#if defined(_WIN32) + _WriteBarrier(); + value = 0; +#else + __sync_lock_release(&value); +#endif + } + + // Returns the previous value. + bool test_and_set() { +#if defined(_WIN32) + return InterlockedExchange(&value, 1) != 0; +#else + return __sync_lock_test_and_set(&value, 1) != 0; +#endif + } + +private: + volatile unsigned int value; + + DISALLOW_COPY_AND_ASSIGN(atomic_flag); +}; + +class recursive_mutex { +#ifdef _WIN32 + typedef CRITICAL_SECTION mutexType; +#else + typedef pthread_mutex_t mutexType; +#endif +public: + recursive_mutex() { +#ifdef _WIN32 + InitializeCriticalSection(&mut_); +#else + // Critical sections are recursive so let's make these recursive too. + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mut_, &attr); +#endif + } + ~recursive_mutex() { +#ifdef _WIN32 + DeleteCriticalSection(&mut_); +#else + pthread_mutex_destroy(&mut_); +#endif + } + + bool trylock() { +#ifdef _WIN32 + return TryEnterCriticalSection(&mut_) != FALSE; +#else + return pthread_mutex_trylock(&mut_) != EBUSY; +#endif + } + + void lock() { +#ifdef _WIN32 + EnterCriticalSection(&mut_); +#else + pthread_mutex_lock(&mut_); +#endif + } + + void unlock() { +#ifdef _WIN32 + LeaveCriticalSection(&mut_); +#else + pthread_mutex_unlock(&mut_); +#endif + } + + mutexType &native_handle() { + return mut_; + } + +private: + mutexType mut_; + recursive_mutex(const recursive_mutex &other); +}; + +class lock_guard { +public: + lock_guard(recursive_mutex &mtx) : mtx_(mtx) {mtx_.lock();} + ~lock_guard() {mtx_.unlock();} + +private: + recursive_mutex &mtx_; +}; + + +// Like a Windows event, or a modern condition variable. + +class event { +public: +#ifdef _WIN32 +#else +#endif + event() { +#ifdef _WIN32 + event_ = CreateEvent(0, FALSE, FALSE, 0); +#else + pthread_cond_init(&event_, NULL); +#endif + } + ~event() { +#ifdef _WIN32 + CloseHandle(event_); +#else + pthread_cond_destroy(&event_); +#endif + } + + void notify_one() { +#ifdef _WIN32 + SetEvent(event_); +#else + pthread_cond_signal(&event_); +#endif + } + + // notify_all is not really possible to implement with win32 events? + + void wait(recursive_mutex &mtx) { + // broken +#ifdef _WIN32 + // This has to be horribly racy. + mtx.lock(); + WaitForSingleObject(event_, INFINITE); + ResetEvent(event_); // necessary? + mtx.unlock(); +#else + pthread_mutex_lock(&mtx.native_handle()); + pthread_cond_wait(&event_, &mtx.native_handle()); + pthread_mutex_unlock(&mtx.native_handle()); +#endif + } + + void wait_for(recursive_mutex &mtx, int milliseconds) { +#ifdef _WIN32 + //mtx.unlock(); + WaitForSingleObject(event_, milliseconds); + ResetEvent(event_); // necessary? + // mtx.lock(); +#else + timespec timeout; +#ifdef __APPLE__ + timeval tv; + gettimeofday(&tv, NULL); + timeout.tv_sec = tv.tv_sec; + timeout.tv_nsec = tv.tv_usec * 1000; +#else + clock_gettime(CLOCK_REALTIME, &timeout); +#endif + timeout.tv_sec += milliseconds / 1000; + timeout.tv_nsec += (milliseconds % 1000) * 1000000; + pthread_mutex_lock(&mtx.native_handle()); + pthread_cond_timedwait(&event_, &mtx.native_handle(), &timeout); + pthread_mutex_unlock(&mtx.native_handle()); +#endif + } + + void reset() { +#ifdef _WIN32 + ResetEvent(event_); +#endif + } +private: +#ifdef _WIN32 + HANDLE event_; +#else + pthread_cond_t event_; +#endif +}; + +// Win32 CONDITION_VARIABLE is Vista+ only. We thus limit it to our 64-bit builds where +// we can be almost certain that the user isn't running XP. + +class condition_variable { +public: +#ifdef _WIN32 +#else +#endif + condition_variable() { +#ifdef _WIN32 +#ifdef _WIN64 + InitializeConditionVariable(&cond_); +#else + sema_ = CreateSemaphore(NULL, 0, LONG_MAX, NULL); + waiting_ = 0; +#endif +#else + pthread_cond_init(&event_, NULL); +#endif + } + ~condition_variable() { +#ifdef _WIN32 +#ifdef _WIN64 +#else + CloseHandle(sema_); +#endif +#else + pthread_cond_destroy(&event_); +#endif + } + + void notify_one() { +#ifdef _WIN32 +#ifdef _M_X64 + WakeConditionVariable(&cond_); +#else + // Should be locked at this time. + if (waiting_ != 0) { + ReleaseSemaphore(sema_, 1, NULL); + } +#endif +#else + pthread_cond_signal(&event_); +#endif + } + + // notify_all is not really possible to implement with win32 events? + // Can be done just fine using WakeAllConditionVariable though. + + void wait(recursive_mutex &mtx) { + // broken http://msdn.microsoft.com/en-us/library/windows/desktop/ms686301(v=vs.85).aspx +#ifdef _WIN32 +#ifdef _M_X64 + SleepConditionVariableCS(&cond_, &mtx.native_handle(), INFINITE); +#else + // Since a semaphore keeps a count, the window between unlock and lock won't cause us to deadlock. + // However, we could wake early incorrectly (if the semaphore is signalled already.) + // That's better than deadlocking or forgetting to wake. + waiting_++; + mtx.unlock(); + WaitForSingleObject(sema_, INFINITE); + mtx.lock(); + waiting_--; +#endif +#else + pthread_cond_wait(&event_, &mtx.native_handle()); +#endif + } + + void wait_for(recursive_mutex &mtx, int milliseconds) { +#ifdef _WIN32 +#ifdef _M_X64 + SleepConditionVariableCS(&cond_, &mtx.native_handle(), milliseconds); +#else + // Since a semaphore keeps a count, the window between unlock and lock won't cause us to deadlock. + // However, we could wake early incorrectly (if the semaphore is signalled already.) + // That's better than deadlocking or forgetting to wake. + waiting_++; + mtx.unlock(); + WaitForSingleObject(sema_, milliseconds); + mtx.lock(); + waiting_--; +#endif +#else + timespec timeout; +#ifdef __APPLE__ + timeval tv; + gettimeofday(&tv, NULL); + timeout.tv_sec = tv.tv_sec; + timeout.tv_nsec = tv.tv_usec * 1000; +#else + clock_gettime(CLOCK_REALTIME, &timeout); +#endif + timeout.tv_sec += milliseconds / 1000; + timeout.tv_nsec += (milliseconds % 1000) * 1000000; + pthread_cond_timedwait(&event_, &mtx.native_handle(), &timeout); +#endif + } + +private: +#ifdef _WIN32 +#ifdef _M_X64 + CONDITION_VARIABLE cond_; +#else + HANDLE sema_; + volatile int waiting_; +#endif +#else + pthread_cond_t event_; +#endif +}; diff --git a/ext/native/base/scoped_ptr.h b/ext/native/base/scoped_ptr.h new file mode 100644 index 0000000000..d1af1c81d0 --- /dev/null +++ b/ext/native/base/scoped_ptr.h @@ -0,0 +1,30 @@ +#pragma once + +// Trivial implementation of boost::scoped_ptr, in a way that I prefer. + +template +class scoped_ptr { +public: + scoped_ptr() : ptr_(0) {} + scoped_ptr(T *p) : ptr_(p) {} + ~scoped_ptr() { + delete ptr_; + } + void reset(T *p) { + delete ptr_; + ptr_ = p; + } + T *release() { + T *p = ptr_; + ptr_ = 0; + return p; + } + T *operator->() { return ptr_; } + const T *operator->() const { return ptr_; } + const T *get() const { return ptr_; } + T *get() { return ptr_; } +private: + scoped_ptr(const scoped_ptr &other); + void operator=(const scoped_ptr &other); + T *ptr_; +}; diff --git a/ext/native/base/stats.h b/ext/native/base/stats.h new file mode 100644 index 0000000000..b111a01dc8 --- /dev/null +++ b/ext/native/base/stats.h @@ -0,0 +1,18 @@ +#pragma once + +// Statistics collection. Not very developed. + +#define STATS_ENABLE + +#ifdef STATS_ENABLE + +void IncrementStat(const char *name); + +#define INCSTAT(name) IncrementStat(name); + +#else + +#define INCSTAT(name) + +#endif + diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp new file mode 100644 index 0000000000..dcc007d799 --- /dev/null +++ b/ext/native/base/stringutil.cpp @@ -0,0 +1,280 @@ +#ifdef _WIN32 +#include +#undef min +#undef max +#endif +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "base/buffer.h" +#include "base/stringutil.h" + +#ifdef _WIN32 +// Function Cross-Compatibility +#define strcasecmp _stricmp + +void OutputDebugStringUTF8(const char *p) { + wchar_t temp[2048]; + int len = std::min(2047, (int)strlen(p)); + int size = (int)MultiByteToWideChar(CP_UTF8, 0, p, len, NULL, 0); + MultiByteToWideChar(CP_UTF8, 0, p, len, temp, size); + temp[size] = 0; + OutputDebugString(temp); +} + +#else + +void OutputDebugStringUTF8(const char *p) { + ILOG("%s", p); +} + +#endif + +void StringTrimEndNonAlphaNum(char *str) { + ssize_t n = strlen(str); + while (!isalnum(str[n]) && n >= 0) { + str[n--] = '\0'; + } +} + +void SkipSpace(const char **ptr) { + while (**ptr && isspace(**ptr)) { + (*ptr)++; + } +} + +void StringUpper(char *str) { + while (*str) { + *str = toupper(*str); + str++; + } +} + +void StringUpper(char *str, int len) { + while (len--) { + *str = toupper(*str); + str++; + } +} + + +unsigned int parseHex(const char *_szValue) +{ + int Value = 0; + size_t Finish = strlen(_szValue); + if (Finish > 8 ) { Finish = 8; } + + for (size_t Count = 0; Count < Finish; Count++) { + Value = (Value << 4); + switch( _szValue[Count] ) { + case '0': break; + case '1': Value += 1; break; + case '2': Value += 2; break; + case '3': Value += 3; break; + case '4': Value += 4; break; + case '5': Value += 5; break; + case '6': Value += 6; break; + case '7': Value += 7; break; + case '8': Value += 8; break; + case '9': Value += 9; break; + case 'A': Value += 10; break; + case 'a': Value += 10; break; + case 'B': Value += 11; break; + case 'b': Value += 11; break; + case 'C': Value += 12; break; + case 'c': Value += 12; break; + case 'D': Value += 13; break; + case 'd': Value += 13; break; + case 'E': Value += 14; break; + case 'e': Value += 14; break; + case 'F': Value += 15; break; + case 'f': Value += 15; break; + default: + Value = (Value >> 4); + Count = Finish; + } + } + return Value; +} + +void DataToHexString(const uint8_t *data, size_t size, std::string *output) { + Buffer buffer; + for (size_t i = 0; i < size; i++) { + buffer.Printf("%02x ", data[i]); + if (i && !(i & 15)) + buffer.Printf("\n"); + } + buffer.TakeAll(output); +} + +std::string StringFromFormat(const char* format, ...) +{ + va_list args; + char *buf = NULL; + std::string temp = ""; +#ifdef _WIN32 + int required = 0; + + va_start(args, format); + required = _vscprintf(format, args); + buf = new char[required + 1]; + if(vsnprintf(buf, required, format, args) < 0) + buf[0] = '\0'; + va_end(args); + + buf[required] = '\0'; + temp = buf; + delete[] buf; +#else + va_start(args, format); + if(vasprintf(&buf, format, args) < 0) + buf = NULL; + va_end(args); + + if(buf != NULL) { + temp = buf; + free(buf); + } +#endif + return temp; +} + +std::string StringFromInt(int value) +{ + char temp[16]; + sprintf(temp, "%i", value); + return temp; +} + +std::string StringFromBool(bool value) +{ + return value ? "True" : "False"; +} + +// Turns " hej " into "hej". Also handles tabs. +std::string StripSpaces(const std::string &str) +{ + const size_t s = str.find_first_not_of(" \t\r\n"); + + if (str.npos != s) + return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); + else + return ""; +} + +// "\"hello\"" is turned to "hello" +// This one assumes that the string has already been space stripped in both +// ends, as done by StripSpaces above, for example. +std::string StripQuotes(const std::string& s) +{ + if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) + return s.substr(1, s.size() - 2); + else + return s; +} + +// For Debugging. Read out an u8 array. +std::string ArrayToString(const uint8_t *data, uint32_t size, int line_len, bool spaces) +{ + std::ostringstream oss; + oss << std::setfill('0') << std::hex; + + for (int line = 0; size; ++data, --size) + { + oss << std::setw(2) << (int)*data; + if (line_len == ++line) + { + oss << '\n'; + line = 0; + } + else if (spaces) + oss << ' '; + } + + return oss.str(); +} + +bool TryParse(const std::string &str, uint32_t *const output) +{ + char *endptr = NULL; + + // Holy crap this is ugly. + + // Reset errno to a value other than ERANGE + errno = 0; + + unsigned long value = strtoul(str.c_str(), &endptr, 0); + + if (!endptr || *endptr) + return false; + + if (errno == ERANGE) + return false; + + if (ULONG_MAX > UINT_MAX) { +#ifdef _MSC_VER +#pragma warning (disable:4309) +#endif + // Note: The typecasts avoid GCC warnings when long is 32 bits wide. + if (value >= static_cast(0x100000000ull) + && value <= static_cast(0xFFFFFFFF00000000ull)) + return false; + } + + *output = static_cast(value); + return true; +} + +bool TryParse(const std::string &str, bool *const output) +{ + if ("1" == str || !strcasecmp("true", str.c_str())) + *output = true; + else if ("0" == str || !strcasecmp("false", str.c_str())) + *output = false; + else + return false; + + return true; +} + +void SplitString(const std::string& str, const char delim, std::vector& output) +{ + std::istringstream iss(str); + output.resize(1); + + while (std::getline(iss, *output.rbegin(), delim)) + output.push_back(""); + + output.pop_back(); +} + +std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) +{ + size_t pos = 0; + + if (src == dest) + return result; + + while(1) + { + pos = result.find(src, pos); + if (pos == result.npos) + break; + result.replace(pos, src.size(), dest); + pos += dest.size(); + } + return result; +} + +int strcmpIgnore(std::string str1, std::string str2, std::string ignorestr1, std::string ignorestr2) { + str1 = ReplaceAll(str1, ignorestr1, ignorestr2); + str2 = ReplaceAll(str2, ignorestr1, ignorestr2); + return strcmp(str1.c_str(),str2.c_str()); +} \ No newline at end of file diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h new file mode 100644 index 0000000000..7452b4be82 --- /dev/null +++ b/ext/native/base/stringutil.h @@ -0,0 +1,165 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "base/basictypes.h" + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#define strncasecmp _strnicmp +#endif + +#ifdef BLACKBERRY +// QNX Does not have an implementation of vasprintf +static inline int vasprintf(char **rResult, const char *aFormat, va_list aAp) +{ + int rVal; + char *result; + va_list ap; + + result = (char *) malloc(16); + if (result == NULL) return -1; + + va_copy(ap, aAp); + rVal = vsnprintf(result, 16, aFormat, ap); + va_end(ap); + + if (rVal == -1) + { + free(result); + return rVal; + } + else if (rVal >= 16) + { + free(result); + result = (char *) malloc(rVal + 1); + if (result == NULL) return -1; + + va_copy(ap, aAp); + rVal = vsnprintf(result, rVal + 1, aFormat, aAp); + va_end(ap); + } + + *rResult = result; + return rVal; +} +#endif + +// Dumb wrapper around itoa, providing a buffer. Declare this on the stack. +class ITOA { +public: + char buffer[16]; + const char *p(int i) { + sprintf(buffer, "%i", i); + return &buffer[0]; + } +}; + +// Other simple string utilities. + +inline bool startsWith(const std::string &str, const std::string &what) { + if (str.size() < what.size()) + return false; + return str.substr(0, what.size()) == what; +} + +inline bool endsWith(const std::string &str, const std::string &what) { + if (str.size() < what.size()) + return false; + return str.substr(str.size() - what.size()) == what; +} + +// Only use on strings where you're only concerned about ASCII. +inline bool startsWithNoCase(const std::string &str, const std::string &what) { + if (str.size() < what.size()) + return false; + return strncasecmp(str.c_str(), what.c_str(), what.size()) == 0; +} + +inline bool endsWithNoCase(const std::string &str, const std::string &what) { + if (str.size() < what.size()) + return false; + const size_t offset = str.size() - what.size(); + return strncasecmp(str.c_str() + offset, what.c_str(), what.size()) == 0; +} + +void DataToHexString(const uint8_t *data, size_t size, std::string *output); +inline void StringToHexString(const std::string &data, std::string *output) { + DataToHexString((uint8_t *)(&data[0]), data.size(), output); +} + + +// highly unsafe and not recommended. +unsigned int parseHex(const char* _szValue); + + +// Suitable for inserting into maps, unlike char*, and cheaper than std::string. +// Strings must be constant and preferably be stored in the read-only part +// of the binary. +class ConstString { +public: + ConstString(const char *ptr) { + ptr_ = ptr; + } + bool operator <(const ConstString &other) const { + return strcmp(ptr_, other.ptr_) < 0; + } + bool operator ==(const ConstString &other) const { + return ptr_ == other.ptr_ || !strcmp(ptr_, other.ptr_); + } + const char *get() const { return ptr_; } +private: + const char *ptr_; +}; + +std::string StringFromFormat(const char* format, ...); +std::string StringFromInt(int value); +std::string StringFromBool(bool value); + +std::string ArrayToString(const uint8_t *data, uint32_t size, int line_len = 20, bool spaces = true); + +std::string StripSpaces(const std::string &s); +std::string StripQuotes(const std::string &s); + +bool TryParse(const std::string &str, bool *const output); +bool TryParse(const std::string &str, uint32_t *const output); + +template +static bool TryParse(const std::string &str, N *const output) +{ + std::istringstream iss(str); + + N tmp = 0; + if (iss >> tmp) + { + *output = tmp; + return true; + } + else + return false; +} +void SplitString(const std::string& str, const char delim, std::vector& output); + +std::string ReplaceAll(std::string input, const std::string& src, const std::string& dest); + +// Compare two strings, ignore the difference between the ignorestr1 and the ignorestr2 in str1 and str2. +int strcmpIgnore(std::string str1, std::string str2, std::string ignorestr1, std::string ignorestr2); + +template +static std::string ValueToString(const N value) +{ + std::stringstream string; + string << value; + return string.str(); +} + +void StringTrimEndNonAlphaNum(char *str); +void SkipSpace(const char **ptr); +void StringUpper(char *str); +void StringUpper(char *str, int len); diff --git a/ext/native/base/timeutil.cpp b/ext/native/base/timeutil.cpp new file mode 100644 index 0000000000..86ab3b7edf --- /dev/null +++ b/ext/native/base/timeutil.cpp @@ -0,0 +1,151 @@ +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/timeutil.h" + +// For NV time functions. Ugly! +#include "gfx/gl_common.h" +#include "gfx_es2/gpu_features.h" + +#ifdef _WIN32 +#include +#else +#include +#include +#endif +#include + +static double curtime = 0; +static float curtime_f = 0; + +#ifdef _WIN32 + +LARGE_INTEGER frequency; +double frequencyMult; +LARGE_INTEGER startTime; + +double real_time_now() { + if (frequency.QuadPart == 0) { + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&startTime); + curtime = 0.0; + frequencyMult = 1.0 / static_cast(frequency.QuadPart); + } + LARGE_INTEGER time; + QueryPerformanceCounter(&time); + double elapsed = static_cast(time.QuadPart - startTime.QuadPart); + return elapsed * frequencyMult; +} + +#elif defined(BLACKBERRY) +double real_time_now() { + struct timespec time; + clock_gettime(CLOCK_MONOTONIC, &time); // Linux must use CLOCK_MONOTONIC_RAW due to time warps + return time.tv_sec + time.tv_nsec / 1.0e9; +} +#else + +uint64_t _frequency = 0; +uint64_t _starttime = 0; + +double real_time_now() { +#ifdef ANDROID + if (false && gl_extensions.EGL_NV_system_time) { + // This is needed to profile using PerfHUD on Tegra + if (_frequency == 0) { + _frequency = eglGetSystemTimeFrequencyNV(); + _starttime = eglGetSystemTimeNV(); + } + + uint64_t cur = eglGetSystemTimeNV(); + int64_t diff = cur - _starttime; + + return (double)diff / (double)_frequency; + } +#if 0 + // This clock is really "choppy" on Nexus 9! + struct timespec time; + clock_gettime(CLOCK_MONOTONIC_RAW, &time); + return time.tv_sec + time.tv_nsec / 1.0e9; +#else + static time_t start; + struct timeval tv; + gettimeofday(&tv, NULL); + if (start == 0) { + start = tv.tv_sec; + } + tv.tv_sec -= start; + return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0; +#endif + +#else + static time_t start; + struct timeval tv; + gettimeofday(&tv, NULL); + if (start == 0) { + start = tv.tv_sec; + } + tv.tv_sec -= start; + return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0; +#endif +} + +#endif + +void time_update() { + curtime = real_time_now(); + curtime_f = (float)curtime; + + //printf("curtime: %f %f\n", curtime, curtime_f); + // also smooth time. + //curtime+=float((double) (time-_starttime) / (double) _frequency); + //curtime*=0.5f; + //curtime+=1.0f/60.0f; + //lastTime=curtime; + //curtime_f = (float)curtime; +} + +float time_now() { + return curtime_f; +} + +double time_now_d() { + return curtime; +} + +int time_now_ms() { + return int(curtime*1000.0); +} + +void sleep_ms(int ms) { +#ifdef _WIN32 +#ifndef METRO + Sleep(ms); +#endif +#else + usleep(ms * 1000); +#endif +} + +LoggingDeadline::LoggingDeadline(const char *name, int ms) : name_(name), endCalled_(false) { + totalTime_ = (double)ms * 0.001; + time_update(); + endTime_ = time_now_d() + totalTime_; +} + +LoggingDeadline::~LoggingDeadline() { + if (!endCalled_) + End(); +} + +bool LoggingDeadline::End() { + endCalled_ = true; + time_update(); + if (time_now_d() > endTime_) { + double late = (time_now_d() - endTime_); + double totalTime = late + totalTime_; + ELOG("===== %0.2fms DEADLINE PASSED FOR %s at %0.2fms - %0.2fms late =====", totalTime_ * 1000.0, name_, 1000.0 * totalTime, 1000.0 * late); + return false; + } + return true; +} + diff --git a/ext/native/base/timeutil.h b/ext/native/base/timeutil.h new file mode 100644 index 0000000000..8ba68ca8ad --- /dev/null +++ b/ext/native/base/timeutil.h @@ -0,0 +1,37 @@ +#pragma once + +// http://linux.die.net/man/3/clock_gettime + +// This time implementation caches the time for max performance (call time_now() as much as you like). +// You need to call time_update() once per frame (or whenever you need the correct time right now). + +void time_update(); + +// Seconds. +float time_now(); +double time_now_d(); + +// Uncached time. Slower than the above cached time functions. Does not update cached time, call time_update for that. +double real_time_now(); + +int time_now_ms(); + + +// Sleep. Does not necessarily have millisecond granularity, especially on Windows. +void sleep_ms(int ms); + + +// Can be sprinkled around the code to make sure that thing don't take +// unexpectedly long. What that means is up to you. +class LoggingDeadline { +public: + LoggingDeadline(const char *name, int deadline_in_ms); + ~LoggingDeadline(); + bool End(); + +private: + const char *name_; + bool endCalled_; + double totalTime_; + double endTime_; +}; \ No newline at end of file diff --git a/ext/native/data/compression.cpp b/ext/native/data/compression.cpp new file mode 100644 index 0000000000..f2bc6494ee --- /dev/null +++ b/ext/native/data/compression.cpp @@ -0,0 +1,105 @@ +// Little utility functions for data compression. +// Taken from http://panthema.net/2007/0328-ZLibString.html + + +#include +#include +#include +#include +#include +#include + +#include + +#include "base/logging.h" + +/** Compress a STL string using zlib with given compression level and return +* the binary data. */ +bool compress_string(const std::string& str, std::string *dest, int compressionlevel) { + z_stream zs; // z_stream is zlib's control structure + memset(&zs, 0, sizeof(zs)); + + if (deflateInit(&zs, compressionlevel) != Z_OK) { + ELOG("deflateInit failed while compressing."); + return false; + } + + zs.next_in = (Bytef*)str.data(); + zs.avail_in = (uInt)str.size(); // set the z_stream's input + + int ret; + char outbuffer[32768]; + std::string outstring; + + // retrieve the compressed bytes blockwise + do { + zs.next_out = reinterpret_cast(outbuffer); + zs.avail_out = sizeof(outbuffer); + + ret = deflate(&zs, Z_FINISH); + + if (outstring.size() < zs.total_out) { + // append the block to the output string + outstring.append(outbuffer, + zs.total_out - outstring.size()); + } + } while (ret == Z_OK); + + deflateEnd(&zs); + + if (ret != Z_STREAM_END) { // an error occurred that was not EOF + std::ostringstream oss; + oss << "Exception during zlib compression: (" << ret << ") " << zs.msg; + return false; + } + + *dest = outstring; + return true; +} + +/** Decompress an STL string using zlib and return the original data. */ +bool decompress_string(const std::string& str, std::string *dest) { + if (!str.size()) + return false; + + z_stream zs; // z_stream is zlib's control structure + memset(&zs, 0, sizeof(zs)); + + // modification by hrydgard: inflateInit2, 16+MAXWBITS makes it read gzip data too + if (inflateInit2(&zs, 32+MAX_WBITS) != Z_OK) { + ELOG("inflateInit failed while decompressing."); + return false; + } + + zs.next_in = (Bytef*)str.data(); + zs.avail_in = (uInt)str.size(); + + int ret; + char outbuffer[32768]; + std::string outstring; + + // get the decompressed bytes blockwise using repeated calls to inflate + do { + zs.next_out = reinterpret_cast(outbuffer); + zs.avail_out = sizeof(outbuffer); + + ret = inflate(&zs, 0); + + if (outstring.size() < zs.total_out) { + outstring.append(outbuffer, + zs.total_out - outstring.size()); + } + + } while (ret == Z_OK); + + inflateEnd(&zs); + + if (ret != Z_STREAM_END) { // an error occurred that was not EOF + std::ostringstream oss; + ELOG("Exception during zlib decompression: (%i) %s", ret, zs.msg); + return false; + } + + *dest = outstring; + return true; +} diff --git a/ext/native/data/compression.h b/ext/native/data/compression.h new file mode 100644 index 0000000000..e37ff85794 --- /dev/null +++ b/ext/native/data/compression.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +bool compress_string(const std::string& str, std::string *dest, int compressionlevel = 9); +bool decompress_string(const std::string& str, std::string *dest); + + +// Delta encoding/decoding - many formats benefit from a pass of this before zlibbing. +// WARNING : Do not use these with floating point data, especially not float16... + +template +inline void delta(T *data, int length) { + T prev = data[0]; + for (int i = 1; i < length; i++) { + T temp = data[i] - prev; + prev = data[i]; + data[i] = temp; + } +} + +template +inline void dedelta(T *data, int length) { + for (int i = 1; i < length; i++) { + data[i] += data[i - 1]; + } +} + diff --git a/ext/native/data/listable.h b/ext/native/data/listable.h new file mode 100644 index 0000000000..017cacf1b9 --- /dev/null +++ b/ext/native/data/listable.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include + +class Listable +{ +public: + virtual ~Listable() {} + virtual const char *getItem(size_t i) const = 0; + virtual size_t numItems() const = 0; + + // Returns -1 for not found. + // Child classes are meant to specialize this if they have a faster way + // than brute force search. + virtual int getIndex(const char *text) { + for (size_t i = 0; i < numItems(); i++) { + if (!strcmp(getItem(i), text)) + return i; + } + return -1; + } +}; + +class ArrayListable : public Listable +{ +public: + ArrayListable(const char * const*arr, size_t count) : arr_(arr), count_(count) {} + virtual ~ArrayListable() {} + + virtual const char *getItem(size_t i) const { return arr_[i]; } + virtual size_t numItems() const { return count_; } + +private: + const char *const*arr_; + size_t count_; +}; + +class VectorListable : public Listable +{ + VectorListable(const std::vector &vec) : vec_(vec) {} + virtual ~VectorListable() {} + + virtual const char *getItem(size_t i) const { return vec_[i].c_str(); } + virtual size_t numItems() const { return vec_.size(); } + +private: + const std::vector &vec_; +}; \ No newline at end of file diff --git a/ext/native/ext/cityhash/COPYING b/ext/native/ext/cityhash/COPYING new file mode 100644 index 0000000000..bf15194dd5 --- /dev/null +++ b/ext/native/ext/cityhash/COPYING @@ -0,0 +1,19 @@ +// Copyright (c) 2011 Google, Inc. +// +// 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/ext/native/ext/cityhash/README b/ext/native/ext/cityhash/README new file mode 100644 index 0000000000..9ce14ea3b7 --- /dev/null +++ b/ext/native/ext/cityhash/README @@ -0,0 +1,200 @@ +NOTE: This is a cut down version of Google CityHash for easy building. + + + +CityHash, a family of hash functions for strings. + + +Introduction +============ + +CityHash provides hash functions for strings. The functions mix the +input bits thoroughly but are not suitable for cryptography. See +"Hash Quality," below, for details on how CityHash was tested and so on. + +We provide reference implementations in C++, with a friendly MIT license. + +CityHash32() returns a 32-bit hash. + +CityHash64() and similar return a 64-bit hash. + +CityHash128() and similar return a 128-bit hash and are tuned for +strings of at least a few hundred bytes. Depending on your compiler +and hardware, it's likely faster than CityHash64() on sufficiently long +strings. It's slower than necessary on shorter strings, but we expect +that case to be relatively unimportant. + +CityHashCrc128() and similar are variants of CityHash128() that depend +on _mm_crc32_u64(), an intrinsic that compiles to a CRC32 instruction +on some CPUs. However, none of the functions we provide are CRCs. + +CityHashCrc256() is a variant of CityHashCrc128() that also depends +on _mm_crc32_u64(). It returns a 256-bit hash. + +All members of the CityHash family were designed with heavy reliance +on previous work by Austin Appleby, Bob Jenkins, and others. +For example, CityHash32 has many similarities with Murmur3a. + +Performance on long strings: 64-bit CPUs +======================================== + +We are most excited by the performance of CityHash64() and its variants on +short strings, but long strings are interesting as well. + +CityHash is intended to be fast, under the constraint that it hash very +well. For CPUs with the CRC32 instruction, CRC is speedy, but CRC wasn't +designed as a hash function and shouldn't be used as one. CityHashCrc128() +is not a CRC, but it uses the CRC32 machinery. + +On a single core of a 2.67GHz Intel Xeon X5550, CityHashCrc256 peaks at about +5 to 5.5 bytes/cycle. The other CityHashCrc functions are wrappers around +CityHashCrc256 and should have similar performance on long strings. +(CityHashCrc256 in v1.0.3 was even faster, but we decided it wasn't as thorough +as it should be.) CityHash128 peaks at about 4.3 bytes/cycle. The fastest +Murmur variant on that hardware, Murmur3F, peaks at about 2.4 bytes/cycle. +We expect the peak speed of CityHash128 to dominate CityHash64, which is +aimed more toward short strings or use in hash tables. + +For long strings, a new function by Bob Jenkins, SpookyHash, is just +slightly slower than CityHash128 on Intel x86-64 CPUs, but noticeably +faster on AMD x86-64 CPUs. For hashing long strings on AMD CPUs +and/or CPUs without the CRC instruction, SpookyHash may be just as +good or better than any of the CityHash variants. + +Performance on short strings: 64-bit CPUs +========================================= + +For short strings, e.g., most hash table keys, CityHash64 is faster than +CityHash128, and probably faster than all the aforementioned functions, +depending on the mix of string lengths. Here are a few results from that +same hardware, where we (unrealistically) tested a single string length over +and over again: + +Hash Results +------------------------------------------------------------------------------ +CityHash64 v1.0.3 7ns for 1 byte, or 6ns for 8 bytes, or 9ns for 64 bytes +Murmur2 (64-bit) 6ns for 1 byte, or 6ns for 8 bytes, or 15ns for 64 bytes +Murmur3F 14ns for 1 byte, or 15ns for 8 bytes, or 23ns for 64 bytes + +We don't have CityHash64 benchmarks results for v1.1, but we expect the +numbers to be similar. + +Performance: 32-bit CPUs +======================== + +CityHash32 is the newest variant of CityHash. It is intended for +32-bit hardware in general but has been mostly tested on x86. Our benchmarks +suggest that Murmur3 is the nearest competitor to CityHash32 on x86. +We don't know of anything faster that has comparable quality. The speed rankings +in our testing: CityHash32 > Murmur3f > Murmur3a (for long strings), and +CityHash32 > Murmur3a > Murmur3f (for short strings). + +Installation +============ + +We provide reference implementations of several CityHash functions, written +in C++. The build system is based on autoconf. It defaults the C++ +compiler flags to "-g -O2", which is probably slower than -O3 if you are +using gcc. YMMV. + +On systems with gcc, we generally recommend: + +./configure +make all check CXXFLAGS="-g -O3" +sudo make install + +Or, if your system has the CRC32 instruction, and you want to build everything: + +./configure --enable-sse4.2 +make all check CXXFLAGS="-g -O3 -msse4.2" +sudo make install + +Note that our build system doesn't try to determine the appropriate compiler +flag for enabling SSE4.2. For gcc it is "-msse4.2". The --enable-sse4.2 +flag to the configure script controls whether citycrc.h is installed when +you "make install." In general, picking the right compiler flags can be +tricky, and may depend on your compiler, your hardware, and even how you +plan to use the library. + +For generic information about how to configure this software, please try: + +./configure --help + +Failing that, please work from city.cc and city*.h, as they contain all the +necessary code. + + +Usage +===== + +The above installation instructions will produce a single library. It will +contain CityHash32(), CityHash64(), and CityHash128(), and their variants, +and possibly CityHashCrc128(), CityHashCrc128WithSeed(), and +CityHashCrc256(). The functions with Crc in the name are declared in +citycrc.h; the rest are declared in city.h. + + +Limitations +=========== + +1) CityHash32 is intended for little-endian 32-bit code, and everything else in +the current version of CityHash is intended for little-endian 64-bit CPUs. + +All functions that don't use the CRC32 instruction should work in +little-endian 32-bit or 64-bit code. CityHash should work on big-endian CPUs +as well, but we haven't tested that very thoroughly yet. + +2) CityHash is fairly complex. As a result of its complexity, it may not +perform as expected on some compilers. For example, preliminary reports +suggest that some Microsoft compilers compile CityHash to assembly that's +10-20% slower than it could be. + + +Hash Quality +============ + +We like to test hash functions with SMHasher, among other things. +SMHasher isn't perfect, but it seems to find almost any significant flaw. +SMHasher is available at http://code.google.com/p/smhasher/ + +SMHasher is designed to pass a 32-bit seed to the hash functions it tests. +No CityHash function is designed to work that way, so we adapt as follows: +For our functions that accept a seed, we use the given seed directly (padded +with zeroes); for our functions that don't accept a seed, we hash the +concatenation of the given seed and the input string. + +The CityHash functions have the following flaws according to SMHasher: + +(1) CityHash64: none + +(2) CityHash64WithSeed: none + +(3) CityHash64WithSeeds: did not test + +(4) CityHash128: none + +(5) CityHash128WithSeed: none + +(6) CityHashCrc128: none + +(7) CityHashCrc128WithSeed: none + +(8) CityHashCrc256: none + +(9) CityHash32: none + +Some minor flaws in 32-bit and 64-bit functions are harmless, as we +expect the primary use of these functions will be in hash tables. We +may have gone slightly overboard in trying to please SMHasher and other +similar tests, but we don't want anyone to choose a different hash function +because of some minor issue reported by a quality test. + + +For more information +==================== + +http://code.google.com/p/cityhash/ + +cityhash-discuss@googlegroups.com + +Please feel free to send us comments, questions, bug reports, or patches. diff --git a/ext/native/ext/cityhash/city.cpp b/ext/native/ext/cityhash/city.cpp new file mode 100644 index 0000000000..06190d529f --- /dev/null +++ b/ext/native/ext/cityhash/city.cpp @@ -0,0 +1,654 @@ +// Copyright (c) 2011 Google, Inc. +// +// 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. +// +// CityHash, by Geoff Pike and Jyrki Alakuijala +// +// This file provides CityHash64() and related functions. +// +// It's probably possible to create even faster hash functions by +// writing a program that systematically explores some of the space of +// possible hash functions, by using SIMD instructions, or by +// compromising on hash quality. + +#ifdef ANDROID +#undef __SSE4_2__ +#endif +#include "city.h" + +#include +#include // To check for glibc +#include // for memcpy and memset + +using namespace std; + +static uint64 UNALIGNED_LOAD64(const char *p) { + uint64 result; + memcpy(&result, p, sizeof(result)); + return result; +} + +static uint32 UNALIGNED_LOAD32(const char *p) { + uint32 result; + memcpy(&result, p, sizeof(result)); + return result; +} + +#ifdef _MSC_VER +#define bswap_32(x) _byteswap_ulong(x) +#define bswap_64(x) _byteswap_uint64(x) + +#elif defined(__GLIBC__) +#include + +#elif defined(__APPLE__) +// Mac OS X / Darwin features +#include +#define bswap_32(x) OSSwapInt32(x) +#define bswap_64(x) OSSwapInt64(x) + +#elif defined(__sun) || defined(sun) +#include +#define bswap_32(x) BSWAP_32(x) +#define bswap_64(x) BSWAP_64(x) + +#elif defined(__DragonFly__) || defined(__FreeBSD__) +#include +#define bswap_32(x) bswap32(x) +#define bswap_64(x) bswap64(x) + +#elif defined(__Bitrig__) || defined(__OpenBSD__) +#include +#define bswap_32(x) swap32(x) +#define bswap_64(x) swap64(x) + +#elif defined(__NetBSD__) +#include +#include +#if defined(__BSWAP_RENAME) && !defined(__bswap_32) +#define bswap_32(x) bswap32(x) +#define bswap_64(x) bswap64(x) +#endif + +#else +#define bswap_32(x) (0 | (((x) & 0x000000ff) << 24) \ + | (((x) & 0x0000ff00) << 8) \ + | (((x) & 0x00ff0000) >> 8) \ + | (((x) & 0xff000000) >> 24)) +#define bswap_64(x) (0 | (((x) & UINT64_C(0x00000000000000ff)) << 56) \ + | (((x) & UINT64_C(0x000000000000ff00)) << 40) \ + | (((x) & UINT64_C(0x0000000000ff0000)) << 24) \ + | (((x) & UINT64_C(0x00000000ff000000)) << 8) \ + | (((x) & UINT64_C(0x000000ff00000000)) >> 8) \ + | (((x) & UINT64_C(0x0000ff0000000000)) >> 24) \ + | (((x) & UINT64_C(0x00ff000000000000)) >> 40) \ + | (((x) & UINT64_C(0xff00000000000000)) >> 56)) +#endif + +#ifdef WORDS_BIGENDIAN +#define uint32_in_expected_order(x) (bswap_32(x)) +#define uint64_in_expected_order(x) (bswap_64(x)) +#else +#define uint32_in_expected_order(x) (x) +#define uint64_in_expected_order(x) (x) +#endif + +#if !defined(LIKELY) +#if HAVE_BUILTIN_EXPECT +#define LIKELY(x) (__builtin_expect(!!(x), 1)) +#else +#define LIKELY(x) (x) +#endif +#endif + +static uint64 Fetch64(const char *p) { + return uint64_in_expected_order(UNALIGNED_LOAD64(p)); +} + +static uint32 Fetch32(const char *p) { + return uint32_in_expected_order(UNALIGNED_LOAD32(p)); +} + +// Some primes between 2^63 and 2^64 for various uses. +static const uint64 k0 = 0xc3a5c85c97cb3127ULL; +static const uint64 k1 = 0xb492b66fbe98f273ULL; +static const uint64 k2 = 0x9ae16a3b2f90404fULL; + +// Magic numbers for 32-bit hashing. Copied from Murmur3. +static const uint32 c1 = 0xcc9e2d51; +static const uint32 c2 = 0x1b873593; + +// A 32-bit to 32-bit integer hash copied from Murmur3. +static uint32 fmix(uint32 h) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + return h; +} + +static uint32 Rotate32(uint32 val, int shift) { + // Avoid shifting by 32: doing so yields an undefined result. + return shift == 0 ? val : ((val >> shift) | (val << (32 - shift))); +} + +#undef PERMUTE3 +#define PERMUTE3(a, b, c) do { std::swap(a, b); std::swap(a, c); } while (0) + +static uint32 Mur(uint32 a, uint32 h) { + // Helper from Murmur3 for combining two 32-bit values. + a *= c1; + a = Rotate32(a, 17); + a *= c2; + h ^= a; + h = Rotate32(h, 19); + return h * 5 + 0xe6546b64; +} + +static uint32 Hash32Len13to24(const char *s, size_t len) { + uint32 a = Fetch32(s - 4 + (len >> 1)); + uint32 b = Fetch32(s + 4); + uint32 c = Fetch32(s + len - 8); + uint32 d = Fetch32(s + (len >> 1)); + uint32 e = Fetch32(s); + uint32 f = Fetch32(s + len - 4); + uint32 h = (uint32)len; + + return fmix(Mur(f, Mur(e, Mur(d, Mur(c, Mur(b, Mur(a, h))))))); +} + +static uint32 Hash32Len0to4(const char *s, size_t len) { + uint32 b = 0; + uint32 c = 9; + for (size_t i = 0; i < len; i++) { + signed char v = s[i]; + b = b * c1 + v; + c ^= b; + } + return fmix(Mur(b, Mur((uint32)len, c))); +} + +static uint32 Hash32Len5to12(const char *s, size_t len) { + uint32 a = (uint32)len, b = (uint32)len * 5, c = 9, d = b; + a += Fetch32(s); + b += Fetch32(s + len - 4); + c += Fetch32(s + ((len >> 1) & 4)); + return fmix(Mur(c, Mur(b, Mur(a, d)))); +} + +uint32 CityHash32(const char *s, size_t len) { + if (len <= 24) { + return len <= 12 ? + (len <= 4 ? Hash32Len0to4(s, len) : Hash32Len5to12(s, len)) : + Hash32Len13to24(s, len); + } + + // len > 24 + uint32 h = (uint32)len, g = c1 * (uint32)len, f = g; + uint32 a0 = Rotate32(Fetch32(s + len - 4) * c1, 17) * c2; + uint32 a1 = Rotate32(Fetch32(s + len - 8) * c1, 17) * c2; + uint32 a2 = Rotate32(Fetch32(s + len - 16) * c1, 17) * c2; + uint32 a3 = Rotate32(Fetch32(s + len - 12) * c1, 17) * c2; + uint32 a4 = Rotate32(Fetch32(s + len - 20) * c1, 17) * c2; + h ^= a0; + h = Rotate32(h, 19); + h = h * 5 + 0xe6546b64; + h ^= a2; + h = Rotate32(h, 19); + h = h * 5 + 0xe6546b64; + g ^= a1; + g = Rotate32(g, 19); + g = g * 5 + 0xe6546b64; + g ^= a3; + g = Rotate32(g, 19); + g = g * 5 + 0xe6546b64; + f += a4; + f = Rotate32(f, 19); + f = f * 5 + 0xe6546b64; + size_t iters = (len - 1) / 20; + do { + uint32 a0 = Rotate32(Fetch32(s) * c1, 17) * c2; + uint32 a1 = Fetch32(s + 4); + uint32 a2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2; + uint32 a3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2; + uint32 a4 = Fetch32(s + 16); + h ^= a0; + h = Rotate32(h, 18); + h = h * 5 + 0xe6546b64; + f += a1; + f = Rotate32(f, 19); + f = f * c1; + g += a2; + g = Rotate32(g, 18); + g = g * 5 + 0xe6546b64; + h ^= a3 + a1; + h = Rotate32(h, 19); + h = h * 5 + 0xe6546b64; + g ^= a4; + g = bswap_32(g) * 5; + h += a4 * 5; + h = bswap_32(h); + f += a0; + PERMUTE3(f, h, g); + s += 20; + } while (--iters != 0); + g = Rotate32(g, 11) * c1; + g = Rotate32(g, 17) * c1; + f = Rotate32(f, 11) * c1; + f = Rotate32(f, 17) * c1; + h = Rotate32(h + g, 19); + h = h * 5 + 0xe6546b64; + h = Rotate32(h, 17) * c1; + h = Rotate32(h + f, 19); + h = h * 5 + 0xe6546b64; + h = Rotate32(h, 17) * c1; + return h; +} + +// Bitwise right rotate. Normally this will compile to a single +// instruction, especially if the shift is a manifest constant. +static uint64 Rotate(uint64 val, int shift) { + // Avoid shifting by 64: doing so yields an undefined result. + return shift == 0 ? val : ((val >> shift) | (val << (64 - shift))); +} + +static uint64 ShiftMix(uint64 val) { + return val ^ (val >> 47); +} + +static uint64 HashLen16(uint64 u, uint64 v) { + return Hash128to64(uint128(u, v)); +} + +static uint64 HashLen16(uint64 u, uint64 v, uint64 mul) { + // Murmur-inspired hashing. + uint64 a = (u ^ v) * mul; + a ^= (a >> 47); + uint64 b = (v ^ a) * mul; + b ^= (b >> 47); + b *= mul; + return b; +} + +static uint64 HashLen0to16(const char *s, size_t len) { + if (len >= 8) { + uint64 mul = k2 + len * 2; + uint64 a = Fetch64(s) + k2; + uint64 b = Fetch64(s + len - 8); + uint64 c = Rotate(b, 37) * mul + a; + uint64 d = (Rotate(a, 25) + b) * mul; + return HashLen16(c, d, mul); + } + if (len >= 4) { + uint64 mul = k2 + len * 2; + uint64 a = Fetch32(s); + return HashLen16(len + (a << 3), Fetch32(s + len - 4), mul); + } + if (len > 0) { + uint8 a = s[0]; + uint8 b = s[len >> 1]; + uint8 c = s[len - 1]; + uint32 y = static_cast(a) + (static_cast(b) << 8); + uint32 z = (uint32)len + (static_cast(c) << 2); + return ShiftMix(y * k2 ^ z * k0) * k2; + } + return k2; +} + +// This probably works well for 16-byte strings as well, but it may be overkill +// in that case. +static uint64 HashLen17to32(const char *s, size_t len) { + uint64 mul = k2 + len * 2; + uint64 a = Fetch64(s) * k1; + uint64 b = Fetch64(s + 8); + uint64 c = Fetch64(s + len - 8) * mul; + uint64 d = Fetch64(s + len - 16) * k2; + return HashLen16(Rotate(a + b, 43) + Rotate(c, 30) + d, + a + Rotate(b + k2, 18) + c, mul); +} + +// Return a 16-byte hash for 48 bytes. Quick and dirty. +// Callers do best to use "random-looking" values for a and b. +static pair WeakHashLen32WithSeeds( + uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b) { + a += w; + b = Rotate(b + a + z, 21); + uint64 c = a; + a += x; + a += y; + b += Rotate(a, 44); + return make_pair(a + z, b + c); +} + +// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. +static pair WeakHashLen32WithSeeds( + const char* s, uint64 a, uint64 b) { + return WeakHashLen32WithSeeds(Fetch64(s), + Fetch64(s + 8), + Fetch64(s + 16), + Fetch64(s + 24), + a, + b); +} + +// Return an 8-byte hash for 33 to 64 bytes. +static uint64 HashLen33to64(const char *s, size_t len) { + uint64 mul = k2 + len * 2; + uint64 a = Fetch64(s) * k2; + uint64 b = Fetch64(s + 8); + uint64 c = Fetch64(s + len - 24); + uint64 d = Fetch64(s + len - 32); + uint64 e = Fetch64(s + 16) * k2; + uint64 f = Fetch64(s + 24) * 9; + uint64 g = Fetch64(s + len - 8); + uint64 h = Fetch64(s + len - 16) * mul; + uint64 u = Rotate(a + g, 43) + (Rotate(b, 30) + c) * 9; + uint64 v = ((a + g) ^ d) + f + 1; + uint64 w = bswap_64((u + v) * mul) + h; + uint64 x = Rotate(e + f, 42) + c; + uint64 y = (bswap_64((v + w) * mul) + g) * mul; + uint64 z = e + f + c; + a = bswap_64((x + z) * mul + y) + b; + b = ShiftMix((z + a) * mul + d + h) * mul; + return b + x; +} + +uint64 CityHash64(const char *s, size_t len) { + if (len <= 32) { + if (len <= 16) { + return HashLen0to16(s, len); + } else { + return HashLen17to32(s, len); + } + } else if (len <= 64) { + return HashLen33to64(s, len); + } + + // For strings over 64 bytes we hash the end first, and then as we + // loop we keep 56 bytes of state: v, w, x, y, and z. + uint64 x = Fetch64(s + len - 40); + uint64 y = Fetch64(s + len - 16) + Fetch64(s + len - 56); + uint64 z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24)); + pair v = WeakHashLen32WithSeeds(s + len - 64, len, z); + pair w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x); + x = x * k1 + Fetch64(s); + + // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. + len = (len - 1) & ~static_cast(63); + do { + x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; + y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; + x ^= w.second; + y += v.first + Fetch64(s + 40); + z = Rotate(z + w.first, 33) * k1; + v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first); + w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16)); + std::swap(z, x); + s += 64; + len -= 64; + } while (len != 0); + return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z, + HashLen16(v.second, w.second) + x); +} + +uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed) { + return CityHash64WithSeeds(s, len, k2, seed); +} + +uint64 CityHash64WithSeeds(const char *s, size_t len, + uint64 seed0, uint64 seed1) { + return HashLen16(CityHash64(s, len) - seed0, seed1); +} + +// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings +// of any length representable in signed long. Based on City and Murmur. +static uint128 CityMurmur(const char *s, size_t len, uint128 seed) { + uint64 a = Uint128Low64(seed); + uint64 b = Uint128High64(seed); + uint64 c = 0; + uint64 d = 0; + signed long l = (signed long)len - 16; + if (l <= 0) { // len <= 16 + a = ShiftMix(a * k1) * k1; + c = b * k1 + HashLen0to16(s, len); + d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c)); + } else { // len > 16 + c = HashLen16(Fetch64(s + len - 8) + k1, a); + d = HashLen16(b + len, c + Fetch64(s + len - 16)); + a += d; + do { + a ^= ShiftMix(Fetch64(s) * k1) * k1; + a *= k1; + b ^= a; + c ^= ShiftMix(Fetch64(s + 8) * k1) * k1; + c *= k1; + d ^= c; + s += 16; + l -= 16; + } while (l > 0); + } + a = HashLen16(a, c); + b = HashLen16(d, b); + return uint128(a ^ b, HashLen16(b, a)); +} + +uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) { + if (len < 128) { + return CityMurmur(s, len, seed); + } + + // We expect len >= 128 to be the common case. Keep 56 bytes of state: + // v, w, x, y, and z. + pair v, w; + uint64 x = Uint128Low64(seed); + uint64 y = Uint128High64(seed); + uint64 z = len * k1; + v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s); + v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8); + w.first = Rotate(y + z, 35) * k1 + x; + w.second = Rotate(x + Fetch64(s + 88), 53) * k1; + + // This is the same inner loop as CityHash64(), manually unrolled. + do { + x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; + y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; + x ^= w.second; + y += v.first + Fetch64(s + 40); + z = Rotate(z + w.first, 33) * k1; + v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first); + w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16)); + std::swap(z, x); + s += 64; + x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; + y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; + x ^= w.second; + y += v.first + Fetch64(s + 40); + z = Rotate(z + w.first, 33) * k1; + v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first); + w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16)); + std::swap(z, x); + s += 64; + len -= 128; + } while (LIKELY(len >= 128)); + x += Rotate(v.first + z, 49) * k0; + y = y * k0 + Rotate(w.second, 37); + z = z * k0 + Rotate(w.first, 27); + w.first *= 9; + v.first *= k0; + // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s. + for (size_t tail_done = 0; tail_done < len; ) { + tail_done += 32; + y = Rotate(x + y, 42) * k0 + v.second; + w.first += Fetch64(s + len - tail_done + 16); + x = x * k0 + w.first; + z += w.second + Fetch64(s + len - tail_done); + w.second += v.first; + v = WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second); + v.first *= k0; + } + // At this point our 56 bytes of state should contain more than + // enough information for a strong 128-bit hash. We use two + // different 56-byte-to-8-byte hashes to get a 16-byte final result. + x = HashLen16(x, v.first); + y = HashLen16(y + z, w.first); + return uint128(HashLen16(x + v.second, w.second) + y, + HashLen16(x + w.second, y + v.second)); +} + +uint128 CityHash128(const char *s, size_t len) { + return len >= 16 ? + CityHash128WithSeed(s + 16, len - 16, + uint128(Fetch64(s), Fetch64(s + 8) + k0)) : + CityHash128WithSeed(s, len, uint128(k0, k1)); +} + +#ifdef __SSE4_2__ +#include "citycrc.h" +#include + +// Requires len >= 240. +static void CityHashCrc256Long(const char *s, size_t len, + uint32 seed, uint64 *result) { + uint64 a = Fetch64(s + 56) + k0; + uint64 b = Fetch64(s + 96) + k0; + uint64 c = result[0] = HashLen16(b, len); + uint64 d = result[1] = Fetch64(s + 120) * k0 + len; + uint64 e = Fetch64(s + 184) + seed; + uint64 f = 0; + uint64 g = 0; + uint64 h = c + d; + uint64 x = seed; + uint64 y = 0; + uint64 z = 0; + + // 240 bytes of input per iter. + size_t iters = len / 240; + len -= iters * 240; + do { +#undef CHUNK +#define CHUNK(r) \ + PERMUTE3(x, z, y); \ + b += Fetch64(s); \ + c += Fetch64(s + 8); \ + d += Fetch64(s + 16); \ + e += Fetch64(s + 24); \ + f += Fetch64(s + 32); \ + a += b; \ + h += f; \ + b += c; \ + f += d; \ + g += e; \ + e += z; \ + g += x; \ + z = _mm_crc32_u64(z, b + g); \ + y = _mm_crc32_u64(y, e + h); \ + x = _mm_crc32_u64(x, f + a); \ + e = Rotate(e, r); \ + c += e; \ + s += 40 + + CHUNK(0); PERMUTE3(a, h, c); + CHUNK(33); PERMUTE3(a, h, f); + CHUNK(0); PERMUTE3(b, h, f); + CHUNK(42); PERMUTE3(b, h, d); + CHUNK(0); PERMUTE3(b, h, e); + CHUNK(33); PERMUTE3(a, h, e); + } while (--iters > 0); + + while (len >= 40) { + CHUNK(29); + e ^= Rotate(a, 20); + h += Rotate(b, 30); + g ^= Rotate(c, 40); + f += Rotate(d, 34); + PERMUTE3(c, h, g); + len -= 40; + } + if (len > 0) { + s = s + len - 40; + CHUNK(33); + e ^= Rotate(a, 43); + h += Rotate(b, 42); + g ^= Rotate(c, 41); + f += Rotate(d, 40); + } + result[0] ^= h; + result[1] ^= g; + g += h; + a = HashLen16(a, g + z); + x += y << 32; + b += x; + c = HashLen16(c, z) + h; + d = HashLen16(d, e + result[0]); + g += e; + h += HashLen16(x, f); + e = HashLen16(a, d) + g; + z = HashLen16(b, c) + a; + y = HashLen16(g, h) + c; + result[0] = e + z + y + x; + a = ShiftMix((a + y) * k0) * k0 + b; + result[1] += a + result[0]; + a = ShiftMix(a * k0) * k0 + c; + result[2] = a + result[1]; + a = ShiftMix((a + e) * k0) * k0; + result[3] = a + result[2]; +} + +// Requires len < 240. +static void CityHashCrc256Short(const char *s, size_t len, uint64 *result) { + char buf[240]; + memcpy(buf, s, len); + memset(buf + len, 0, 240 - len); + CityHashCrc256Long(buf, 240, ~static_cast(len), result); +} + +void CityHashCrc256(const char *s, size_t len, uint64 *result) { + if (LIKELY(len >= 240)) { + CityHashCrc256Long(s, len, 0, result); + } else { + CityHashCrc256Short(s, len, result); + } +} + +uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) { + if (len <= 900) { + return CityHash128WithSeed(s, len, seed); + } else { + uint64 result[4]; + CityHashCrc256(s, len, result); + uint64 u = Uint128High64(seed) + result[0]; + uint64 v = Uint128Low64(seed) + result[1]; + return uint128(HashLen16(u, v + result[2]), + HashLen16(Rotate(v, 32), u * k0 + result[3])); + } +} + +uint128 CityHashCrc128(const char *s, size_t len) { + if (len <= 900) { + return CityHash128(s, len); + } else { + uint64 result[4]; + CityHashCrc256(s, len, result); + return uint128(result[2], result[3]); + } +} + +#endif diff --git a/ext/native/ext/cityhash/city.h b/ext/native/ext/cityhash/city.h new file mode 100644 index 0000000000..94499ce419 --- /dev/null +++ b/ext/native/ext/cityhash/city.h @@ -0,0 +1,112 @@ +// Copyright (c) 2011 Google, Inc. +// +// 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. +// +// CityHash, by Geoff Pike and Jyrki Alakuijala +// +// http://code.google.com/p/cityhash/ +// +// This file provides a few functions for hashing strings. All of them are +// high-quality functions in the sense that they pass standard tests such +// as Austin Appleby's SMHasher. They are also fast. +// +// For 64-bit x86 code, on short strings, we don't know of anything faster than +// CityHash64 that is of comparable quality. We believe our nearest competitor +// is Murmur3. For 64-bit x86 code, CityHash64 is an excellent choice for hash +// tables and most other hashing (excluding cryptography). +// +// For 64-bit x86 code, on long strings, the picture is more complicated. +// On many recent Intel CPUs, such as Nehalem, Westmere, Sandy Bridge, etc., +// CityHashCrc128 appears to be faster than all competitors of comparable +// quality. CityHash128 is also good but not quite as fast. We believe our +// nearest competitor is Bob Jenkins' Spooky. We don't have great data for +// other 64-bit CPUs, but for long strings we know that Spooky is slightly +// faster than CityHash on some relatively recent AMD x86-64 CPUs, for example. +// Note that CityHashCrc128 is declared in citycrc.h. +// +// For 32-bit x86 code, we don't know of anything faster than CityHash32 that +// is of comparable quality. We believe our nearest competitor is Murmur3A. +// (On 64-bit CPUs, it is typically faster to use the other CityHash variants.) +// +// Functions in the CityHash family are not suitable for cryptography. +// +// Please see CityHash's README file for more details on our performance +// measurements and so on. +// +// WARNING: This code has been only lightly tested on big-endian platforms! +// It is known to work well on little-endian platforms that have a small penalty +// for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs. +// It should work on all 32-bit and 64-bit platforms that allow unaligned reads; +// bug reports are welcome. +// +// By the way, for some hash functions, given strings a and b, the hash +// of a+b is easily derived from the hashes of a and b. This property +// doesn't hold for any hash functions in this file. + +#ifndef CITY_HASH_H_ +#define CITY_HASH_H_ + +#include // for size_t. +#include +#include + +typedef uint8_t uint8; +typedef uint32_t uint32; +typedef uint64_t uint64; +typedef std::pair uint128; + +inline uint64 Uint128Low64(const uint128& x) { return x.first; } +inline uint64 Uint128High64(const uint128& x) { return x.second; } + +// Hash function for a byte array. +uint64 CityHash64(const char *buf, size_t len); + +// Hash function for a byte array. For convenience, a 64-bit seed is also +// hashed into the result. +uint64 CityHash64WithSeed(const char *buf, size_t len, uint64 seed); + +// Hash function for a byte array. For convenience, two seeds are also +// hashed into the result. +uint64 CityHash64WithSeeds(const char *buf, size_t len, + uint64 seed0, uint64 seed1); + +// Hash function for a byte array. +uint128 CityHash128(const char *s, size_t len); + +// Hash function for a byte array. For convenience, a 128-bit seed is also +// hashed into the result. +uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed); + +// Hash function for a byte array. Most useful in 32-bit binaries. +uint32 CityHash32(const char *buf, size_t len); + +// Hash 128 input bits down to 64 bits of output. +// This is intended to be a reasonably good hash function. +inline uint64 Hash128to64(const uint128& x) { + // Murmur-inspired hashing. + const uint64 kMul = 0x9ddfea08eb382d69ULL; + uint64 a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul; + a ^= (a >> 47); + uint64 b = (Uint128High64(x) ^ a) * kMul; + b ^= (b >> 47); + b *= kMul; + return b; +} + +#endif // CITY_HASH_H_ diff --git a/ext/native/ext/cityhash/citycrc.h b/ext/native/ext/cityhash/citycrc.h new file mode 100644 index 0000000000..054d188a95 --- /dev/null +++ b/ext/native/ext/cityhash/citycrc.h @@ -0,0 +1,43 @@ +// Copyright (c) 2011 Google, Inc. +// +// 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. +// +// CityHash, by Geoff Pike and Jyrki Alakuijala +// +// This file declares the subset of the CityHash functions that require +// _mm_crc32_u64(). See the CityHash README for details. +// +// Functions in the CityHash family are not suitable for cryptography. + +#ifndef CITY_HASH_CRC_H_ +#define CITY_HASH_CRC_H_ + +#include "city.h" + +// Hash function for a byte array. +uint128 CityHashCrc128(const char *s, size_t len); + +// Hash function for a byte array. For convenience, a 128-bit seed is also +// hashed into the result. +uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed); + +// Hash function for a byte array. Sets result[0] ... result[3]. +void CityHashCrc256(const char *s, size_t len, uint64 *result); + +#endif // CITY_HASH_CRC_H_ diff --git a/ext/native/ext/glew/GL/glew.h b/ext/native/ext/glew/GL/glew.h new file mode 100644 index 0000000000..bee952d37d --- /dev/null +++ b/ext/native/ext/glew/GL/glew.h @@ -0,0 +1,18376 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2014, Nigel Stewart +** 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__) || defined(__X_GL_H) +#error gl.h included before glew.h +#endif +#if defined(__gl2_h_) +#error gl2.h included before glew.h +#endif +#if defined(__gltypes_h_) +#error gltypes.h included before glew.h +#endif +#if defined(__REGAL_H__) +#error Regal.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 __gl2_h_ +#define __GL_H__ +#define __gltypes_h_ +#define __REGAL_H__ +#define __X_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. + */ +/* and */ +#ifdef APIENTRY +# ifndef GLAPIENTRY +# define GLAPIENTRY APIENTRY +# endif +# ifndef GLEWAPIENTRY +# define GLEWAPIENTRY APIENTRY +# endif +#else +#define GLEW_APIENTRY_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN__) || (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) +# define APIENTRY __stdcall +# ifndef GLAPIENTRY +# define GLAPIENTRY __stdcall +# endif +# ifndef GLEWAPIENTRY +# define GLEWAPIENTRY __stdcall +# endif +# else +# define APIENTRY +# endif +#endif +#ifndef GLAPI +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define GLAPI extern +# endif +#endif +/* */ +#ifndef CALLBACK +#define GLEW_CALLBACK_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN__) +# 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_) && !defined(__MINGW64__) +# 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__) || defined(__CYGWIN__) +# define GLAPI extern +# else +# define GLAPI WINGDIAPI +# endif +#endif + +/* + * GLEW_STATIC is defined for static library. + * GLEW_BUILD is defined for building the DLL library. + */ + +#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 + +/* SGI MIPSPro doesn't like stdint.h in C++ mode */ +/* ID: 3376260 Solaris 9 has inttypes.h, but not stdint.h */ + +#if (defined(__sgi) || defined(__sun)) && !defined(__GNUC__) +#include +#else +#include +#endif + +#define GLEW_APIENTRY_DEFINED +#define APIENTRY + +/* + * GLEW_STATIC is defined for static library. + */ + +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# if defined(__GNUC__) && __GNUC__>=4 +# define GLEWAPI extern __attribute__ ((visibility("default"))) +# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# define GLEWAPI extern __global +# else +# define GLEWAPI extern +# endif +#endif + +/* */ +#ifndef GLAPI +#define GLAPI extern +#endif + +#endif /* _WIN32 */ + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifndef GLEWAPIENTRY +#define GLEWAPIENTRY +#endif + +#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) && _MSC_VER < 1400 +typedef __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +#elif defined(_MSC_VER) || defined(__BORLANDC__) +typedef signed long long GLint64EXT; +typedef unsigned long long GLuint64EXT; +#else +# if defined(__MINGW32__) || defined(__CYGWIN__) +#include +# endif +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif +typedef GLint64EXT GLint64; +typedef GLuint64EXT GLuint64; +typedef struct __GLsync *GLsync; + +typedef char GLchar; + +#define GL_ZERO 0 +#define GL_FALSE 0 +#define GL_LOGIC_OP 0x0BF1 +#define GL_NONE 0 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_NO_ERROR 0 +#define GL_POINTS 0x0000 +#define GL_CURRENT_BIT 0x00000001 +#define GL_TRUE 1 +#define GL_ONE 1 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_POINT_BIT 0x00000002 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_BIT 0x00000004 +#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_BIT 0x00000008 +#define GL_POLYGON 0x0009 +#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 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_NEVER 0x0200 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#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_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_STENCIL_BUFFER_BIT 0x00000400 +#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_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_VIEWPORT_BIT 0x00000800 +#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_TRANSFORM_BIT 0x00001000 +#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_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_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_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_ENABLE_BIT 0x00002000 +#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_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_R3_G3_B2 0x2A10 +#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_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_LIGHT0 0x4000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#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_HINT_BIT 0x00008000 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#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_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_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_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_CLIENT_ALL_ATTRIB_BITS 0xffffffff + +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 void *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 void *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 void *indices); +GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); +GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const void *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, void* *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, void *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 void *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 void *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 void *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, void *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 void *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 void *pixels); +GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *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 void *pixels); +GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *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 void *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 ---------------------------------- */ + +#ifndef GLEW_NO_GLU +# ifdef __APPLE__ +# include +# if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +# define GLEW_NO_GLU +# endif +# endif +#endif + +#ifndef GLEW_NO_GLU +/* this is where we can safely include GLU */ +# if defined(__APPLE__) && defined(__MACH__) +# include +# else +# include +# endif +#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_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 void *indices); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *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 void *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_2_1 --------------------------- */ + +#ifndef GL_VERSION_1_2_1 +#define GL_VERSION_1_2_1 1 + +#define GLEW_VERSION_1_2_1 GLEW_GET_VAR(__GLEW_VERSION_1_2_1) + +#endif /* GL_VERSION_1_2_1 */ + +/* ----------------------------- 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 void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *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 void *data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, void *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 void *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, const GLint *first, const GLsizei *count, GLsizei drawcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const* indices, GLsizei drawcount); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const 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, const void *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_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC1_RGB GL_SOURCE1_RGB +#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 GLintptr; +typedef ptrdiff_t GLsizeiptr; + +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 void* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void* 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, void** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void* 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 void* (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 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) (GLuint 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, void**); +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 *const* string, const GLint* length); +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 void* 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_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#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_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_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 * 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 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, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); +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 GLchar *const*, 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 void*); + +#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender) +#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback) +#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 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_VERSION_3_1 ---------------------------- */ + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 + +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum, GLint, GLsizei, GLsizei); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum, GLsizei, GLenum, const void*, GLsizei); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum, GLenum, GLuint); + +#define glDrawArraysInstanced GLEW_GET_FUN(__glewDrawArraysInstanced) +#define glDrawElementsInstanced GLEW_GET_FUN(__glewDrawElementsInstanced) +#define glPrimitiveRestartIndex GLEW_GET_FUN(__glewPrimitiveRestartIndex) +#define glTexBuffer GLEW_GET_FUN(__glewTexBuffer) + +#define GLEW_VERSION_3_1 GLEW_GET_VAR(__GLEW_VERSION_3_1) + +#endif /* GL_VERSION_3_1 */ + +/* ----------------------------- GL_VERSION_3_2 ---------------------------- */ + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 + +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum, GLenum, GLuint, GLint); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum, GLenum, GLint64 *); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum, GLuint, GLint64 *); + +#define glFramebufferTexture GLEW_GET_FUN(__glewFramebufferTexture) +#define glGetBufferParameteri64v GLEW_GET_FUN(__glewGetBufferParameteri64v) +#define glGetInteger64i_v GLEW_GET_FUN(__glewGetInteger64i_v) + +#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2) + +#endif /* GL_VERSION_3_2 */ + +/* ----------------------------- GL_VERSION_3_3 ---------------------------- */ + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_RGB10_A2UI 0x906F + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); + +#define glVertexAttribDivisor GLEW_GET_FUN(__glewVertexAttribDivisor) + +#define GLEW_VERSION_3_3 GLEW_GET_VAR(__GLEW_VERSION_3_3) + +#endif /* GL_VERSION_3_3 */ + +/* ----------------------------- GL_VERSION_4_0 ---------------------------- */ + +#ifndef GL_VERSION_4_0 +#define GL_VERSION_4_0 1 + +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value); + +#define glBlendEquationSeparatei GLEW_GET_FUN(__glewBlendEquationSeparatei) +#define glBlendEquationi GLEW_GET_FUN(__glewBlendEquationi) +#define glBlendFuncSeparatei GLEW_GET_FUN(__glewBlendFuncSeparatei) +#define glBlendFunci GLEW_GET_FUN(__glewBlendFunci) +#define glMinSampleShading GLEW_GET_FUN(__glewMinSampleShading) + +#define GLEW_VERSION_4_0 GLEW_GET_VAR(__GLEW_VERSION_4_0) + +#endif /* GL_VERSION_4_0 */ + +/* ----------------------------- GL_VERSION_4_1 ---------------------------- */ + +#ifndef GL_VERSION_4_1 +#define GL_VERSION_4_1 1 + +#define GLEW_VERSION_4_1 GLEW_GET_VAR(__GLEW_VERSION_4_1) + +#endif /* GL_VERSION_4_1 */ + +/* ----------------------------- GL_VERSION_4_2 ---------------------------- */ + +#ifndef GL_VERSION_4_2 +#define GL_VERSION_4_2 1 + +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F + +#define GLEW_VERSION_4_2 GLEW_GET_VAR(__GLEW_VERSION_4_2) + +#endif /* GL_VERSION_4_2 */ + +/* ----------------------------- GL_VERSION_4_3 ---------------------------- */ + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 1 + +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E + +#define GLEW_VERSION_4_3 GLEW_GET_VAR(__GLEW_VERSION_4_3) + +#endif /* GL_VERSION_4_3 */ + +/* ----------------------------- GL_VERSION_4_4 ---------------------------- */ + +#ifndef GL_VERSION_4_4 +#define GL_VERSION_4_4 1 + +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A + +#define GLEW_VERSION_4_4 GLEW_GET_VAR(__GLEW_VERSION_4_4) + +#endif /* GL_VERSION_4_4 */ + +/* -------------------------- 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_AMD_blend_minmax_factor ---------------------- */ + +#ifndef GL_AMD_blend_minmax_factor +#define GL_AMD_blend_minmax_factor 1 + +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FACTOR_MAX_AMD 0x901D + +#define GLEW_AMD_blend_minmax_factor GLEW_GET_VAR(__GLEW_AMD_blend_minmax_factor) + +#endif /* GL_AMD_blend_minmax_factor */ + +/* ----------------------- GL_AMD_conservative_depth ----------------------- */ + +#ifndef GL_AMD_conservative_depth +#define GL_AMD_conservative_depth 1 + +#define GLEW_AMD_conservative_depth GLEW_GET_VAR(__GLEW_AMD_conservative_depth) + +#endif /* GL_AMD_conservative_depth */ + +/* -------------------------- GL_AMD_debug_output -------------------------- */ + +#ifndef GL_AMD_debug_output +#define GL_AMD_debug_output 1 + +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 + +typedef void (GLAPIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, void* userParam); + +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf); +typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message); + +#define glDebugMessageCallbackAMD GLEW_GET_FUN(__glewDebugMessageCallbackAMD) +#define glDebugMessageEnableAMD GLEW_GET_FUN(__glewDebugMessageEnableAMD) +#define glDebugMessageInsertAMD GLEW_GET_FUN(__glewDebugMessageInsertAMD) +#define glGetDebugMessageLogAMD GLEW_GET_FUN(__glewGetDebugMessageLogAMD) + +#define GLEW_AMD_debug_output GLEW_GET_VAR(__GLEW_AMD_debug_output) + +#endif /* GL_AMD_debug_output */ + +/* ---------------------- GL_AMD_depth_clamp_separate ---------------------- */ + +#ifndef GL_AMD_depth_clamp_separate +#define GL_AMD_depth_clamp_separate 1 + +#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E +#define GL_DEPTH_CLAMP_FAR_AMD 0x901F + +#define GLEW_AMD_depth_clamp_separate GLEW_GET_VAR(__GLEW_AMD_depth_clamp_separate) + +#endif /* GL_AMD_depth_clamp_separate */ + +/* ----------------------- GL_AMD_draw_buffers_blend ----------------------- */ + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + +#define glBlendEquationIndexedAMD GLEW_GET_FUN(__glewBlendEquationIndexedAMD) +#define glBlendEquationSeparateIndexedAMD GLEW_GET_FUN(__glewBlendEquationSeparateIndexedAMD) +#define glBlendFuncIndexedAMD GLEW_GET_FUN(__glewBlendFuncIndexedAMD) +#define glBlendFuncSeparateIndexedAMD GLEW_GET_FUN(__glewBlendFuncSeparateIndexedAMD) + +#define GLEW_AMD_draw_buffers_blend GLEW_GET_VAR(__GLEW_AMD_draw_buffers_blend) + +#endif /* GL_AMD_draw_buffers_blend */ + +/* --------------------------- GL_AMD_gcn_shader --------------------------- */ + +#ifndef GL_AMD_gcn_shader +#define GL_AMD_gcn_shader 1 + +#define GLEW_AMD_gcn_shader GLEW_GET_VAR(__GLEW_AMD_gcn_shader) + +#endif /* GL_AMD_gcn_shader */ + +/* ------------------------ GL_AMD_gpu_shader_int64 ------------------------ */ + +#ifndef GL_AMD_gpu_shader_int64 +#define GL_AMD_gpu_shader_int64 1 + +#define GLEW_AMD_gpu_shader_int64 GLEW_GET_VAR(__GLEW_AMD_gpu_shader_int64) + +#endif /* GL_AMD_gpu_shader_int64 */ + +/* ---------------------- GL_AMD_interleaved_elements ---------------------- */ + +#ifndef GL_AMD_interleaved_elements +#define GL_AMD_interleaved_elements 1 + +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RG8UI 0x8238 +#define GL_RG16UI 0x823A +#define GL_RGBA8UI 0x8D7C +#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 +#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param); + +#define glVertexAttribParameteriAMD GLEW_GET_FUN(__glewVertexAttribParameteriAMD) + +#define GLEW_AMD_interleaved_elements GLEW_GET_VAR(__GLEW_AMD_interleaved_elements) + +#endif /* GL_AMD_interleaved_elements */ + +/* ----------------------- GL_AMD_multi_draw_indirect ---------------------- */ + +#ifndef GL_AMD_multi_draw_indirect +#define GL_AMD_multi_draw_indirect 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); + +#define glMultiDrawArraysIndirectAMD GLEW_GET_FUN(__glewMultiDrawArraysIndirectAMD) +#define glMultiDrawElementsIndirectAMD GLEW_GET_FUN(__glewMultiDrawElementsIndirectAMD) + +#define GLEW_AMD_multi_draw_indirect GLEW_GET_VAR(__GLEW_AMD_multi_draw_indirect) + +#endif /* GL_AMD_multi_draw_indirect */ + +/* ------------------------- GL_AMD_name_gen_delete ------------------------ */ + +#ifndef GL_AMD_name_gen_delete +#define GL_AMD_name_gen_delete 1 + +#define GL_DATA_BUFFER_AMD 0x9151 +#define GL_PERFORMANCE_MONITOR_AMD 0x9152 +#define GL_QUERY_OBJECT_AMD 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 +#define GL_SAMPLER_OBJECT_AMD 0x9155 + +typedef void (GLAPIENTRY * PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint* names); +typedef void (GLAPIENTRY * PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint* names); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); + +#define glDeleteNamesAMD GLEW_GET_FUN(__glewDeleteNamesAMD) +#define glGenNamesAMD GLEW_GET_FUN(__glewGenNamesAMD) +#define glIsNameAMD GLEW_GET_FUN(__glewIsNameAMD) + +#define GLEW_AMD_name_gen_delete GLEW_GET_VAR(__GLEW_AMD_name_gen_delete) + +#endif /* GL_AMD_name_gen_delete */ + +/* ---------------------- GL_AMD_occlusion_query_event --------------------- */ + +#ifndef GL_AMD_occlusion_query_event +#define GL_AMD_occlusion_query_event 1 + +#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 +#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 +#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 +#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 +#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F +#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param); + +#define glQueryObjectParameteruiAMD GLEW_GET_FUN(__glewQueryObjectParameteruiAMD) + +#define GLEW_AMD_occlusion_query_event GLEW_GET_VAR(__GLEW_AMD_occlusion_query_event) + +#endif /* GL_AMD_occlusion_query_event */ + +/* ----------------------- GL_AMD_performance_monitor ---------------------- */ + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 + +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 + +typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); +typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar *counterString); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, GLchar *groupString); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList); + +#define glBeginPerfMonitorAMD GLEW_GET_FUN(__glewBeginPerfMonitorAMD) +#define glDeletePerfMonitorsAMD GLEW_GET_FUN(__glewDeletePerfMonitorsAMD) +#define glEndPerfMonitorAMD GLEW_GET_FUN(__glewEndPerfMonitorAMD) +#define glGenPerfMonitorsAMD GLEW_GET_FUN(__glewGenPerfMonitorsAMD) +#define glGetPerfMonitorCounterDataAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterDataAMD) +#define glGetPerfMonitorCounterInfoAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterInfoAMD) +#define glGetPerfMonitorCounterStringAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterStringAMD) +#define glGetPerfMonitorCountersAMD GLEW_GET_FUN(__glewGetPerfMonitorCountersAMD) +#define glGetPerfMonitorGroupStringAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupStringAMD) +#define glGetPerfMonitorGroupsAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupsAMD) +#define glSelectPerfMonitorCountersAMD GLEW_GET_FUN(__glewSelectPerfMonitorCountersAMD) + +#define GLEW_AMD_performance_monitor GLEW_GET_VAR(__GLEW_AMD_performance_monitor) + +#endif /* GL_AMD_performance_monitor */ + +/* -------------------------- GL_AMD_pinned_memory ------------------------- */ + +#ifndef GL_AMD_pinned_memory +#define GL_AMD_pinned_memory 1 + +#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 + +#define GLEW_AMD_pinned_memory GLEW_GET_VAR(__GLEW_AMD_pinned_memory) + +#endif /* GL_AMD_pinned_memory */ + +/* ----------------------- GL_AMD_query_buffer_object ---------------------- */ + +#ifndef GL_AMD_query_buffer_object +#define GL_AMD_query_buffer_object 1 + +#define GL_QUERY_BUFFER_AMD 0x9192 +#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 +#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 + +#define GLEW_AMD_query_buffer_object GLEW_GET_VAR(__GLEW_AMD_query_buffer_object) + +#endif /* GL_AMD_query_buffer_object */ + +/* ------------------------ GL_AMD_sample_positions ------------------------ */ + +#ifndef GL_AMD_sample_positions +#define GL_AMD_sample_positions 1 + +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F + +typedef void (GLAPIENTRY * PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat* val); + +#define glSetMultisamplefvAMD GLEW_GET_FUN(__glewSetMultisamplefvAMD) + +#define GLEW_AMD_sample_positions GLEW_GET_VAR(__GLEW_AMD_sample_positions) + +#endif /* GL_AMD_sample_positions */ + +/* ------------------ GL_AMD_seamless_cubemap_per_texture ------------------ */ + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS_ARB 0x884F + +#define GLEW_AMD_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_AMD_seamless_cubemap_per_texture) + +#endif /* GL_AMD_seamless_cubemap_per_texture */ + +/* -------------------- GL_AMD_shader_atomic_counter_ops ------------------- */ + +#ifndef GL_AMD_shader_atomic_counter_ops +#define GL_AMD_shader_atomic_counter_ops 1 + +#define GLEW_AMD_shader_atomic_counter_ops GLEW_GET_VAR(__GLEW_AMD_shader_atomic_counter_ops) + +#endif /* GL_AMD_shader_atomic_counter_ops */ + +/* ---------------------- GL_AMD_shader_stencil_export --------------------- */ + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export 1 + +#define GLEW_AMD_shader_stencil_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_export) + +#endif /* GL_AMD_shader_stencil_export */ + +/* ------------------- GL_AMD_shader_stencil_value_export ------------------ */ + +#ifndef GL_AMD_shader_stencil_value_export +#define GL_AMD_shader_stencil_value_export 1 + +#define GLEW_AMD_shader_stencil_value_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_value_export) + +#endif /* GL_AMD_shader_stencil_value_export */ + +/* ---------------------- GL_AMD_shader_trinary_minmax --------------------- */ + +#ifndef GL_AMD_shader_trinary_minmax +#define GL_AMD_shader_trinary_minmax 1 + +#define GLEW_AMD_shader_trinary_minmax GLEW_GET_VAR(__GLEW_AMD_shader_trinary_minmax) + +#endif /* GL_AMD_shader_trinary_minmax */ + +/* ------------------------- GL_AMD_sparse_texture ------------------------- */ + +#ifndef GL_AMD_sparse_texture +#define GL_AMD_sparse_texture 1 + +#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 +#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A +#define GL_MIN_SPARSE_LEVEL_AMD 0x919B +#define GL_MIN_LOD_WARNING_AMD 0x919C + +typedef void (GLAPIENTRY * PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); + +#define glTexStorageSparseAMD GLEW_GET_FUN(__glewTexStorageSparseAMD) +#define glTextureStorageSparseAMD GLEW_GET_FUN(__glewTextureStorageSparseAMD) + +#define GLEW_AMD_sparse_texture GLEW_GET_VAR(__GLEW_AMD_sparse_texture) + +#endif /* GL_AMD_sparse_texture */ + +/* ------------------- GL_AMD_stencil_operation_extended ------------------- */ + +#ifndef GL_AMD_stencil_operation_extended +#define GL_AMD_stencil_operation_extended 1 + +#define GL_SET_AMD 0x874A +#define GL_REPLACE_VALUE_AMD 0x874B +#define GL_STENCIL_OP_VALUE_AMD 0x874C +#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D + +typedef void (GLAPIENTRY * PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); + +#define glStencilOpValueAMD GLEW_GET_FUN(__glewStencilOpValueAMD) + +#define GLEW_AMD_stencil_operation_extended GLEW_GET_VAR(__GLEW_AMD_stencil_operation_extended) + +#endif /* GL_AMD_stencil_operation_extended */ + +/* ------------------------ GL_AMD_texture_texture4 ------------------------ */ + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 1 + +#define GLEW_AMD_texture_texture4 GLEW_GET_VAR(__GLEW_AMD_texture_texture4) + +#endif /* GL_AMD_texture_texture4 */ + +/* --------------- GL_AMD_transform_feedback3_lines_triangles -------------- */ + +#ifndef GL_AMD_transform_feedback3_lines_triangles +#define GL_AMD_transform_feedback3_lines_triangles 1 + +#define GLEW_AMD_transform_feedback3_lines_triangles GLEW_GET_VAR(__GLEW_AMD_transform_feedback3_lines_triangles) + +#endif /* GL_AMD_transform_feedback3_lines_triangles */ + +/* ----------------------- GL_AMD_transform_feedback4 ---------------------- */ + +#ifndef GL_AMD_transform_feedback4 +#define GL_AMD_transform_feedback4 1 + +#define GL_STREAM_RASTERIZATION_AMD 0x91A0 + +#define GLEW_AMD_transform_feedback4 GLEW_GET_VAR(__GLEW_AMD_transform_feedback4) + +#endif /* GL_AMD_transform_feedback4 */ + +/* ----------------------- GL_AMD_vertex_shader_layer ---------------------- */ + +#ifndef GL_AMD_vertex_shader_layer +#define GL_AMD_vertex_shader_layer 1 + +#define GLEW_AMD_vertex_shader_layer GLEW_GET_VAR(__GLEW_AMD_vertex_shader_layer) + +#endif /* GL_AMD_vertex_shader_layer */ + +/* -------------------- GL_AMD_vertex_shader_tessellator ------------------- */ + +#ifndef GL_AMD_vertex_shader_tessellator +#define GL_AMD_vertex_shader_tessellator 1 + +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_DISCRETE_AMD 0x9006 +#define GL_CONTINUOUS_AMD 0x9007 + +typedef void (GLAPIENTRY * PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); + +#define glTessellationFactorAMD GLEW_GET_FUN(__glewTessellationFactorAMD) +#define glTessellationModeAMD GLEW_GET_FUN(__glewTessellationModeAMD) + +#define GLEW_AMD_vertex_shader_tessellator GLEW_GET_VAR(__GLEW_AMD_vertex_shader_tessellator) + +#endif /* GL_AMD_vertex_shader_tessellator */ + +/* ------------------ GL_AMD_vertex_shader_viewport_index ------------------ */ + +#ifndef GL_AMD_vertex_shader_viewport_index +#define GL_AMD_vertex_shader_viewport_index 1 + +#define GLEW_AMD_vertex_shader_viewport_index GLEW_GET_VAR(__GLEW_AMD_vertex_shader_viewport_index) + +#endif /* GL_AMD_vertex_shader_viewport_index */ + +/* ------------------------- GL_ANGLE_depth_texture ------------------------ */ + +#ifndef GL_ANGLE_depth_texture +#define GL_ANGLE_depth_texture 1 + +#define GLEW_ANGLE_depth_texture GLEW_GET_VAR(__GLEW_ANGLE_depth_texture) + +#endif /* GL_ANGLE_depth_texture */ + +/* ----------------------- GL_ANGLE_framebuffer_blit ----------------------- */ + +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferANGLE GLEW_GET_FUN(__glewBlitFramebufferANGLE) + +#define GLEW_ANGLE_framebuffer_blit GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_blit) + +#endif /* GL_ANGLE_framebuffer_blit */ + +/* -------------------- GL_ANGLE_framebuffer_multisample ------------------- */ + +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 + +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleANGLE GLEW_GET_FUN(__glewRenderbufferStorageMultisampleANGLE) + +#define GLEW_ANGLE_framebuffer_multisample GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_multisample) + +#endif /* GL_ANGLE_framebuffer_multisample */ + +/* ----------------------- GL_ANGLE_instanced_arrays ----------------------- */ + +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); + +#define glDrawArraysInstancedANGLE GLEW_GET_FUN(__glewDrawArraysInstancedANGLE) +#define glDrawElementsInstancedANGLE GLEW_GET_FUN(__glewDrawElementsInstancedANGLE) +#define glVertexAttribDivisorANGLE GLEW_GET_FUN(__glewVertexAttribDivisorANGLE) + +#define GLEW_ANGLE_instanced_arrays GLEW_GET_VAR(__GLEW_ANGLE_instanced_arrays) + +#endif /* GL_ANGLE_instanced_arrays */ + +/* -------------------- GL_ANGLE_pack_reverse_row_order -------------------- */ + +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 + +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 + +#define GLEW_ANGLE_pack_reverse_row_order GLEW_GET_VAR(__GLEW_ANGLE_pack_reverse_row_order) + +#endif /* GL_ANGLE_pack_reverse_row_order */ + +/* ------------------------ GL_ANGLE_program_binary ------------------------ */ + +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 + +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 + +#define GLEW_ANGLE_program_binary GLEW_GET_VAR(__GLEW_ANGLE_program_binary) + +#endif /* GL_ANGLE_program_binary */ + +/* ------------------- GL_ANGLE_texture_compression_dxt1 ------------------- */ + +#ifndef GL_ANGLE_texture_compression_dxt1 +#define GL_ANGLE_texture_compression_dxt1 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 + +#define GLEW_ANGLE_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt1) + +#endif /* GL_ANGLE_texture_compression_dxt1 */ + +/* ------------------- GL_ANGLE_texture_compression_dxt3 ------------------- */ + +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 + +#define GLEW_ANGLE_texture_compression_dxt3 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt3) + +#endif /* GL_ANGLE_texture_compression_dxt3 */ + +/* ------------------- GL_ANGLE_texture_compression_dxt5 ------------------- */ + +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 + +#define GLEW_ANGLE_texture_compression_dxt5 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt5) + +#endif /* GL_ANGLE_texture_compression_dxt5 */ + +/* ------------------------- GL_ANGLE_texture_usage ------------------------ */ + +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 + +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 + +#define GLEW_ANGLE_texture_usage GLEW_GET_VAR(__GLEW_ANGLE_texture_usage) + +#endif /* GL_ANGLE_texture_usage */ + +/* -------------------------- GL_ANGLE_timer_query ------------------------- */ + +#ifndef GL_ANGLE_timer_query +#define GL_ANGLE_timer_query 1 + +#define GL_QUERY_COUNTER_BITS_ANGLE 0x8864 +#define GL_CURRENT_QUERY_ANGLE 0x8865 +#define GL_QUERY_RESULT_ANGLE 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ANGLE 0x8867 +#define GL_TIME_ELAPSED_ANGLE 0x88BF +#define GL_TIMESTAMP_ANGLE 0x8E28 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYANGLEPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESANGLEPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYANGLEPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENQUERIESANGLEPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VANGLEPROC) (GLuint id, GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVANGLEPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VANGLEPROC) (GLuint id, GLenum pname, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVANGLEPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVANGLEPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYANGLEPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERANGLEPROC) (GLuint id, GLenum target); + +#define glBeginQueryANGLE GLEW_GET_FUN(__glewBeginQueryANGLE) +#define glDeleteQueriesANGLE GLEW_GET_FUN(__glewDeleteQueriesANGLE) +#define glEndQueryANGLE GLEW_GET_FUN(__glewEndQueryANGLE) +#define glGenQueriesANGLE GLEW_GET_FUN(__glewGenQueriesANGLE) +#define glGetQueryObjecti64vANGLE GLEW_GET_FUN(__glewGetQueryObjecti64vANGLE) +#define glGetQueryObjectivANGLE GLEW_GET_FUN(__glewGetQueryObjectivANGLE) +#define glGetQueryObjectui64vANGLE GLEW_GET_FUN(__glewGetQueryObjectui64vANGLE) +#define glGetQueryObjectuivANGLE GLEW_GET_FUN(__glewGetQueryObjectuivANGLE) +#define glGetQueryivANGLE GLEW_GET_FUN(__glewGetQueryivANGLE) +#define glIsQueryANGLE GLEW_GET_FUN(__glewIsQueryANGLE) +#define glQueryCounterANGLE GLEW_GET_FUN(__glewQueryCounterANGLE) + +#define GLEW_ANGLE_timer_query GLEW_GET_VAR(__GLEW_ANGLE_timer_query) + +#endif /* GL_ANGLE_timer_query */ + +/* ------------------- GL_ANGLE_translated_shader_source ------------------- */ + +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 + +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 + +typedef void (GLAPIENTRY * PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); + +#define glGetTranslatedShaderSourceANGLE GLEW_GET_FUN(__glewGetTranslatedShaderSourceANGLE) + +#define GLEW_ANGLE_translated_shader_source GLEW_GET_VAR(__GLEW_ANGLE_translated_shader_source) + +#endif /* GL_ANGLE_translated_shader_source */ + +/* ----------------------- GL_APPLE_aux_depth_stencil ---------------------- */ + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil 1 + +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 + +#define GLEW_APPLE_aux_depth_stencil GLEW_GET_VAR(__GLEW_APPLE_aux_depth_stencil) + +#endif /* GL_APPLE_aux_depth_stencil */ + +/* ------------------------ 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 0x8A0C +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E + +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_object_purgeable ----------------------- */ + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable 1 + +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D + +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params); +typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); + +#define glGetObjectParameterivAPPLE GLEW_GET_FUN(__glewGetObjectParameterivAPPLE) +#define glObjectPurgeableAPPLE GLEW_GET_FUN(__glewObjectPurgeableAPPLE) +#define glObjectUnpurgeableAPPLE GLEW_GET_FUN(__glewObjectUnpurgeableAPPLE) + +#define GLEW_APPLE_object_purgeable GLEW_GET_VAR(__GLEW_APPLE_object_purgeable) + +#endif /* GL_APPLE_object_purgeable */ + +/* ------------------------- 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_rgb_422 --------------------------- */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 + +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_422_APPLE 0x8A1F +#define GL_RGB_RAW_422_APPLE 0x8A51 + +#define GLEW_APPLE_rgb_422 GLEW_GET_VAR(__GLEW_APPLE_rgb_422) + +#endif /* GL_APPLE_rgb_422 */ + +/* --------------------------- GL_APPLE_row_bytes -------------------------- */ + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes 1 + +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 + +#define GLEW_APPLE_row_bytes GLEW_GET_VAR(__GLEW_APPLE_row_bytes) + +#endif /* GL_APPLE_row_bytes */ + +/* ------------------------ 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, void **params); +typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, void *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_CLIENT_APPLE 0x85B4 +#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_vertex_program_evaluators ------------------ */ + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators 1 + +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 + +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points); + +#define glDisableVertexAttribAPPLE GLEW_GET_FUN(__glewDisableVertexAttribAPPLE) +#define glEnableVertexAttribAPPLE GLEW_GET_FUN(__glewEnableVertexAttribAPPLE) +#define glIsVertexAttribEnabledAPPLE GLEW_GET_FUN(__glewIsVertexAttribEnabledAPPLE) +#define glMapVertexAttrib1dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1dAPPLE) +#define glMapVertexAttrib1fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1fAPPLE) +#define glMapVertexAttrib2dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2dAPPLE) +#define glMapVertexAttrib2fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2fAPPLE) + +#define GLEW_APPLE_vertex_program_evaluators GLEW_GET_VAR(__GLEW_APPLE_vertex_program_evaluators) + +#endif /* GL_APPLE_vertex_program_evaluators */ + +/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 + +#define GL_YCBCR_422_APPLE 0x85B9 + +#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) + +#endif /* GL_APPLE_ycbcr_422 */ + +/* ------------------------ GL_ARB_ES2_compatibility ----------------------- */ + +#ifndef GL_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 + +#define GL_FIXED 0x140C +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_RGB565 0x8D62 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD + +typedef int GLfixed; + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf d); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f); +typedef void (GLAPIENTRY * PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint *precision); +typedef void (GLAPIENTRY * PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (GLAPIENTRY * PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint* shaders, GLenum binaryformat, const void*binary, GLsizei length); + +#define glClearDepthf GLEW_GET_FUN(__glewClearDepthf) +#define glDepthRangef GLEW_GET_FUN(__glewDepthRangef) +#define glGetShaderPrecisionFormat GLEW_GET_FUN(__glewGetShaderPrecisionFormat) +#define glReleaseShaderCompiler GLEW_GET_FUN(__glewReleaseShaderCompiler) +#define glShaderBinary GLEW_GET_FUN(__glewShaderBinary) + +#define GLEW_ARB_ES2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES2_compatibility) + +#endif /* GL_ARB_ES2_compatibility */ + +/* ------------------------ GL_ARB_ES3_compatibility ----------------------- */ + +#ifndef GL_ARB_ES3_compatibility +#define GL_ARB_ES3_compatibility 1 + +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 + +#define GLEW_ARB_ES3_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_compatibility) + +#endif /* GL_ARB_ES3_compatibility */ + +/* ------------------------ GL_ARB_arrays_of_arrays ------------------------ */ + +#ifndef GL_ARB_arrays_of_arrays +#define GL_ARB_arrays_of_arrays 1 + +#define GLEW_ARB_arrays_of_arrays GLEW_GET_VAR(__GLEW_ARB_arrays_of_arrays) + +#endif /* GL_ARB_arrays_of_arrays */ + +/* -------------------------- GL_ARB_base_instance ------------------------- */ + +#ifndef GL_ARB_base_instance +#define GL_ARB_base_instance 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance); + +#define glDrawArraysInstancedBaseInstance GLEW_GET_FUN(__glewDrawArraysInstancedBaseInstance) +#define glDrawElementsInstancedBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseInstance) +#define glDrawElementsInstancedBaseVertexBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexBaseInstance) + +#define GLEW_ARB_base_instance GLEW_GET_VAR(__GLEW_ARB_base_instance) + +#endif /* GL_ARB_base_instance */ + +/* ------------------------ GL_ARB_bindless_texture ------------------------ */ + +#ifndef GL_ARB_bindless_texture +#define GL_ARB_bindless_texture 1 + +#define GL_UNSIGNED_INT64_ARB 0x140F + +typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); +typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT* params); +typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); +typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values); +typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); +typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT* v); + +#define glGetImageHandleARB GLEW_GET_FUN(__glewGetImageHandleARB) +#define glGetTextureHandleARB GLEW_GET_FUN(__glewGetTextureHandleARB) +#define glGetTextureSamplerHandleARB GLEW_GET_FUN(__glewGetTextureSamplerHandleARB) +#define glGetVertexAttribLui64vARB GLEW_GET_FUN(__glewGetVertexAttribLui64vARB) +#define glIsImageHandleResidentARB GLEW_GET_FUN(__glewIsImageHandleResidentARB) +#define glIsTextureHandleResidentARB GLEW_GET_FUN(__glewIsTextureHandleResidentARB) +#define glMakeImageHandleNonResidentARB GLEW_GET_FUN(__glewMakeImageHandleNonResidentARB) +#define glMakeImageHandleResidentARB GLEW_GET_FUN(__glewMakeImageHandleResidentARB) +#define glMakeTextureHandleNonResidentARB GLEW_GET_FUN(__glewMakeTextureHandleNonResidentARB) +#define glMakeTextureHandleResidentARB GLEW_GET_FUN(__glewMakeTextureHandleResidentARB) +#define glProgramUniformHandleui64ARB GLEW_GET_FUN(__glewProgramUniformHandleui64ARB) +#define glProgramUniformHandleui64vARB GLEW_GET_FUN(__glewProgramUniformHandleui64vARB) +#define glUniformHandleui64ARB GLEW_GET_FUN(__glewUniformHandleui64ARB) +#define glUniformHandleui64vARB GLEW_GET_FUN(__glewUniformHandleui64vARB) +#define glVertexAttribL1ui64ARB GLEW_GET_FUN(__glewVertexAttribL1ui64ARB) +#define glVertexAttribL1ui64vARB GLEW_GET_FUN(__glewVertexAttribL1ui64vARB) + +#define GLEW_ARB_bindless_texture GLEW_GET_VAR(__GLEW_ARB_bindless_texture) + +#endif /* GL_ARB_bindless_texture */ + +/* ----------------------- GL_ARB_blend_func_extended ---------------------- */ + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended 1 + +#define GL_SRC1_COLOR 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar * name); + +#define glBindFragDataLocationIndexed GLEW_GET_FUN(__glewBindFragDataLocationIndexed) +#define glGetFragDataIndex GLEW_GET_FUN(__glewGetFragDataIndex) + +#define GLEW_ARB_blend_func_extended GLEW_GET_VAR(__GLEW_ARB_blend_func_extended) + +#endif /* GL_ARB_blend_func_extended */ + +/* ------------------------- GL_ARB_buffer_storage ------------------------- */ + +#ifndef GL_ARB_buffer_storage +#define GL_ARB_buffer_storage 1 + +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_PERSISTENT_BIT 0x00000040 +#define GL_MAP_COHERENT_BIT 0x00000080 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_STORAGE_FLAGS 0x8220 + +typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); + +#define glBufferStorage GLEW_GET_FUN(__glewBufferStorage) +#define glNamedBufferStorageEXT GLEW_GET_FUN(__glewNamedBufferStorageEXT) + +#define GLEW_ARB_buffer_storage GLEW_GET_VAR(__GLEW_ARB_buffer_storage) + +#endif /* GL_ARB_buffer_storage */ + +/* ---------------------------- GL_ARB_cl_event ---------------------------- */ + +#ifndef GL_ARB_cl_event +#define GL_ARB_cl_event 1 + +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 + +typedef struct _cl_context *cl_context; +typedef struct _cl_event *cl_event; + +typedef GLsync (GLAPIENTRY * PFNGLCREATESYNCFROMCLEVENTARBPROC) (cl_context context, cl_event event, GLbitfield flags); + +#define glCreateSyncFromCLeventARB GLEW_GET_FUN(__glewCreateSyncFromCLeventARB) + +#define GLEW_ARB_cl_event GLEW_GET_VAR(__GLEW_ARB_cl_event) + +#endif /* GL_ARB_cl_event */ + +/* ----------------------- GL_ARB_clear_buffer_object ---------------------- */ + +#ifndef GL_ARB_clear_buffer_object +#define GL_ARB_clear_buffer_object 1 + +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); + +#define glClearBufferData GLEW_GET_FUN(__glewClearBufferData) +#define glClearBufferSubData GLEW_GET_FUN(__glewClearBufferSubData) +#define glClearNamedBufferDataEXT GLEW_GET_FUN(__glewClearNamedBufferDataEXT) +#define glClearNamedBufferSubDataEXT GLEW_GET_FUN(__glewClearNamedBufferSubDataEXT) + +#define GLEW_ARB_clear_buffer_object GLEW_GET_VAR(__GLEW_ARB_clear_buffer_object) + +#endif /* GL_ARB_clear_buffer_object */ + +/* -------------------------- GL_ARB_clear_texture ------------------------- */ + +#ifndef GL_ARB_clear_texture +#define GL_ARB_clear_texture 1 + +#define GL_CLEAR_TEXTURE 0x9365 + +typedef void (GLAPIENTRY * PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); + +#define glClearTexImage GLEW_GET_FUN(__glewClearTexImage) +#define glClearTexSubImage GLEW_GET_FUN(__glewClearTexSubImage) + +#define GLEW_ARB_clear_texture GLEW_GET_VAR(__GLEW_ARB_clear_texture) + +#endif /* GL_ARB_clear_texture */ + +/* ----------------------- 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_compatibility ------------------------- */ + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility 1 + +#define GLEW_ARB_compatibility GLEW_GET_VAR(__GLEW_ARB_compatibility) + +#endif /* GL_ARB_compatibility */ + +/* ---------------- GL_ARB_compressed_texture_pixel_storage ---------------- */ + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_ARB_compressed_texture_pixel_storage 1 + +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E + +#define GLEW_ARB_compressed_texture_pixel_storage GLEW_GET_VAR(__GLEW_ARB_compressed_texture_pixel_storage) + +#endif /* GL_ARB_compressed_texture_pixel_storage */ + +/* ------------------------- GL_ARB_compute_shader ------------------------- */ + +#ifndef GL_ARB_compute_shader +#define GL_ARB_compute_shader 1 + +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF + +typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); + +#define glDispatchCompute GLEW_GET_FUN(__glewDispatchCompute) +#define glDispatchComputeIndirect GLEW_GET_FUN(__glewDispatchComputeIndirect) + +#define GLEW_ARB_compute_shader GLEW_GET_VAR(__GLEW_ARB_compute_shader) + +#endif /* GL_ARB_compute_shader */ + +/* ------------------- GL_ARB_compute_variable_group_size ------------------ */ + +#ifndef GL_ARB_compute_variable_group_size +#define GL_ARB_compute_variable_group_size 1 + +#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB +#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF +#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 + +typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); + +#define glDispatchComputeGroupSizeARB GLEW_GET_FUN(__glewDispatchComputeGroupSizeARB) + +#define GLEW_ARB_compute_variable_group_size GLEW_GET_VAR(__GLEW_ARB_compute_variable_group_size) + +#endif /* GL_ARB_compute_variable_group_size */ + +/* ----------------------- GL_ARB_conservative_depth ----------------------- */ + +#ifndef GL_ARB_conservative_depth +#define GL_ARB_conservative_depth 1 + +#define GLEW_ARB_conservative_depth GLEW_GET_VAR(__GLEW_ARB_conservative_depth) + +#endif /* GL_ARB_conservative_depth */ + +/* --------------------------- GL_ARB_copy_buffer -------------------------- */ + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 + +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 + +typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); + +#define glCopyBufferSubData GLEW_GET_FUN(__glewCopyBufferSubData) + +#define GLEW_ARB_copy_buffer GLEW_GET_VAR(__GLEW_ARB_copy_buffer) + +#endif /* GL_ARB_copy_buffer */ + +/* --------------------------- GL_ARB_copy_image --------------------------- */ + +#ifndef GL_ARB_copy_image +#define GL_ARB_copy_image 1 + +typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + +#define glCopyImageSubData GLEW_GET_FUN(__glewCopyImageSubData) + +#define GLEW_ARB_copy_image GLEW_GET_VAR(__GLEW_ARB_copy_image) + +#endif /* GL_ARB_copy_image */ + +/* -------------------------- GL_ARB_debug_output -------------------------- */ + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 + +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 + +typedef void (GLAPIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); + +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); +typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); + +#define glDebugMessageCallbackARB GLEW_GET_FUN(__glewDebugMessageCallbackARB) +#define glDebugMessageControlARB GLEW_GET_FUN(__glewDebugMessageControlARB) +#define glDebugMessageInsertARB GLEW_GET_FUN(__glewDebugMessageInsertARB) +#define glGetDebugMessageLogARB GLEW_GET_FUN(__glewGetDebugMessageLogARB) + +#define GLEW_ARB_debug_output GLEW_GET_VAR(__GLEW_ARB_debug_output) + +#endif /* GL_ARB_debug_output */ + +/* ----------------------- 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_clamp -------------------------- */ + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp 1 + +#define GL_DEPTH_CLAMP 0x864F + +#define GLEW_ARB_depth_clamp GLEW_GET_VAR(__GLEW_ARB_depth_clamp) + +#endif /* GL_ARB_depth_clamp */ + +/* -------------------------- 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_buffers_blend ----------------------- */ + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); + +#define glBlendEquationSeparateiARB GLEW_GET_FUN(__glewBlendEquationSeparateiARB) +#define glBlendEquationiARB GLEW_GET_FUN(__glewBlendEquationiARB) +#define glBlendFuncSeparateiARB GLEW_GET_FUN(__glewBlendFuncSeparateiARB) +#define glBlendFunciARB GLEW_GET_FUN(__glewBlendFunciARB) + +#define GLEW_ARB_draw_buffers_blend GLEW_GET_VAR(__GLEW_ARB_draw_buffers_blend) + +#endif /* GL_ARB_draw_buffers_blend */ + +/* -------------------- GL_ARB_draw_elements_base_vertex ------------------- */ + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex 1 + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei* count, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex); + +#define glDrawElementsBaseVertex GLEW_GET_FUN(__glewDrawElementsBaseVertex) +#define glDrawElementsInstancedBaseVertex GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertex) +#define glDrawRangeElementsBaseVertex GLEW_GET_FUN(__glewDrawRangeElementsBaseVertex) +#define glMultiDrawElementsBaseVertex GLEW_GET_FUN(__glewMultiDrawElementsBaseVertex) + +#define GLEW_ARB_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_ARB_draw_elements_base_vertex) + +#endif /* GL_ARB_draw_elements_base_vertex */ + +/* -------------------------- GL_ARB_draw_indirect ------------------------- */ + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect 1 + +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); + +#define glDrawArraysIndirect GLEW_GET_FUN(__glewDrawArraysIndirect) +#define glDrawElementsIndirect GLEW_GET_FUN(__glewDrawElementsIndirect) + +#define GLEW_ARB_draw_indirect GLEW_GET_VAR(__GLEW_ARB_draw_indirect) + +#endif /* GL_ARB_draw_indirect */ + +/* ------------------------- GL_ARB_draw_instanced ------------------------- */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 + +#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced) + +#endif /* GL_ARB_draw_instanced */ + +/* ------------------------ GL_ARB_enhanced_layouts ------------------------ */ + +#ifndef GL_ARB_enhanced_layouts +#define GL_ARB_enhanced_layouts 1 + +#define GL_LOCATION_COMPONENT 0x934A +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C + +#define GLEW_ARB_enhanced_layouts GLEW_GET_VAR(__GLEW_ARB_enhanced_layouts) + +#endif /* GL_ARB_enhanced_layouts */ + +/* -------------------- GL_ARB_explicit_attrib_location -------------------- */ + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location 1 + +#define GLEW_ARB_explicit_attrib_location GLEW_GET_VAR(__GLEW_ARB_explicit_attrib_location) + +#endif /* GL_ARB_explicit_attrib_location */ + +/* -------------------- GL_ARB_explicit_uniform_location ------------------- */ + +#ifndef GL_ARB_explicit_uniform_location +#define GL_ARB_explicit_uniform_location 1 + +#define GL_MAX_UNIFORM_LOCATIONS 0x826E + +#define GLEW_ARB_explicit_uniform_location GLEW_GET_VAR(__GLEW_ARB_explicit_uniform_location) + +#endif /* GL_ARB_explicit_uniform_location */ + +/* ------------------- GL_ARB_fragment_coord_conventions ------------------- */ + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions 1 + +#define GLEW_ARB_fragment_coord_conventions GLEW_GET_VAR(__GLEW_ARB_fragment_coord_conventions) + +#endif /* GL_ARB_fragment_coord_conventions */ + +/* --------------------- GL_ARB_fragment_layer_viewport -------------------- */ + +#ifndef GL_ARB_fragment_layer_viewport +#define GL_ARB_fragment_layer_viewport 1 + +#define GLEW_ARB_fragment_layer_viewport GLEW_GET_VAR(__GLEW_ARB_fragment_layer_viewport) + +#endif /* GL_ARB_fragment_layer_viewport */ + +/* ------------------------ 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_no_attachments ------------------- */ + +#ifndef GL_ARB_framebuffer_no_attachments +#define GL_ARB_framebuffer_no_attachments 1 + +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); + +#define glFramebufferParameteri GLEW_GET_FUN(__glewFramebufferParameteri) +#define glGetFramebufferParameteriv GLEW_GET_FUN(__glewGetFramebufferParameteriv) +#define glGetNamedFramebufferParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferParameterivEXT) +#define glNamedFramebufferParameteriEXT GLEW_GET_FUN(__glewNamedFramebufferParameteriEXT) + +#define GLEW_ARB_framebuffer_no_attachments GLEW_GET_VAR(__GLEW_ARB_framebuffer_no_attachments) + +#endif /* GL_ARB_framebuffer_no_attachments */ + +/* ----------------------- 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 * 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 * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, 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 glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) +#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) +#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) +#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer) +#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_get_program_binary ----------------------- */ + +#ifndef GL_ARB_get_program_binary +#define GL_ARB_get_program_binary 1 + +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum *binaryFormat, void*binary); +typedef void (GLAPIENTRY * PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); + +#define glGetProgramBinary GLEW_GET_FUN(__glewGetProgramBinary) +#define glProgramBinary GLEW_GET_FUN(__glewProgramBinary) +#define glProgramParameteri GLEW_GET_FUN(__glewProgramParameteri) + +#define GLEW_ARB_get_program_binary GLEW_GET_VAR(__GLEW_ARB_get_program_binary) + +#endif /* GL_ARB_get_program_binary */ + +/* --------------------------- GL_ARB_gpu_shader5 -------------------------- */ + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 1 + +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MAX_VERTEX_STREAMS 0x8E71 + +#define GLEW_ARB_gpu_shader5 GLEW_GET_VAR(__GLEW_ARB_gpu_shader5) + +#endif /* GL_ARB_gpu_shader5 */ + +/* ------------------------- GL_ARB_gpu_shader_fp64 ------------------------ */ + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 1 + +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE + +typedef void (GLAPIENTRY * PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); + +#define glGetUniformdv GLEW_GET_FUN(__glewGetUniformdv) +#define glUniform1d GLEW_GET_FUN(__glewUniform1d) +#define glUniform1dv GLEW_GET_FUN(__glewUniform1dv) +#define glUniform2d GLEW_GET_FUN(__glewUniform2d) +#define glUniform2dv GLEW_GET_FUN(__glewUniform2dv) +#define glUniform3d GLEW_GET_FUN(__glewUniform3d) +#define glUniform3dv GLEW_GET_FUN(__glewUniform3dv) +#define glUniform4d GLEW_GET_FUN(__glewUniform4d) +#define glUniform4dv GLEW_GET_FUN(__glewUniform4dv) +#define glUniformMatrix2dv GLEW_GET_FUN(__glewUniformMatrix2dv) +#define glUniformMatrix2x3dv GLEW_GET_FUN(__glewUniformMatrix2x3dv) +#define glUniformMatrix2x4dv GLEW_GET_FUN(__glewUniformMatrix2x4dv) +#define glUniformMatrix3dv GLEW_GET_FUN(__glewUniformMatrix3dv) +#define glUniformMatrix3x2dv GLEW_GET_FUN(__glewUniformMatrix3x2dv) +#define glUniformMatrix3x4dv GLEW_GET_FUN(__glewUniformMatrix3x4dv) +#define glUniformMatrix4dv GLEW_GET_FUN(__glewUniformMatrix4dv) +#define glUniformMatrix4x2dv GLEW_GET_FUN(__glewUniformMatrix4x2dv) +#define glUniformMatrix4x3dv GLEW_GET_FUN(__glewUniformMatrix4x3dv) + +#define GLEW_ARB_gpu_shader_fp64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_fp64) + +#endif /* GL_ARB_gpu_shader_fp64 */ + +/* ------------------------ 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 void *data); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *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 void *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *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, void *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, void *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, void *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, void *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, void *row, void *column, void *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 void *row, const void *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_indirect_parameters ---------------------- */ + +#ifndef GL_ARB_indirect_parameters +#define GL_ARB_indirect_parameters 1 + +#define GL_PARAMETER_BUFFER_ARB 0x80EE +#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); + +#define glMultiDrawArraysIndirectCountARB GLEW_GET_FUN(__glewMultiDrawArraysIndirectCountARB) +#define glMultiDrawElementsIndirectCountARB GLEW_GET_FUN(__glewMultiDrawElementsIndirectCountARB) + +#define GLEW_ARB_indirect_parameters GLEW_GET_VAR(__GLEW_ARB_indirect_parameters) + +#endif /* GL_ARB_indirect_parameters */ + +/* ------------------------ 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 * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + +#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB) +#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB) +#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_internalformat_query ---------------------- */ + +#ifndef GL_ARB_internalformat_query +#define GL_ARB_internalformat_query 1 + +#define GL_NUM_SAMPLE_COUNTS 0x9380 + +typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params); + +#define glGetInternalformativ GLEW_GET_FUN(__glewGetInternalformativ) + +#define GLEW_ARB_internalformat_query GLEW_GET_VAR(__GLEW_ARB_internalformat_query) + +#endif /* GL_ARB_internalformat_query */ + +/* ---------------------- GL_ARB_internalformat_query2 --------------------- */ + +#ifndef GL_ARB_internalformat_query2 +#define GL_ARB_internalformat_query2 1 + +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_MIPMAP 0x8293 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_COLOR_ENCODING 0x8296 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_SRGB_DECODE_ARB 0x8299 +#define GL_FILTER 0x829A +#define GL_VERTEX_TEXTURE 0x829B +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 + +typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64* params); + +#define glGetInternalformati64v GLEW_GET_FUN(__glewGetInternalformati64v) + +#define GLEW_ARB_internalformat_query2 GLEW_GET_VAR(__GLEW_ARB_internalformat_query2) + +#endif /* GL_ARB_internalformat_query2 */ + +/* ----------------------- GL_ARB_invalidate_subdata ----------------------- */ + +#ifndef GL_ARB_invalidate_subdata +#define GL_ARB_invalidate_subdata 1 + +typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments); +typedef void (GLAPIENTRY * PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + +#define glInvalidateBufferData GLEW_GET_FUN(__glewInvalidateBufferData) +#define glInvalidateBufferSubData GLEW_GET_FUN(__glewInvalidateBufferSubData) +#define glInvalidateFramebuffer GLEW_GET_FUN(__glewInvalidateFramebuffer) +#define glInvalidateSubFramebuffer GLEW_GET_FUN(__glewInvalidateSubFramebuffer) +#define glInvalidateTexImage GLEW_GET_FUN(__glewInvalidateTexImage) +#define glInvalidateTexSubImage GLEW_GET_FUN(__glewInvalidateTexSubImage) + +#define GLEW_ARB_invalidate_subdata GLEW_GET_VAR(__GLEW_ARB_invalidate_subdata) + +#endif /* GL_ARB_invalidate_subdata */ + +/* ---------------------- GL_ARB_map_buffer_alignment ---------------------- */ + +#ifndef GL_ARB_map_buffer_alignment +#define GL_ARB_map_buffer_alignment 1 + +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC + +#define GLEW_ARB_map_buffer_alignment GLEW_GET_VAR(__GLEW_ARB_map_buffer_alignment) + +#endif /* GL_ARB_map_buffer_alignment */ + +/* ------------------------ 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 void * (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, void *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_multi_bind --------------------------- */ + +#ifndef GL_ARB_multi_bind +#define GL_ARB_multi_bind 1 + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizeiptr *sizes); +typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint* samplers); +typedef void (GLAPIENTRY * PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides); + +#define glBindBuffersBase GLEW_GET_FUN(__glewBindBuffersBase) +#define glBindBuffersRange GLEW_GET_FUN(__glewBindBuffersRange) +#define glBindImageTextures GLEW_GET_FUN(__glewBindImageTextures) +#define glBindSamplers GLEW_GET_FUN(__glewBindSamplers) +#define glBindTextures GLEW_GET_FUN(__glewBindTextures) +#define glBindVertexBuffers GLEW_GET_FUN(__glewBindVertexBuffers) + +#define GLEW_ARB_multi_bind GLEW_GET_VAR(__GLEW_ARB_multi_bind) + +#endif /* GL_ARB_multi_bind */ + +/* ----------------------- GL_ARB_multi_draw_indirect ---------------------- */ + +#ifndef GL_ARB_multi_draw_indirect +#define GL_ARB_multi_draw_indirect 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); + +#define glMultiDrawArraysIndirect GLEW_GET_FUN(__glewMultiDrawArraysIndirect) +#define glMultiDrawElementsIndirect GLEW_GET_FUN(__glewMultiDrawElementsIndirect) + +#define GLEW_ARB_multi_draw_indirect GLEW_GET_VAR(__GLEW_ARB_multi_draw_indirect) + +#endif /* GL_ARB_multi_draw_indirect */ + +/* --------------------------- 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_occlusion_query2 ------------------------ */ + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 1 + +#define GL_ANY_SAMPLES_PASSED 0x8C2F + +#define GLEW_ARB_occlusion_query2 GLEW_GET_VAR(__GLEW_ARB_occlusion_query2) + +#endif /* GL_ARB_occlusion_query2 */ + +/* ----------------------- 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, const 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_program_interface_query -------------------- */ + +#ifndef GL_ARB_program_interface_query +#define GL_ARB_program_interface_query 1 + +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_IS_PER_PATCH 0x92E7 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint* params); +typedef GLuint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name); +typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar* name); +typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLint *params); + +#define glGetProgramInterfaceiv GLEW_GET_FUN(__glewGetProgramInterfaceiv) +#define glGetProgramResourceIndex GLEW_GET_FUN(__glewGetProgramResourceIndex) +#define glGetProgramResourceLocation GLEW_GET_FUN(__glewGetProgramResourceLocation) +#define glGetProgramResourceLocationIndex GLEW_GET_FUN(__glewGetProgramResourceLocationIndex) +#define glGetProgramResourceName GLEW_GET_FUN(__glewGetProgramResourceName) +#define glGetProgramResourceiv GLEW_GET_FUN(__glewGetProgramResourceiv) + +#define GLEW_ARB_program_interface_query GLEW_GET_VAR(__GLEW_ARB_program_interface_query) + +#endif /* GL_ARB_program_interface_query */ + +/* ------------------------ GL_ARB_provoking_vertex ------------------------ */ + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex 1 + +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F + +typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXPROC) (GLenum mode); + +#define glProvokingVertex GLEW_GET_FUN(__glewProvokingVertex) + +#define GLEW_ARB_provoking_vertex GLEW_GET_VAR(__GLEW_ARB_provoking_vertex) + +#endif /* GL_ARB_provoking_vertex */ + +/* ----------------------- GL_ARB_query_buffer_object ---------------------- */ + +#ifndef GL_ARB_query_buffer_object +#define GL_ARB_query_buffer_object 1 + +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 + +#define GLEW_ARB_query_buffer_object GLEW_GET_VAR(__GLEW_ARB_query_buffer_object) + +#endif /* GL_ARB_query_buffer_object */ + +/* ------------------ GL_ARB_robust_buffer_access_behavior ----------------- */ + +#ifndef GL_ARB_robust_buffer_access_behavior +#define GL_ARB_robust_buffer_access_behavior 1 + +#define GLEW_ARB_robust_buffer_access_behavior GLEW_GET_VAR(__GLEW_ARB_robust_buffer_access_behavior) + +#endif /* GL_ARB_robust_buffer_access_behavior */ + +/* --------------------------- GL_ARB_robustness --------------------------- */ + +#ifndef GL_ARB_robustness +#define GL_ARB_robustness 1 + +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 + +typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table); +typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void* img); +typedef void (GLAPIENTRY * PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image); +typedef void (GLAPIENTRY * PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); +typedef void (GLAPIENTRY * PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble* v); +typedef void (GLAPIENTRY * PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat* v); +typedef void (GLAPIENTRY * PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint* v); +typedef void (GLAPIENTRY * PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort* values); +typedef void (GLAPIENTRY * PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte* pattern); +typedef void (GLAPIENTRY * PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, void*column, void*span); +typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* img); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params); +typedef void (GLAPIENTRY * PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data); + +#define glGetGraphicsResetStatusARB GLEW_GET_FUN(__glewGetGraphicsResetStatusARB) +#define glGetnColorTableARB GLEW_GET_FUN(__glewGetnColorTableARB) +#define glGetnCompressedTexImageARB GLEW_GET_FUN(__glewGetnCompressedTexImageARB) +#define glGetnConvolutionFilterARB GLEW_GET_FUN(__glewGetnConvolutionFilterARB) +#define glGetnHistogramARB GLEW_GET_FUN(__glewGetnHistogramARB) +#define glGetnMapdvARB GLEW_GET_FUN(__glewGetnMapdvARB) +#define glGetnMapfvARB GLEW_GET_FUN(__glewGetnMapfvARB) +#define glGetnMapivARB GLEW_GET_FUN(__glewGetnMapivARB) +#define glGetnMinmaxARB GLEW_GET_FUN(__glewGetnMinmaxARB) +#define glGetnPixelMapfvARB GLEW_GET_FUN(__glewGetnPixelMapfvARB) +#define glGetnPixelMapuivARB GLEW_GET_FUN(__glewGetnPixelMapuivARB) +#define glGetnPixelMapusvARB GLEW_GET_FUN(__glewGetnPixelMapusvARB) +#define glGetnPolygonStippleARB GLEW_GET_FUN(__glewGetnPolygonStippleARB) +#define glGetnSeparableFilterARB GLEW_GET_FUN(__glewGetnSeparableFilterARB) +#define glGetnTexImageARB GLEW_GET_FUN(__glewGetnTexImageARB) +#define glGetnUniformdvARB GLEW_GET_FUN(__glewGetnUniformdvARB) +#define glGetnUniformfvARB GLEW_GET_FUN(__glewGetnUniformfvARB) +#define glGetnUniformivARB GLEW_GET_FUN(__glewGetnUniformivARB) +#define glGetnUniformuivARB GLEW_GET_FUN(__glewGetnUniformuivARB) +#define glReadnPixelsARB GLEW_GET_FUN(__glewReadnPixelsARB) + +#define GLEW_ARB_robustness GLEW_GET_VAR(__GLEW_ARB_robustness) + +#endif /* GL_ARB_robustness */ + +/* ---------------- GL_ARB_robustness_application_isolation ---------------- */ + +#ifndef GL_ARB_robustness_application_isolation +#define GL_ARB_robustness_application_isolation 1 + +#define GLEW_ARB_robustness_application_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_application_isolation) + +#endif /* GL_ARB_robustness_application_isolation */ + +/* ---------------- GL_ARB_robustness_share_group_isolation ---------------- */ + +#ifndef GL_ARB_robustness_share_group_isolation +#define GL_ARB_robustness_share_group_isolation 1 + +#define GLEW_ARB_robustness_share_group_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_share_group_isolation) + +#endif /* GL_ARB_robustness_share_group_isolation */ + +/* ------------------------- GL_ARB_sample_shading ------------------------- */ + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading 1 + +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 + +typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value); + +#define glMinSampleShadingARB GLEW_GET_FUN(__glewMinSampleShadingARB) + +#define GLEW_ARB_sample_shading GLEW_GET_VAR(__GLEW_ARB_sample_shading) + +#endif /* GL_ARB_sample_shading */ + +/* ------------------------- GL_ARB_sampler_objects ------------------------ */ + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects 1 + +#define GL_SAMPLER_BINDING 0x8919 + +typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint * samplers); +typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint* params); + +#define glBindSampler GLEW_GET_FUN(__glewBindSampler) +#define glDeleteSamplers GLEW_GET_FUN(__glewDeleteSamplers) +#define glGenSamplers GLEW_GET_FUN(__glewGenSamplers) +#define glGetSamplerParameterIiv GLEW_GET_FUN(__glewGetSamplerParameterIiv) +#define glGetSamplerParameterIuiv GLEW_GET_FUN(__glewGetSamplerParameterIuiv) +#define glGetSamplerParameterfv GLEW_GET_FUN(__glewGetSamplerParameterfv) +#define glGetSamplerParameteriv GLEW_GET_FUN(__glewGetSamplerParameteriv) +#define glIsSampler GLEW_GET_FUN(__glewIsSampler) +#define glSamplerParameterIiv GLEW_GET_FUN(__glewSamplerParameterIiv) +#define glSamplerParameterIuiv GLEW_GET_FUN(__glewSamplerParameterIuiv) +#define glSamplerParameterf GLEW_GET_FUN(__glewSamplerParameterf) +#define glSamplerParameterfv GLEW_GET_FUN(__glewSamplerParameterfv) +#define glSamplerParameteri GLEW_GET_FUN(__glewSamplerParameteri) +#define glSamplerParameteriv GLEW_GET_FUN(__glewSamplerParameteriv) + +#define GLEW_ARB_sampler_objects GLEW_GET_VAR(__GLEW_ARB_sampler_objects) + +#endif /* GL_ARB_sampler_objects */ + +/* ------------------------ GL_ARB_seamless_cube_map ----------------------- */ + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F + +#define GLEW_ARB_seamless_cube_map GLEW_GET_VAR(__GLEW_ARB_seamless_cube_map) + +#endif /* GL_ARB_seamless_cube_map */ + +/* ------------------ GL_ARB_seamless_cubemap_per_texture ------------------ */ + +#ifndef GL_ARB_seamless_cubemap_per_texture +#define GL_ARB_seamless_cubemap_per_texture 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F + +#define GLEW_ARB_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_ARB_seamless_cubemap_per_texture) + +#endif /* GL_ARB_seamless_cubemap_per_texture */ + +/* --------------------- GL_ARB_separate_shader_objects -------------------- */ + +#ifndef GL_ARB_separate_shader_objects +#define GL_ARB_separate_shader_objects 1 + +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_ALL_SHADER_BITS 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar * const * strings); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint* pipelines); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar *infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); + +#define glActiveShaderProgram GLEW_GET_FUN(__glewActiveShaderProgram) +#define glBindProgramPipeline GLEW_GET_FUN(__glewBindProgramPipeline) +#define glCreateShaderProgramv GLEW_GET_FUN(__glewCreateShaderProgramv) +#define glDeleteProgramPipelines GLEW_GET_FUN(__glewDeleteProgramPipelines) +#define glGenProgramPipelines GLEW_GET_FUN(__glewGenProgramPipelines) +#define glGetProgramPipelineInfoLog GLEW_GET_FUN(__glewGetProgramPipelineInfoLog) +#define glGetProgramPipelineiv GLEW_GET_FUN(__glewGetProgramPipelineiv) +#define glIsProgramPipeline GLEW_GET_FUN(__glewIsProgramPipeline) +#define glProgramUniform1d GLEW_GET_FUN(__glewProgramUniform1d) +#define glProgramUniform1dv GLEW_GET_FUN(__glewProgramUniform1dv) +#define glProgramUniform1f GLEW_GET_FUN(__glewProgramUniform1f) +#define glProgramUniform1fv GLEW_GET_FUN(__glewProgramUniform1fv) +#define glProgramUniform1i GLEW_GET_FUN(__glewProgramUniform1i) +#define glProgramUniform1iv GLEW_GET_FUN(__glewProgramUniform1iv) +#define glProgramUniform1ui GLEW_GET_FUN(__glewProgramUniform1ui) +#define glProgramUniform1uiv GLEW_GET_FUN(__glewProgramUniform1uiv) +#define glProgramUniform2d GLEW_GET_FUN(__glewProgramUniform2d) +#define glProgramUniform2dv GLEW_GET_FUN(__glewProgramUniform2dv) +#define glProgramUniform2f GLEW_GET_FUN(__glewProgramUniform2f) +#define glProgramUniform2fv GLEW_GET_FUN(__glewProgramUniform2fv) +#define glProgramUniform2i GLEW_GET_FUN(__glewProgramUniform2i) +#define glProgramUniform2iv GLEW_GET_FUN(__glewProgramUniform2iv) +#define glProgramUniform2ui GLEW_GET_FUN(__glewProgramUniform2ui) +#define glProgramUniform2uiv GLEW_GET_FUN(__glewProgramUniform2uiv) +#define glProgramUniform3d GLEW_GET_FUN(__glewProgramUniform3d) +#define glProgramUniform3dv GLEW_GET_FUN(__glewProgramUniform3dv) +#define glProgramUniform3f GLEW_GET_FUN(__glewProgramUniform3f) +#define glProgramUniform3fv GLEW_GET_FUN(__glewProgramUniform3fv) +#define glProgramUniform3i GLEW_GET_FUN(__glewProgramUniform3i) +#define glProgramUniform3iv GLEW_GET_FUN(__glewProgramUniform3iv) +#define glProgramUniform3ui GLEW_GET_FUN(__glewProgramUniform3ui) +#define glProgramUniform3uiv GLEW_GET_FUN(__glewProgramUniform3uiv) +#define glProgramUniform4d GLEW_GET_FUN(__glewProgramUniform4d) +#define glProgramUniform4dv GLEW_GET_FUN(__glewProgramUniform4dv) +#define glProgramUniform4f GLEW_GET_FUN(__glewProgramUniform4f) +#define glProgramUniform4fv GLEW_GET_FUN(__glewProgramUniform4fv) +#define glProgramUniform4i GLEW_GET_FUN(__glewProgramUniform4i) +#define glProgramUniform4iv GLEW_GET_FUN(__glewProgramUniform4iv) +#define glProgramUniform4ui GLEW_GET_FUN(__glewProgramUniform4ui) +#define glProgramUniform4uiv GLEW_GET_FUN(__glewProgramUniform4uiv) +#define glProgramUniformMatrix2dv GLEW_GET_FUN(__glewProgramUniformMatrix2dv) +#define glProgramUniformMatrix2fv GLEW_GET_FUN(__glewProgramUniformMatrix2fv) +#define glProgramUniformMatrix2x3dv GLEW_GET_FUN(__glewProgramUniformMatrix2x3dv) +#define glProgramUniformMatrix2x3fv GLEW_GET_FUN(__glewProgramUniformMatrix2x3fv) +#define glProgramUniformMatrix2x4dv GLEW_GET_FUN(__glewProgramUniformMatrix2x4dv) +#define glProgramUniformMatrix2x4fv GLEW_GET_FUN(__glewProgramUniformMatrix2x4fv) +#define glProgramUniformMatrix3dv GLEW_GET_FUN(__glewProgramUniformMatrix3dv) +#define glProgramUniformMatrix3fv GLEW_GET_FUN(__glewProgramUniformMatrix3fv) +#define glProgramUniformMatrix3x2dv GLEW_GET_FUN(__glewProgramUniformMatrix3x2dv) +#define glProgramUniformMatrix3x2fv GLEW_GET_FUN(__glewProgramUniformMatrix3x2fv) +#define glProgramUniformMatrix3x4dv GLEW_GET_FUN(__glewProgramUniformMatrix3x4dv) +#define glProgramUniformMatrix3x4fv GLEW_GET_FUN(__glewProgramUniformMatrix3x4fv) +#define glProgramUniformMatrix4dv GLEW_GET_FUN(__glewProgramUniformMatrix4dv) +#define glProgramUniformMatrix4fv GLEW_GET_FUN(__glewProgramUniformMatrix4fv) +#define glProgramUniformMatrix4x2dv GLEW_GET_FUN(__glewProgramUniformMatrix4x2dv) +#define glProgramUniformMatrix4x2fv GLEW_GET_FUN(__glewProgramUniformMatrix4x2fv) +#define glProgramUniformMatrix4x3dv GLEW_GET_FUN(__glewProgramUniformMatrix4x3dv) +#define glProgramUniformMatrix4x3fv GLEW_GET_FUN(__glewProgramUniformMatrix4x3fv) +#define glUseProgramStages GLEW_GET_FUN(__glewUseProgramStages) +#define glValidateProgramPipeline GLEW_GET_FUN(__glewValidateProgramPipeline) + +#define GLEW_ARB_separate_shader_objects GLEW_GET_VAR(__GLEW_ARB_separate_shader_objects) + +#endif /* GL_ARB_separate_shader_objects */ + +/* --------------------- GL_ARB_shader_atomic_counters --------------------- */ + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ARB_shader_atomic_counters 1 + +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC + +typedef void (GLAPIENTRY * PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint* params); + +#define glGetActiveAtomicCounterBufferiv GLEW_GET_FUN(__glewGetActiveAtomicCounterBufferiv) + +#define GLEW_ARB_shader_atomic_counters GLEW_GET_VAR(__GLEW_ARB_shader_atomic_counters) + +#endif /* GL_ARB_shader_atomic_counters */ + +/* ----------------------- GL_ARB_shader_bit_encoding ---------------------- */ + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 + +#define GLEW_ARB_shader_bit_encoding GLEW_GET_VAR(__GLEW_ARB_shader_bit_encoding) + +#endif /* GL_ARB_shader_bit_encoding */ + +/* --------------------- GL_ARB_shader_draw_parameters --------------------- */ + +#ifndef GL_ARB_shader_draw_parameters +#define GL_ARB_shader_draw_parameters 1 + +#define GLEW_ARB_shader_draw_parameters GLEW_GET_VAR(__GLEW_ARB_shader_draw_parameters) + +#endif /* GL_ARB_shader_draw_parameters */ + +/* ------------------------ GL_ARB_shader_group_vote ----------------------- */ + +#ifndef GL_ARB_shader_group_vote +#define GL_ARB_shader_group_vote 1 + +#define GLEW_ARB_shader_group_vote GLEW_GET_VAR(__GLEW_ARB_shader_group_vote) + +#endif /* GL_ARB_shader_group_vote */ + +/* --------------------- GL_ARB_shader_image_load_store -------------------- */ + +#ifndef GL_ARB_shader_image_load_store +#define GL_ARB_shader_image_load_store 1 + +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (GLAPIENTRY * PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); + +#define glBindImageTexture GLEW_GET_FUN(__glewBindImageTexture) +#define glMemoryBarrier GLEW_GET_FUN(__glewMemoryBarrier) + +#define GLEW_ARB_shader_image_load_store GLEW_GET_VAR(__GLEW_ARB_shader_image_load_store) + +#endif /* GL_ARB_shader_image_load_store */ + +/* ------------------------ GL_ARB_shader_image_size ----------------------- */ + +#ifndef GL_ARB_shader_image_size +#define GL_ARB_shader_image_size 1 + +#define GLEW_ARB_shader_image_size GLEW_GET_VAR(__GLEW_ARB_shader_image_size) + +#endif /* GL_ARB_shader_image_size */ + +/* ------------------------- 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_shader_precision ------------------------ */ + +#ifndef GL_ARB_shader_precision +#define GL_ARB_shader_precision 1 + +#define GLEW_ARB_shader_precision GLEW_GET_VAR(__GLEW_ARB_shader_precision) + +#endif /* GL_ARB_shader_precision */ + +/* ---------------------- GL_ARB_shader_stencil_export --------------------- */ + +#ifndef GL_ARB_shader_stencil_export +#define GL_ARB_shader_stencil_export 1 + +#define GLEW_ARB_shader_stencil_export GLEW_GET_VAR(__GLEW_ARB_shader_stencil_export) + +#endif /* GL_ARB_shader_stencil_export */ + +/* ------------------ GL_ARB_shader_storage_buffer_object ------------------ */ + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 + +#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF + +typedef void (GLAPIENTRY * PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); + +#define glShaderStorageBlockBinding GLEW_GET_FUN(__glewShaderStorageBlockBinding) + +#define GLEW_ARB_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_ARB_shader_storage_buffer_object) + +#endif /* GL_ARB_shader_storage_buffer_object */ + +/* ------------------------ GL_ARB_shader_subroutine ----------------------- */ + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine 1 + +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B + +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint* values); +typedef GLuint (GLAPIENTRY * PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar* name); +typedef GLint (GLAPIENTRY * PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint* params); +typedef void (GLAPIENTRY * PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint* indices); + +#define glGetActiveSubroutineName GLEW_GET_FUN(__glewGetActiveSubroutineName) +#define glGetActiveSubroutineUniformName GLEW_GET_FUN(__glewGetActiveSubroutineUniformName) +#define glGetActiveSubroutineUniformiv GLEW_GET_FUN(__glewGetActiveSubroutineUniformiv) +#define glGetProgramStageiv GLEW_GET_FUN(__glewGetProgramStageiv) +#define glGetSubroutineIndex GLEW_GET_FUN(__glewGetSubroutineIndex) +#define glGetSubroutineUniformLocation GLEW_GET_FUN(__glewGetSubroutineUniformLocation) +#define glGetUniformSubroutineuiv GLEW_GET_FUN(__glewGetUniformSubroutineuiv) +#define glUniformSubroutinesuiv GLEW_GET_FUN(__glewUniformSubroutinesuiv) + +#define GLEW_ARB_shader_subroutine GLEW_GET_VAR(__GLEW_ARB_shader_subroutine) + +#endif /* GL_ARB_shader_subroutine */ + +/* ----------------------- GL_ARB_shader_texture_lod ----------------------- */ + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod 1 + +#define GLEW_ARB_shader_texture_lod GLEW_GET_VAR(__GLEW_ARB_shader_texture_lod) + +#endif /* GL_ARB_shader_texture_lod */ + +/* ---------------------- 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_shading_language_420pack -------------------- */ + +#ifndef GL_ARB_shading_language_420pack +#define GL_ARB_shading_language_420pack 1 + +#define GLEW_ARB_shading_language_420pack GLEW_GET_VAR(__GLEW_ARB_shading_language_420pack) + +#endif /* GL_ARB_shading_language_420pack */ + +/* -------------------- GL_ARB_shading_language_include -------------------- */ + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include 1 + +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA + +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* const *path, const GLint *length); +typedef void (GLAPIENTRY * PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name, GLsizei bufSize, GLint *stringlen, GLchar *string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar* name, GLenum pname, GLint *params); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar* name, GLint stringlen, const GLchar *string); + +#define glCompileShaderIncludeARB GLEW_GET_FUN(__glewCompileShaderIncludeARB) +#define glDeleteNamedStringARB GLEW_GET_FUN(__glewDeleteNamedStringARB) +#define glGetNamedStringARB GLEW_GET_FUN(__glewGetNamedStringARB) +#define glGetNamedStringivARB GLEW_GET_FUN(__glewGetNamedStringivARB) +#define glIsNamedStringARB GLEW_GET_FUN(__glewIsNamedStringARB) +#define glNamedStringARB GLEW_GET_FUN(__glewNamedStringARB) + +#define GLEW_ARB_shading_language_include GLEW_GET_VAR(__GLEW_ARB_shading_language_include) + +#endif /* GL_ARB_shading_language_include */ + +/* -------------------- GL_ARB_shading_language_packing -------------------- */ + +#ifndef GL_ARB_shading_language_packing +#define GL_ARB_shading_language_packing 1 + +#define GLEW_ARB_shading_language_packing GLEW_GET_VAR(__GLEW_ARB_shading_language_packing) + +#endif /* GL_ARB_shading_language_packing */ + +/* ----------------------------- 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_sparse_texture ------------------------- */ + +#ifndef GL_ARB_sparse_texture +#define GL_ARB_sparse_texture 1 + +#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A +#define GL_TEXTURE_SPARSE_ARB 0x91A6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 +#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 +#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA + +typedef void (GLAPIENTRY * PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +typedef void (GLAPIENTRY * PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); + +#define glTexPageCommitmentARB GLEW_GET_FUN(__glewTexPageCommitmentARB) +#define glTexturePageCommitmentEXT GLEW_GET_FUN(__glewTexturePageCommitmentEXT) + +#define GLEW_ARB_sparse_texture GLEW_GET_VAR(__GLEW_ARB_sparse_texture) + +#endif /* GL_ARB_sparse_texture */ + +/* ------------------------ GL_ARB_stencil_texturing ----------------------- */ + +#ifndef GL_ARB_stencil_texturing +#define GL_ARB_stencil_texturing 1 + +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA + +#define GLEW_ARB_stencil_texturing GLEW_GET_VAR(__GLEW_ARB_stencil_texturing) + +#endif /* GL_ARB_stencil_texturing */ + +/* ------------------------------ GL_ARB_sync ------------------------------ */ + +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 + +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF + +typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); +typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync); +typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETSYNCIVPROC) (GLsync GLsync,GLenum pname,GLsizei bufSize,GLsizei* length, GLint *values); +typedef GLboolean (GLAPIENTRY * PFNGLISSYNCPROC) (GLsync GLsync); +typedef void (GLAPIENTRY * PFNGLWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); + +#define glClientWaitSync GLEW_GET_FUN(__glewClientWaitSync) +#define glDeleteSync GLEW_GET_FUN(__glewDeleteSync) +#define glFenceSync GLEW_GET_FUN(__glewFenceSync) +#define glGetInteger64v GLEW_GET_FUN(__glewGetInteger64v) +#define glGetSynciv GLEW_GET_FUN(__glewGetSynciv) +#define glIsSync GLEW_GET_FUN(__glewIsSync) +#define glWaitSync GLEW_GET_FUN(__glewWaitSync) + +#define GLEW_ARB_sync GLEW_GET_VAR(__GLEW_ARB_sync) + +#endif /* GL_ARB_sync */ + +/* ----------------------- GL_ARB_tessellation_shader ---------------------- */ + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader 1 + +#define GL_PATCHES 0xE +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A + +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat* values); +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); + +#define glPatchParameterfv GLEW_GET_FUN(__glewPatchParameterfv) +#define glPatchParameteri GLEW_GET_FUN(__glewPatchParameteri) + +#define GLEW_ARB_tessellation_shader GLEW_GET_VAR(__GLEW_ARB_tessellation_shader) + +#endif /* GL_ARB_tessellation_shader */ + +/* ---------------------- 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_buffer_object_rgb32 ------------------ */ + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 1 + +#define GLEW_ARB_texture_buffer_object_rgb32 GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object_rgb32) + +#endif /* GL_ARB_texture_buffer_object_rgb32 */ + +/* ---------------------- GL_ARB_texture_buffer_range ---------------------- */ + +#ifndef GL_ARB_texture_buffer_range +#define GL_ARB_texture_buffer_range 1 + +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F + +typedef void (GLAPIENTRY * PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); + +#define glTexBufferRange GLEW_GET_FUN(__glewTexBufferRange) +#define glTextureBufferRangeEXT GLEW_GET_FUN(__glewTextureBufferRangeEXT) + +#define GLEW_ARB_texture_buffer_range GLEW_GET_VAR(__GLEW_ARB_texture_buffer_range) + +#endif /* GL_ARB_texture_buffer_range */ + +/* ----------------------- 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_bptc -------------------- */ + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc 1 + +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F + +#define GLEW_ARB_texture_compression_bptc GLEW_GET_VAR(__GLEW_ARB_texture_compression_bptc) + +#endif /* GL_ARB_texture_compression_bptc */ + +/* -------------------- 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_cube_map_array --------------------- */ + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array 1 + +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F + +#define GLEW_ARB_texture_cube_map_array GLEW_GET_VAR(__GLEW_ARB_texture_cube_map_array) + +#endif /* GL_ARB_texture_cube_map_array */ + +/* ------------------------- 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_gather ------------------------- */ + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather 1 + +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F + +#define GLEW_ARB_texture_gather GLEW_GET_VAR(__GLEW_ARB_texture_gather) + +#endif /* GL_ARB_texture_gather */ + +/* ------------------ GL_ARB_texture_mirror_clamp_to_edge ------------------ */ + +#ifndef GL_ARB_texture_mirror_clamp_to_edge +#define GL_ARB_texture_mirror_clamp_to_edge 1 + +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 + +#define GLEW_ARB_texture_mirror_clamp_to_edge GLEW_GET_VAR(__GLEW_ARB_texture_mirror_clamp_to_edge) + +#endif /* GL_ARB_texture_mirror_clamp_to_edge */ + +/* --------------------- 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_multisample ---------------------- */ + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 + +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 + +typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + +#define glGetMultisamplefv GLEW_GET_FUN(__glewGetMultisamplefv) +#define glSampleMaski GLEW_GET_FUN(__glewSampleMaski) +#define glTexImage2DMultisample GLEW_GET_FUN(__glewTexImage2DMultisample) +#define glTexImage3DMultisample GLEW_GET_FUN(__glewTexImage3DMultisample) + +#define GLEW_ARB_texture_multisample GLEW_GET_VAR(__GLEW_ARB_texture_multisample) + +#endif /* GL_ARB_texture_multisample */ + +/* -------------------- 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_query_levels ---------------------- */ + +#ifndef GL_ARB_texture_query_levels +#define GL_ARB_texture_query_levels 1 + +#define GLEW_ARB_texture_query_levels GLEW_GET_VAR(__GLEW_ARB_texture_query_levels) + +#endif /* GL_ARB_texture_query_levels */ + +/* ------------------------ GL_ARB_texture_query_lod ----------------------- */ + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod 1 + +#define GLEW_ARB_texture_query_lod GLEW_GET_VAR(__GLEW_ARB_texture_query_lod) + +#endif /* GL_ARB_texture_query_lod */ + +/* ------------------------ 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_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#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_texture_rgb10_a2ui ----------------------- */ + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui 1 + +#define GL_RGB10_A2UI 0x906F + +#define GLEW_ARB_texture_rgb10_a2ui GLEW_GET_VAR(__GLEW_ARB_texture_rgb10_a2ui) + +#endif /* GL_ARB_texture_rgb10_a2ui */ + +/* ------------------------ GL_ARB_texture_stencil8 ------------------------ */ + +#ifndef GL_ARB_texture_stencil8 +#define GL_ARB_texture_stencil8 1 + +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GLEW_ARB_texture_stencil8 GLEW_GET_VAR(__GLEW_ARB_texture_stencil8) + +#endif /* GL_ARB_texture_stencil8 */ + +/* ------------------------- GL_ARB_texture_storage ------------------------ */ + +#ifndef GL_ARB_texture_storage +#define GL_ARB_texture_storage 1 + +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F + +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + +#define glTexStorage1D GLEW_GET_FUN(__glewTexStorage1D) +#define glTexStorage2D GLEW_GET_FUN(__glewTexStorage2D) +#define glTexStorage3D GLEW_GET_FUN(__glewTexStorage3D) +#define glTextureStorage1DEXT GLEW_GET_FUN(__glewTextureStorage1DEXT) +#define glTextureStorage2DEXT GLEW_GET_FUN(__glewTextureStorage2DEXT) +#define glTextureStorage3DEXT GLEW_GET_FUN(__glewTextureStorage3DEXT) + +#define GLEW_ARB_texture_storage GLEW_GET_VAR(__GLEW_ARB_texture_storage) + +#endif /* GL_ARB_texture_storage */ + +/* ------------------- GL_ARB_texture_storage_multisample ------------------ */ + +#ifndef GL_ARB_texture_storage_multisample +#define GL_ARB_texture_storage_multisample 1 + +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + +#define glTexStorage2DMultisample GLEW_GET_FUN(__glewTexStorage2DMultisample) +#define glTexStorage3DMultisample GLEW_GET_FUN(__glewTexStorage3DMultisample) +#define glTextureStorage2DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage2DMultisampleEXT) +#define glTextureStorage3DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage3DMultisampleEXT) + +#define GLEW_ARB_texture_storage_multisample GLEW_GET_VAR(__GLEW_ARB_texture_storage_multisample) + +#endif /* GL_ARB_texture_storage_multisample */ + +/* ------------------------- GL_ARB_texture_swizzle ------------------------ */ + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle 1 + +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 + +#define GLEW_ARB_texture_swizzle GLEW_GET_VAR(__GLEW_ARB_texture_swizzle) + +#endif /* GL_ARB_texture_swizzle */ + +/* -------------------------- GL_ARB_texture_view -------------------------- */ + +#ifndef GL_ARB_texture_view +#define GL_ARB_texture_view 1 + +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF + +typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); + +#define glTextureView GLEW_GET_FUN(__glewTextureView) + +#define GLEW_ARB_texture_view GLEW_GET_VAR(__GLEW_ARB_texture_view) + +#endif /* GL_ARB_texture_view */ + +/* --------------------------- GL_ARB_timer_query -------------------------- */ + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 + +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); + +#define glGetQueryObjecti64v GLEW_GET_FUN(__glewGetQueryObjecti64v) +#define glGetQueryObjectui64v GLEW_GET_FUN(__glewGetQueryObjectui64v) +#define glQueryCounter GLEW_GET_FUN(__glewQueryCounter) + +#define GLEW_ARB_timer_query GLEW_GET_VAR(__GLEW_ARB_timer_query) + +#endif /* GL_ARB_timer_query */ + +/* ----------------------- GL_ARB_transform_feedback2 ---------------------- */ + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 1 + +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 + +typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); +typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); +typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); + +#define glBindTransformFeedback GLEW_GET_FUN(__glewBindTransformFeedback) +#define glDeleteTransformFeedbacks GLEW_GET_FUN(__glewDeleteTransformFeedbacks) +#define glDrawTransformFeedback GLEW_GET_FUN(__glewDrawTransformFeedback) +#define glGenTransformFeedbacks GLEW_GET_FUN(__glewGenTransformFeedbacks) +#define glIsTransformFeedback GLEW_GET_FUN(__glewIsTransformFeedback) +#define glPauseTransformFeedback GLEW_GET_FUN(__glewPauseTransformFeedback) +#define glResumeTransformFeedback GLEW_GET_FUN(__glewResumeTransformFeedback) + +#define GLEW_ARB_transform_feedback2 GLEW_GET_VAR(__GLEW_ARB_transform_feedback2) + +#endif /* GL_ARB_transform_feedback2 */ + +/* ----------------------- GL_ARB_transform_feedback3 ---------------------- */ + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 1 + +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_VERTEX_STREAMS 0x8E71 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); +typedef void (GLAPIENTRY * PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); + +#define glBeginQueryIndexed GLEW_GET_FUN(__glewBeginQueryIndexed) +#define glDrawTransformFeedbackStream GLEW_GET_FUN(__glewDrawTransformFeedbackStream) +#define glEndQueryIndexed GLEW_GET_FUN(__glewEndQueryIndexed) +#define glGetQueryIndexediv GLEW_GET_FUN(__glewGetQueryIndexediv) + +#define GLEW_ARB_transform_feedback3 GLEW_GET_VAR(__GLEW_ARB_transform_feedback3) + +#endif /* GL_ARB_transform_feedback3 */ + +/* ------------------ GL_ARB_transform_feedback_instanced ------------------ */ + +#ifndef GL_ARB_transform_feedback_instanced +#define GL_ARB_transform_feedback_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount); + +#define glDrawTransformFeedbackInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackInstanced) +#define glDrawTransformFeedbackStreamInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackStreamInstanced) + +#define GLEW_ARB_transform_feedback_instanced GLEW_GET_VAR(__GLEW_ARB_transform_feedback_instanced) + +#endif /* GL_ARB_transform_feedback_instanced */ + +/* ------------------------ 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_uniform_buffer_object --------------------- */ + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object 1 + +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data); +typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar* uniformBlockName); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const * uniformNames, GLuint* uniformIndices); +typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + +#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase) +#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange) +#define glGetActiveUniformBlockName GLEW_GET_FUN(__glewGetActiveUniformBlockName) +#define glGetActiveUniformBlockiv GLEW_GET_FUN(__glewGetActiveUniformBlockiv) +#define glGetActiveUniformName GLEW_GET_FUN(__glewGetActiveUniformName) +#define glGetActiveUniformsiv GLEW_GET_FUN(__glewGetActiveUniformsiv) +#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v) +#define glGetUniformBlockIndex GLEW_GET_FUN(__glewGetUniformBlockIndex) +#define glGetUniformIndices GLEW_GET_FUN(__glewGetUniformIndices) +#define glUniformBlockBinding GLEW_GET_FUN(__glewUniformBlockBinding) + +#define GLEW_ARB_uniform_buffer_object GLEW_GET_VAR(__GLEW_ARB_uniform_buffer_object) + +#endif /* GL_ARB_uniform_buffer_object */ + +/* ------------------------ GL_ARB_vertex_array_bgra ----------------------- */ + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_ARB_vertex_array_bgra GLEW_GET_VAR(__GLEW_ARB_vertex_array_bgra) + +#endif /* GL_ARB_vertex_array_bgra */ + +/* ----------------------- 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_attrib_64bit ---------------------- */ + +#ifndef GL_ARB_vertex_attrib_64bit +#define GL_ARB_vertex_attrib_64bit 1 + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); + +#define glGetVertexAttribLdv GLEW_GET_FUN(__glewGetVertexAttribLdv) +#define glVertexAttribL1d GLEW_GET_FUN(__glewVertexAttribL1d) +#define glVertexAttribL1dv GLEW_GET_FUN(__glewVertexAttribL1dv) +#define glVertexAttribL2d GLEW_GET_FUN(__glewVertexAttribL2d) +#define glVertexAttribL2dv GLEW_GET_FUN(__glewVertexAttribL2dv) +#define glVertexAttribL3d GLEW_GET_FUN(__glewVertexAttribL3d) +#define glVertexAttribL3dv GLEW_GET_FUN(__glewVertexAttribL3dv) +#define glVertexAttribL4d GLEW_GET_FUN(__glewVertexAttribL4d) +#define glVertexAttribL4dv GLEW_GET_FUN(__glewVertexAttribL4dv) +#define glVertexAttribLPointer GLEW_GET_FUN(__glewVertexAttribLPointer) + +#define GLEW_ARB_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_64bit) + +#endif /* GL_ARB_vertex_attrib_64bit */ + +/* ---------------------- GL_ARB_vertex_attrib_binding --------------------- */ + +#ifndef GL_ARB_vertex_attrib_binding +#define GL_ARB_vertex_attrib_binding 1 + +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_VERTEX_BINDING_BUFFER 0x8F4F + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); + +#define glBindVertexBuffer GLEW_GET_FUN(__glewBindVertexBuffer) +#define glVertexArrayBindVertexBufferEXT GLEW_GET_FUN(__glewVertexArrayBindVertexBufferEXT) +#define glVertexArrayVertexAttribBindingEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribBindingEXT) +#define glVertexArrayVertexAttribFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribFormatEXT) +#define glVertexArrayVertexAttribIFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIFormatEXT) +#define glVertexArrayVertexAttribLFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLFormatEXT) +#define glVertexArrayVertexBindingDivisorEXT GLEW_GET_FUN(__glewVertexArrayVertexBindingDivisorEXT) +#define glVertexAttribBinding GLEW_GET_FUN(__glewVertexAttribBinding) +#define glVertexAttribFormat GLEW_GET_FUN(__glewVertexAttribFormat) +#define glVertexAttribIFormat GLEW_GET_FUN(__glewVertexAttribIFormat) +#define glVertexAttribLFormat GLEW_GET_FUN(__glewVertexAttribLFormat) +#define glVertexBindingDivisor GLEW_GET_FUN(__glewVertexBindingDivisor) + +#define GLEW_ARB_vertex_attrib_binding GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_binding) + +#endif /* GL_ARB_vertex_attrib_binding */ + +/* -------------------------- 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, void *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 GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *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, void** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void * (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, void** 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_vertex_type_10f_11f_11f_rev ------------------ */ + +#ifndef GL_ARB_vertex_type_10f_11f_11f_rev +#define GL_ARB_vertex_type_10f_11f_11f_rev 1 + +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B + +#define GLEW_ARB_vertex_type_10f_11f_11f_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_10f_11f_11f_rev) + +#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ + +/* ------------------- GL_ARB_vertex_type_2_10_10_10_rev ------------------- */ + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev 1 + +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_INT_2_10_10_10_REV 0x8D9F + +typedef void (GLAPIENTRY * PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint* value); + +#define glColorP3ui GLEW_GET_FUN(__glewColorP3ui) +#define glColorP3uiv GLEW_GET_FUN(__glewColorP3uiv) +#define glColorP4ui GLEW_GET_FUN(__glewColorP4ui) +#define glColorP4uiv GLEW_GET_FUN(__glewColorP4uiv) +#define glMultiTexCoordP1ui GLEW_GET_FUN(__glewMultiTexCoordP1ui) +#define glMultiTexCoordP1uiv GLEW_GET_FUN(__glewMultiTexCoordP1uiv) +#define glMultiTexCoordP2ui GLEW_GET_FUN(__glewMultiTexCoordP2ui) +#define glMultiTexCoordP2uiv GLEW_GET_FUN(__glewMultiTexCoordP2uiv) +#define glMultiTexCoordP3ui GLEW_GET_FUN(__glewMultiTexCoordP3ui) +#define glMultiTexCoordP3uiv GLEW_GET_FUN(__glewMultiTexCoordP3uiv) +#define glMultiTexCoordP4ui GLEW_GET_FUN(__glewMultiTexCoordP4ui) +#define glMultiTexCoordP4uiv GLEW_GET_FUN(__glewMultiTexCoordP4uiv) +#define glNormalP3ui GLEW_GET_FUN(__glewNormalP3ui) +#define glNormalP3uiv GLEW_GET_FUN(__glewNormalP3uiv) +#define glSecondaryColorP3ui GLEW_GET_FUN(__glewSecondaryColorP3ui) +#define glSecondaryColorP3uiv GLEW_GET_FUN(__glewSecondaryColorP3uiv) +#define glTexCoordP1ui GLEW_GET_FUN(__glewTexCoordP1ui) +#define glTexCoordP1uiv GLEW_GET_FUN(__glewTexCoordP1uiv) +#define glTexCoordP2ui GLEW_GET_FUN(__glewTexCoordP2ui) +#define glTexCoordP2uiv GLEW_GET_FUN(__glewTexCoordP2uiv) +#define glTexCoordP3ui GLEW_GET_FUN(__glewTexCoordP3ui) +#define glTexCoordP3uiv GLEW_GET_FUN(__glewTexCoordP3uiv) +#define glTexCoordP4ui GLEW_GET_FUN(__glewTexCoordP4ui) +#define glTexCoordP4uiv GLEW_GET_FUN(__glewTexCoordP4uiv) +#define glVertexAttribP1ui GLEW_GET_FUN(__glewVertexAttribP1ui) +#define glVertexAttribP1uiv GLEW_GET_FUN(__glewVertexAttribP1uiv) +#define glVertexAttribP2ui GLEW_GET_FUN(__glewVertexAttribP2ui) +#define glVertexAttribP2uiv GLEW_GET_FUN(__glewVertexAttribP2uiv) +#define glVertexAttribP3ui GLEW_GET_FUN(__glewVertexAttribP3ui) +#define glVertexAttribP3uiv GLEW_GET_FUN(__glewVertexAttribP3uiv) +#define glVertexAttribP4ui GLEW_GET_FUN(__glewVertexAttribP4ui) +#define glVertexAttribP4uiv GLEW_GET_FUN(__glewVertexAttribP4uiv) +#define glVertexP2ui GLEW_GET_FUN(__glewVertexP2ui) +#define glVertexP2uiv GLEW_GET_FUN(__glewVertexP2uiv) +#define glVertexP3ui GLEW_GET_FUN(__glewVertexP3ui) +#define glVertexP3uiv GLEW_GET_FUN(__glewVertexP3uiv) +#define glVertexP4ui GLEW_GET_FUN(__glewVertexP4ui) +#define glVertexP4uiv GLEW_GET_FUN(__glewVertexP4uiv) + +#define GLEW_ARB_vertex_type_2_10_10_10_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_2_10_10_10_rev) + +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +/* ------------------------- GL_ARB_viewport_array ------------------------- */ + +#ifndef GL_ARB_viewport_array +#define GL_ARB_viewport_array 1 + +#define GL_DEPTH_RANGE 0x0B70 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_MAX_VIEWPORTS 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F + +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd * v); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble* data); +typedef void (GLAPIENTRY * PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat* data); +typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint * v); +typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint * v); +typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat * v); + +#define glDepthRangeArrayv GLEW_GET_FUN(__glewDepthRangeArrayv) +#define glDepthRangeIndexed GLEW_GET_FUN(__glewDepthRangeIndexed) +#define glGetDoublei_v GLEW_GET_FUN(__glewGetDoublei_v) +#define glGetFloati_v GLEW_GET_FUN(__glewGetFloati_v) +#define glScissorArrayv GLEW_GET_FUN(__glewScissorArrayv) +#define glScissorIndexed GLEW_GET_FUN(__glewScissorIndexed) +#define glScissorIndexedv GLEW_GET_FUN(__glewScissorIndexedv) +#define glViewportArrayv GLEW_GET_FUN(__glewViewportArrayv) +#define glViewportIndexedf GLEW_GET_FUN(__glewViewportIndexedf) +#define glViewportIndexedfv GLEW_GET_FUN(__glewViewportIndexedfv) + +#define GLEW_ARB_viewport_array GLEW_GET_VAR(__GLEW_ARB_viewport_array) + +#endif /* GL_ARB_viewport_array */ + +/* --------------------------- 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_2X_BIT_ATI 0x00000001 +#define GL_RED_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_BLUE_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_meminfo ---------------------------- */ + +#ifndef GL_ATI_meminfo +#define GL_ATI_meminfo 1 + +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD + +#define GLEW_ATI_meminfo GLEW_GET_VAR(__GLEW_ATI_meminfo) + +#endif /* GL_ATI_meminfo */ + +/* -------------------------- 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(__glewPNTrianglesfATI) +#define glPNTrianglesiATI GLEW_GET_FUN(__glewPNTrianglesiATI) + +#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 *coords); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); + +#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 glVertexStream1dATI GLEW_GET_FUN(__glewVertexStream1dATI) +#define glVertexStream1dvATI GLEW_GET_FUN(__glewVertexStream1dvATI) +#define glVertexStream1fATI GLEW_GET_FUN(__glewVertexStream1fATI) +#define glVertexStream1fvATI GLEW_GET_FUN(__glewVertexStream1fvATI) +#define glVertexStream1iATI GLEW_GET_FUN(__glewVertexStream1iATI) +#define glVertexStream1ivATI GLEW_GET_FUN(__glewVertexStream1ivATI) +#define glVertexStream1sATI GLEW_GET_FUN(__glewVertexStream1sATI) +#define glVertexStream1svATI GLEW_GET_FUN(__glewVertexStream1svATI) +#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 + +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC + +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_debug_label -------------------------- */ + +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 + +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 + +typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei* length, GLchar *label); +typedef void (GLAPIENTRY * PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar* label); + +#define glGetObjectLabelEXT GLEW_GET_FUN(__glewGetObjectLabelEXT) +#define glLabelObjectEXT GLEW_GET_FUN(__glewLabelObjectEXT) + +#define GLEW_EXT_debug_label GLEW_GET_VAR(__GLEW_EXT_debug_label) + +#endif /* GL_EXT_debug_label */ + +/* -------------------------- GL_EXT_debug_marker -------------------------- */ + +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 + +typedef void (GLAPIENTRY * PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar* marker); +typedef void (GLAPIENTRY * PFNGLPOPGROUPMARKEREXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar* marker); + +#define glInsertEventMarkerEXT GLEW_GET_FUN(__glewInsertEventMarkerEXT) +#define glPopGroupMarkerEXT GLEW_GET_FUN(__glewPopGroupMarkerEXT) +#define glPushGroupMarkerEXT GLEW_GET_FUN(__glewPushGroupMarkerEXT) + +#define GLEW_EXT_debug_marker GLEW_GET_VAR(__GLEW_EXT_debug_marker) + +#endif /* GL_EXT_debug_marker */ + +/* ------------------------ 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 * PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +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 target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATI_VEXTPROC) (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 target, GLuint index, void** params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void** 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 void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void** param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void** param); +typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield 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 * PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +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); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); + +#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 glDisableClientStateiEXT GLEW_GET_FUN(__glewDisableClientStateiEXT) +#define glDisableVertexArrayAttribEXT GLEW_GET_FUN(__glewDisableVertexArrayAttribEXT) +#define glDisableVertexArrayEXT GLEW_GET_FUN(__glewDisableVertexArrayEXT) +#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT) +#define glEnableClientStateiEXT GLEW_GET_FUN(__glewEnableClientStateiEXT) +#define glEnableVertexArrayAttribEXT GLEW_GET_FUN(__glewEnableVertexArrayAttribEXT) +#define glEnableVertexArrayEXT GLEW_GET_FUN(__glewEnableVertexArrayEXT) +#define glFlushMappedNamedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedNamedBufferRangeEXT) +#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 glGetDoublei_vEXT GLEW_GET_FUN(__glewGetDoublei_vEXT) +#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT) +#define glGetFloati_vEXT GLEW_GET_FUN(__glewGetFloati_vEXT) +#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 glGetPointeri_vEXT GLEW_GET_FUN(__glewGetPointeri_vEXT) +#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 glGetVertexArrayIntegeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayIntegeri_vEXT) +#define glGetVertexArrayIntegervEXT GLEW_GET_FUN(__glewGetVertexArrayIntegervEXT) +#define glGetVertexArrayPointeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayPointeri_vEXT) +#define glGetVertexArrayPointervEXT GLEW_GET_FUN(__glewGetVertexArrayPointervEXT) +#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT) +#define glMapNamedBufferRangeEXT GLEW_GET_FUN(__glewMapNamedBufferRangeEXT) +#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 glNamedCopyBufferSubDataEXT GLEW_GET_FUN(__glewNamedCopyBufferSubDataEXT) +#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 glVertexArrayColorOffsetEXT GLEW_GET_FUN(__glewVertexArrayColorOffsetEXT) +#define glVertexArrayEdgeFlagOffsetEXT GLEW_GET_FUN(__glewVertexArrayEdgeFlagOffsetEXT) +#define glVertexArrayFogCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayFogCoordOffsetEXT) +#define glVertexArrayIndexOffsetEXT GLEW_GET_FUN(__glewVertexArrayIndexOffsetEXT) +#define glVertexArrayMultiTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayMultiTexCoordOffsetEXT) +#define glVertexArrayNormalOffsetEXT GLEW_GET_FUN(__glewVertexArrayNormalOffsetEXT) +#define glVertexArraySecondaryColorOffsetEXT GLEW_GET_FUN(__glewVertexArraySecondaryColorOffsetEXT) +#define glVertexArrayTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayTexCoordOffsetEXT) +#define glVertexArrayVertexAttribDivisorEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribDivisorEXT) +#define glVertexArrayVertexAttribIOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIOffsetEXT) +#define glVertexArrayVertexAttribOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribOffsetEXT) +#define glVertexArrayVertexOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexOffsetEXT) + +#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 void *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_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 + +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *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 void *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_multisample_blit_scaled -------------- */ + +#ifndef GL_EXT_framebuffer_multisample_blit_scaled +#define GL_EXT_framebuffer_multisample_blit_scaled 1 + +#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB + +#define GLEW_EXT_framebuffer_multisample_blit_scaled GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample_blit_scaled) + +#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ + +/* ----------------------- 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 * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT) +#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT) +#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 void *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 + +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, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const void *const *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_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, const 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_provoking_vertex ------------------------ */ + +#ifndef GL_EXT_provoking_vertex +#define GL_EXT_provoking_vertex 1 + +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_PROVOKING_VERTEX_EXT 0x8E4F + +typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); + +#define glProvokingVertexEXT GLEW_GET_FUN(__glewProvokingVertexEXT) + +#define GLEW_EXT_provoking_vertex GLEW_GET_VAR(__GLEW_EXT_provoking_vertex) + +#endif /* GL_EXT_provoking_vertex */ + +/* ------------------------- 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, const void *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_shader_objects -------------------- */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 + +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D + +typedef void (GLAPIENTRY * PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar* string); +typedef void (GLAPIENTRY * PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); + +#define glActiveProgramEXT GLEW_GET_FUN(__glewActiveProgramEXT) +#define glCreateShaderProgramEXT GLEW_GET_FUN(__glewCreateShaderProgramEXT) +#define glUseShaderProgramEXT GLEW_GET_FUN(__glewUseShaderProgramEXT) + +#define GLEW_EXT_separate_shader_objects GLEW_GET_VAR(__GLEW_EXT_separate_shader_objects) + +#endif /* GL_EXT_separate_shader_objects */ + +/* --------------------- 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_shader_image_load_formatted ------------------ */ + +#ifndef GL_EXT_shader_image_load_formatted +#define GL_EXT_shader_image_load_formatted 1 + +#define GLEW_EXT_shader_image_load_formatted GLEW_GET_VAR(__GLEW_EXT_shader_image_load_formatted) + +#endif /* GL_EXT_shader_image_load_formatted */ + +/* --------------------- GL_EXT_shader_image_load_store -------------------- */ + +#ifndef GL_EXT_shader_image_load_store +#define GL_EXT_shader_image_load_store 1 + +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 +#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 +#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A +#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B +#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C +#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D +#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E +#define GL_IMAGE_1D_EXT 0x904C +#define GL_IMAGE_2D_EXT 0x904D +#define GL_IMAGE_3D_EXT 0x904E +#define GL_IMAGE_2D_RECT_EXT 0x904F +#define GL_IMAGE_CUBE_EXT 0x9050 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_IMAGE_1D_ARRAY_EXT 0x9052 +#define GL_IMAGE_2D_ARRAY_EXT 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 +#define GL_INT_IMAGE_1D_EXT 0x9057 +#define GL_INT_IMAGE_2D_EXT 0x9058 +#define GL_INT_IMAGE_3D_EXT 0x9059 +#define GL_INT_IMAGE_2D_RECT_EXT 0x905A +#define GL_INT_IMAGE_CUBE_EXT 0x905B +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D +#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C +#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D +#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E +#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +typedef void (GLAPIENTRY * PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); + +#define glBindImageTextureEXT GLEW_GET_FUN(__glewBindImageTextureEXT) +#define glMemoryBarrierEXT GLEW_GET_FUN(__glewMemoryBarrierEXT) + +#define GLEW_EXT_shader_image_load_store GLEW_GET_VAR(__GLEW_EXT_shader_image_load_store) + +#endif /* GL_EXT_shader_image_load_store */ + +/* ----------------------- GL_EXT_shader_integer_mix ----------------------- */ + +#ifndef GL_EXT_shader_integer_mix +#define GL_EXT_shader_integer_mix 1 + +#define GLEW_EXT_shader_integer_mix GLEW_GET_VAR(__GLEW_EXT_shader_integer_mix) + +#endif /* GL_EXT_shader_integer_mix */ + +/* -------------------------- 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 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + +#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT) + +#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 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 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_sRGB_decode ---------------------- */ + +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 + +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A + +#define GLEW_EXT_texture_sRGB_decode GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_decode) + +#endif /* GL_EXT_texture_sRGB_decode */ + +/* --------------------- 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_snorm ------------------------- */ + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm 1 + +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_ALPHA_SNORM 0x9010 +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_ALPHA8_SNORM 0x9014 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_ALPHA16_SNORM 0x9018 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_INTENSITY16_SNORM 0x901B + +#define GLEW_EXT_texture_snorm GLEW_GET_VAR(__GLEW_EXT_texture_snorm) + +#endif /* GL_EXT_texture_snorm */ + +/* ------------------------- 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, GLchar *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar * const* 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 * 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 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_attrib_64bit ---------------------- */ + +#ifndef GL_EXT_vertex_attrib_64bit +#define GL_EXT_vertex_attrib_64bit 1 + +#define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_MAT2x3_EXT 0x8F49 +#define GL_DOUBLE_MAT2x4_EXT 0x8F4A +#define GL_DOUBLE_MAT3x2_EXT 0x8F4B +#define GL_DOUBLE_MAT3x4_EXT 0x8F4C +#define GL_DOUBLE_MAT4x2_EXT 0x8F4D +#define GL_DOUBLE_MAT4x3_EXT 0x8F4E +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4_EXT 0x8FFE + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + +#define glGetVertexAttribLdvEXT GLEW_GET_FUN(__glewGetVertexAttribLdvEXT) +#define glVertexArrayVertexAttribLOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLOffsetEXT) +#define glVertexAttribL1dEXT GLEW_GET_FUN(__glewVertexAttribL1dEXT) +#define glVertexAttribL1dvEXT GLEW_GET_FUN(__glewVertexAttribL1dvEXT) +#define glVertexAttribL2dEXT GLEW_GET_FUN(__glewVertexAttribL2dEXT) +#define glVertexAttribL2dvEXT GLEW_GET_FUN(__glewVertexAttribL2dvEXT) +#define glVertexAttribL3dEXT GLEW_GET_FUN(__glewVertexAttribL3dEXT) +#define glVertexAttribL3dvEXT GLEW_GET_FUN(__glewVertexAttribL3dvEXT) +#define glVertexAttribL4dEXT GLEW_GET_FUN(__glewVertexAttribL4dEXT) +#define glVertexAttribL4dvEXT GLEW_GET_FUN(__glewVertexAttribL4dvEXT) +#define glVertexAttribLPointerEXT GLEW_GET_FUN(__glewVertexAttribLPointerEXT) + +#define GLEW_EXT_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_EXT_vertex_attrib_64bit) + +#endif /* GL_EXT_vertex_attrib_64bit */ + +/* -------------------------- 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, void **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, void *addr); +typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, void *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, void *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_EXT_x11_sync_object ------------------------ */ + +#ifndef GL_EXT_x11_sync_object +#define GL_EXT_x11_sync_object 1 + +#define GL_SYNC_X11_FENCE_EXT 0x90E1 + +typedef GLsync (GLAPIENTRY * PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); + +#define glImportSyncEXT GLEW_GET_FUN(__glewImportSyncEXT) + +#define GLEW_EXT_x11_sync_object GLEW_GET_VAR(__GLEW_EXT_x11_sync_object) + +#endif /* GL_EXT_x11_sync_object */ + +/* ---------------------- 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 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 void *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 void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** 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_fragment_shader_ordering ------------------- */ + +#ifndef GL_INTEL_fragment_shader_ordering +#define GL_INTEL_fragment_shader_ordering 1 + +#define GLEW_INTEL_fragment_shader_ordering GLEW_GET_VAR(__GLEW_INTEL_fragment_shader_ordering) + +#endif /* GL_INTEL_fragment_shader_ordering */ + +/* -------------------------- GL_INTEL_map_texture ------------------------- */ + +#ifndef GL_INTEL_map_texture +#define GL_INTEL_map_texture 1 + +#define GL_LAYOUT_DEFAULT_INTEL 0 +#define GL_LAYOUT_LINEAR_INTEL 1 +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF + +typedef void * (GLAPIENTRY * PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint* stride, GLenum *layout); +typedef void (GLAPIENTRY * PFNGLSYNCTEXTUREINTELPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); + +#define glMapTexture2DINTEL GLEW_GET_FUN(__glewMapTexture2DINTEL) +#define glSyncTextureINTEL GLEW_GET_FUN(__glewSyncTextureINTEL) +#define glUnmapTexture2DINTEL GLEW_GET_FUN(__glewUnmapTexture2DINTEL) + +#define GLEW_INTEL_map_texture GLEW_GET_VAR(__GLEW_INTEL_map_texture) + +#endif /* GL_INTEL_map_texture */ + +/* ------------------------ 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_performance_query ---------------------- */ + +#ifndef GL_INTEL_performance_query +#define GL_INTEL_performance_query 1 + +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x0000 +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x0001 +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 +#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 +#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 +#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 +#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 +#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 +#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 +#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 +#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA +#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB +#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC +#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD +#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE +#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF +#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 + +typedef void (GLAPIENTRY * PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GLAPIENTRY * PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint* queryHandle); +typedef void (GLAPIENTRY * PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GLAPIENTRY * PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GLAPIENTRY * PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint* queryId); +typedef void (GLAPIENTRY * PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint* nextQueryId); +typedef void (GLAPIENTRY * PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar* counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +typedef void (GLAPIENTRY * PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); +typedef void (GLAPIENTRY * PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar* queryName, GLuint *queryId); +typedef void (GLAPIENTRY * PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar* queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); + +#define glBeginPerfQueryINTEL GLEW_GET_FUN(__glewBeginPerfQueryINTEL) +#define glCreatePerfQueryINTEL GLEW_GET_FUN(__glewCreatePerfQueryINTEL) +#define glDeletePerfQueryINTEL GLEW_GET_FUN(__glewDeletePerfQueryINTEL) +#define glEndPerfQueryINTEL GLEW_GET_FUN(__glewEndPerfQueryINTEL) +#define glGetFirstPerfQueryIdINTEL GLEW_GET_FUN(__glewGetFirstPerfQueryIdINTEL) +#define glGetNextPerfQueryIdINTEL GLEW_GET_FUN(__glewGetNextPerfQueryIdINTEL) +#define glGetPerfCounterInfoINTEL GLEW_GET_FUN(__glewGetPerfCounterInfoINTEL) +#define glGetPerfQueryDataINTEL GLEW_GET_FUN(__glewGetPerfQueryDataINTEL) +#define glGetPerfQueryIdByNameINTEL GLEW_GET_FUN(__glewGetPerfQueryIdByNameINTEL) +#define glGetPerfQueryInfoINTEL GLEW_GET_FUN(__glewGetPerfQueryInfoINTEL) + +#define GLEW_INTEL_performance_query GLEW_GET_VAR(__GLEW_INTEL_performance_query) + +#endif /* GL_INTEL_performance_query */ + +/* ------------------------ 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_KHR_debug ----------------------------- */ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 + +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_DISPLAY_LIST 0x82E7 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_OUTPUT 0x92E0 + +typedef void (GLAPIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); + +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); +typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); +typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar *label); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei* length, GLchar *label); +typedef void (GLAPIENTRY * PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar* label); +typedef void (GLAPIENTRY * PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar* label); +typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (void); +typedef void (GLAPIENTRY * PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar * message); + +#define glDebugMessageCallback GLEW_GET_FUN(__glewDebugMessageCallback) +#define glDebugMessageControl GLEW_GET_FUN(__glewDebugMessageControl) +#define glDebugMessageInsert GLEW_GET_FUN(__glewDebugMessageInsert) +#define glGetDebugMessageLog GLEW_GET_FUN(__glewGetDebugMessageLog) +#define glGetObjectLabel GLEW_GET_FUN(__glewGetObjectLabel) +#define glGetObjectPtrLabel GLEW_GET_FUN(__glewGetObjectPtrLabel) +#define glObjectLabel GLEW_GET_FUN(__glewObjectLabel) +#define glObjectPtrLabel GLEW_GET_FUN(__glewObjectPtrLabel) +#define glPopDebugGroup GLEW_GET_FUN(__glewPopDebugGroup) +#define glPushDebugGroup GLEW_GET_FUN(__glewPushDebugGroup) + +#define GLEW_KHR_debug GLEW_GET_VAR(__GLEW_KHR_debug) + +#endif /* GL_KHR_debug */ + +/* ------------------ GL_KHR_texture_compression_astc_hdr ------------------ */ + +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 + +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD + +#define GLEW_KHR_texture_compression_astc_hdr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_hdr) + +#endif /* GL_KHR_texture_compression_astc_hdr */ + +/* ------------------ GL_KHR_texture_compression_astc_ldr ------------------ */ + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 + +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD + +#define GLEW_KHR_texture_compression_astc_ldr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_ldr) + +#endif /* GL_KHR_texture_compression_astc_ldr */ + +/* -------------------------- 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 * PFNGLBUFFERREGIONENABLEDPROC) (void); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); +typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glBufferRegionEnabled GLEW_GET_FUN(__glewBufferRegionEnabled) +#define glDeleteBufferRegion GLEW_GET_FUN(__glewDeleteBufferRegion) +#define glDrawBufferRegion GLEW_GET_FUN(__glewDrawBufferRegion) +#define glNewBufferRegion GLEW_GET_FUN(__glewNewBufferRegion) +#define glReadBufferRegion GLEW_GET_FUN(__glewReadBufferRegion) + +#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_NVX_conditional_render ----------------------- */ + +#ifndef GL_NVX_conditional_render +#define GL_NVX_conditional_render 1 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVXPROC) (void); + +#define glBeginConditionalRenderNVX GLEW_GET_FUN(__glewBeginConditionalRenderNVX) +#define glEndConditionalRenderNVX GLEW_GET_FUN(__glewEndConditionalRenderNVX) + +#define GLEW_NVX_conditional_render GLEW_GET_VAR(__GLEW_NVX_conditional_render) + +#endif /* GL_NVX_conditional_render */ + +/* ------------------------- GL_NVX_gpu_memory_info ------------------------ */ + +#ifndef GL_NVX_gpu_memory_info +#define GL_NVX_gpu_memory_info 1 + +#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 +#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 +#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 +#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A +#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B + +#define GLEW_NVX_gpu_memory_info GLEW_GET_VAR(__GLEW_NVX_gpu_memory_info) + +#endif /* GL_NVX_gpu_memory_info */ + +/* ------------------- GL_NV_bindless_multi_draw_indirect ------------------ */ + +#ifndef GL_NV_bindless_multi_draw_indirect +#define GL_NV_bindless_multi_draw_indirect 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); + +#define glMultiDrawArraysIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawArraysIndirectBindlessNV) +#define glMultiDrawElementsIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawElementsIndirectBindlessNV) + +#define GLEW_NV_bindless_multi_draw_indirect GLEW_GET_VAR(__GLEW_NV_bindless_multi_draw_indirect) + +#endif /* GL_NV_bindless_multi_draw_indirect */ + +/* ------------------------- GL_NV_bindless_texture ------------------------ */ + +#ifndef GL_NV_bindless_texture +#define GL_NV_bindless_texture 1 + +typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); +typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); +typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); +typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values); +typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); +typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64* value); + +#define glGetImageHandleNV GLEW_GET_FUN(__glewGetImageHandleNV) +#define glGetTextureHandleNV GLEW_GET_FUN(__glewGetTextureHandleNV) +#define glGetTextureSamplerHandleNV GLEW_GET_FUN(__glewGetTextureSamplerHandleNV) +#define glIsImageHandleResidentNV GLEW_GET_FUN(__glewIsImageHandleResidentNV) +#define glIsTextureHandleResidentNV GLEW_GET_FUN(__glewIsTextureHandleResidentNV) +#define glMakeImageHandleNonResidentNV GLEW_GET_FUN(__glewMakeImageHandleNonResidentNV) +#define glMakeImageHandleResidentNV GLEW_GET_FUN(__glewMakeImageHandleResidentNV) +#define glMakeTextureHandleNonResidentNV GLEW_GET_FUN(__glewMakeTextureHandleNonResidentNV) +#define glMakeTextureHandleResidentNV GLEW_GET_FUN(__glewMakeTextureHandleResidentNV) +#define glProgramUniformHandleui64NV GLEW_GET_FUN(__glewProgramUniformHandleui64NV) +#define glProgramUniformHandleui64vNV GLEW_GET_FUN(__glewProgramUniformHandleui64vNV) +#define glUniformHandleui64NV GLEW_GET_FUN(__glewUniformHandleui64NV) +#define glUniformHandleui64vNV GLEW_GET_FUN(__glewUniformHandleui64vNV) + +#define GLEW_NV_bindless_texture GLEW_GET_VAR(__GLEW_NV_bindless_texture) + +#endif /* GL_NV_bindless_texture */ + +/* --------------------- GL_NV_blend_equation_advanced --------------------- */ + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 + +#define GL_XOR_NV 0x1506 +#define GL_RED_NV 0x1903 +#define GL_GREEN_NV 0x1904 +#define GL_BLUE_NV 0x1905 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_DISJOINT_NV 0x9283 +#define GL_CONJOINT_NV 0x9284 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#define GL_SRC_NV 0x9286 +#define GL_DST_NV 0x9287 +#define GL_SRC_OVER_NV 0x9288 +#define GL_DST_OVER_NV 0x9289 +#define GL_SRC_IN_NV 0x928A +#define GL_DST_IN_NV 0x928B +#define GL_SRC_OUT_NV 0x928C +#define GL_DST_OUT_NV 0x928D +#define GL_SRC_ATOP_NV 0x928E +#define GL_DST_ATOP_NV 0x928F +#define GL_PLUS_NV 0x9291 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_MULTIPLY_NV 0x9294 +#define GL_SCREEN_NV 0x9295 +#define GL_OVERLAY_NV 0x9296 +#define GL_DARKEN_NV 0x9297 +#define GL_LIGHTEN_NV 0x9298 +#define GL_COLORDODGE_NV 0x9299 +#define GL_COLORBURN_NV 0x929A +#define GL_HARDLIGHT_NV 0x929B +#define GL_SOFTLIGHT_NV 0x929C +#define GL_DIFFERENCE_NV 0x929E +#define GL_MINUS_NV 0x929F +#define GL_EXCLUSION_NV 0x92A0 +#define GL_CONTRAST_NV 0x92A1 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_INVERT_OVG_NV 0x92B4 + +typedef void (GLAPIENTRY * PFNGLBLENDBARRIERNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); + +#define glBlendBarrierNV GLEW_GET_FUN(__glewBlendBarrierNV) +#define glBlendParameteriNV GLEW_GET_FUN(__glewBlendParameteriNV) + +#define GLEW_NV_blend_equation_advanced GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced) + +#endif /* GL_NV_blend_equation_advanced */ + +/* ----------------- GL_NV_blend_equation_advanced_coherent ---------------- */ + +#ifndef GL_NV_blend_equation_advanced_coherent +#define GL_NV_blend_equation_advanced_coherent 1 + +#define GLEW_NV_blend_equation_advanced_coherent GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced_coherent) + +#endif /* GL_NV_blend_equation_advanced_coherent */ + +/* --------------------------- 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_compute_program5 ------------------------ */ + +#ifndef GL_NV_compute_program5 +#define GL_NV_compute_program5 1 + +#define GL_COMPUTE_PROGRAM_NV 0x90FB +#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC + +#define GLEW_NV_compute_program5 GLEW_GET_VAR(__GLEW_NV_compute_program5) + +#endif /* GL_NV_compute_program5 */ + +/* ------------------------ 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_copy_image --------------------------- */ + +#ifndef GL_NV_copy_image +#define GL_NV_copy_image 1 + +typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + +#define glCopyImageSubDataNV GLEW_GET_FUN(__glewCopyImageSubDataNV) + +#define GLEW_NV_copy_image GLEW_GET_VAR(__GLEW_NV_copy_image) + +#endif /* GL_NV_copy_image */ + +/* -------------------------- GL_NV_deep_texture3D ------------------------- */ + +#ifndef GL_NV_deep_texture3D +#define GL_NV_deep_texture3D 1 + +#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 +#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 + +#define GLEW_NV_deep_texture3D GLEW_GET_VAR(__GLEW_NV_deep_texture3D) + +#endif /* GL_NV_deep_texture3D */ + +/* ------------------------ 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_draw_texture -------------------------- */ + +#ifndef GL_NV_draw_texture +#define GL_NV_draw_texture 1 + +typedef void (GLAPIENTRY * PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); + +#define glDrawTextureNV GLEW_GET_FUN(__glewDrawTextureNV) + +#define GLEW_NV_draw_texture GLEW_GET_VAR(__GLEW_NV_draw_texture) + +#endif /* GL_NV_draw_texture */ + +/* ---------------------------- 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_gpu_program5 -------------------------- */ + +#ifndef GL_NV_gpu_program5 +#define GL_NV_gpu_program5 1 + +#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C +#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F + +#define GLEW_NV_gpu_program5 GLEW_GET_VAR(__GLEW_NV_gpu_program5) + +#endif /* GL_NV_gpu_program5 */ + +/* -------------------- GL_NV_gpu_program5_mem_extended -------------------- */ + +#ifndef GL_NV_gpu_program5_mem_extended +#define GL_NV_gpu_program5_mem_extended 1 + +#define GLEW_NV_gpu_program5_mem_extended GLEW_GET_VAR(__GLEW_NV_gpu_program5_mem_extended) + +#endif /* GL_NV_gpu_program5_mem_extended */ + +/* ------------------------- GL_NV_gpu_program_fp64 ------------------------ */ + +#ifndef GL_NV_gpu_program_fp64 +#define GL_NV_gpu_program_fp64 1 + +#define GLEW_NV_gpu_program_fp64 GLEW_GET_VAR(__GLEW_NV_gpu_program_fp64) + +#endif /* GL_NV_gpu_program_fp64 */ + +/* --------------------------- GL_NV_gpu_shader5 --------------------------- */ + +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 + +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB + +typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); + +#define glGetUniformi64vNV GLEW_GET_FUN(__glewGetUniformi64vNV) +#define glGetUniformui64vNV GLEW_GET_FUN(__glewGetUniformui64vNV) +#define glProgramUniform1i64NV GLEW_GET_FUN(__glewProgramUniform1i64NV) +#define glProgramUniform1i64vNV GLEW_GET_FUN(__glewProgramUniform1i64vNV) +#define glProgramUniform1ui64NV GLEW_GET_FUN(__glewProgramUniform1ui64NV) +#define glProgramUniform1ui64vNV GLEW_GET_FUN(__glewProgramUniform1ui64vNV) +#define glProgramUniform2i64NV GLEW_GET_FUN(__glewProgramUniform2i64NV) +#define glProgramUniform2i64vNV GLEW_GET_FUN(__glewProgramUniform2i64vNV) +#define glProgramUniform2ui64NV GLEW_GET_FUN(__glewProgramUniform2ui64NV) +#define glProgramUniform2ui64vNV GLEW_GET_FUN(__glewProgramUniform2ui64vNV) +#define glProgramUniform3i64NV GLEW_GET_FUN(__glewProgramUniform3i64NV) +#define glProgramUniform3i64vNV GLEW_GET_FUN(__glewProgramUniform3i64vNV) +#define glProgramUniform3ui64NV GLEW_GET_FUN(__glewProgramUniform3ui64NV) +#define glProgramUniform3ui64vNV GLEW_GET_FUN(__glewProgramUniform3ui64vNV) +#define glProgramUniform4i64NV GLEW_GET_FUN(__glewProgramUniform4i64NV) +#define glProgramUniform4i64vNV GLEW_GET_FUN(__glewProgramUniform4i64vNV) +#define glProgramUniform4ui64NV GLEW_GET_FUN(__glewProgramUniform4ui64NV) +#define glProgramUniform4ui64vNV GLEW_GET_FUN(__glewProgramUniform4ui64vNV) +#define glUniform1i64NV GLEW_GET_FUN(__glewUniform1i64NV) +#define glUniform1i64vNV GLEW_GET_FUN(__glewUniform1i64vNV) +#define glUniform1ui64NV GLEW_GET_FUN(__glewUniform1ui64NV) +#define glUniform1ui64vNV GLEW_GET_FUN(__glewUniform1ui64vNV) +#define glUniform2i64NV GLEW_GET_FUN(__glewUniform2i64NV) +#define glUniform2i64vNV GLEW_GET_FUN(__glewUniform2i64vNV) +#define glUniform2ui64NV GLEW_GET_FUN(__glewUniform2ui64NV) +#define glUniform2ui64vNV GLEW_GET_FUN(__glewUniform2ui64vNV) +#define glUniform3i64NV GLEW_GET_FUN(__glewUniform3i64NV) +#define glUniform3i64vNV GLEW_GET_FUN(__glewUniform3i64vNV) +#define glUniform3ui64NV GLEW_GET_FUN(__glewUniform3ui64NV) +#define glUniform3ui64vNV GLEW_GET_FUN(__glewUniform3ui64vNV) +#define glUniform4i64NV GLEW_GET_FUN(__glewUniform4i64NV) +#define glUniform4i64vNV GLEW_GET_FUN(__glewUniform4i64vNV) +#define glUniform4ui64NV GLEW_GET_FUN(__glewUniform4ui64NV) +#define glUniform4ui64vNV GLEW_GET_FUN(__glewUniform4ui64vNV) + +#define GLEW_NV_gpu_shader5 GLEW_GET_VAR(__GLEW_NV_gpu_shader5) + +#endif /* GL_NV_gpu_shader5 */ + +/* ---------------------------- 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_coverage ---------------------- */ + +#ifndef GL_NV_multisample_coverage +#define GL_NV_multisample_coverage 1 + +#define GL_COLOR_SAMPLES_NV 0x8E20 + +#define GLEW_NV_multisample_coverage GLEW_GET_VAR(__GLEW_NV_multisample_coverage) + +#endif /* GL_NV_multisample_coverage */ + +/* --------------------- 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_parameter_buffer_object2 -------------------- */ + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 1 + +#define GLEW_NV_parameter_buffer_object2 GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object2) + +#endif /* GL_NV_parameter_buffer_object2 */ + +/* -------------------------- GL_NV_path_rendering ------------------------- */ + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 + +#define GL_CLOSE_PATH_NV 0x00 +#define GL_BOLD_BIT_NV 0x01 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 + +typedef void (GLAPIENTRY * PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); +typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHNVPROC) (GLuint name, GLenum coverMode); +typedef void (GLAPIENTRY * PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); +typedef GLuint (GLAPIENTRY * PFNGLGENPATHSNVPROC) (GLsizei range); +typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat* value); +typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint* value); +typedef void (GLAPIENTRY * PFNGLGETPATHCOMMANDSNVPROC) (GLuint name, GLubyte* commands); +typedef void (GLAPIENTRY * PFNGLGETPATHCOORDSNVPROC) (GLuint name, GLfloat* coords); +typedef void (GLAPIENTRY * PFNGLGETPATHDASHARRAYNVPROC) (GLuint name, GLfloat* dashArray); +typedef GLfloat (GLAPIENTRY * PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef void (GLAPIENTRY * PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint fistPathName, GLsizei numPaths, GLsizei stride, GLfloat* metrics); +typedef void (GLAPIENTRY * PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERFVNVPROC) (GLuint name, GLenum param, GLfloat* value); +typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERIVNVPROC) (GLuint name, GLenum param, GLint* value); +typedef void (GLAPIENTRY * PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat* value); +typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint* value); +typedef void (GLAPIENTRY * PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +typedef GLboolean (GLAPIENTRY * PFNGLISPATHNVPROC) (GLuint path); +typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat* coeffs); +typedef void (GLAPIENTRY * PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const void*coords); +typedef void (GLAPIENTRY * PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void* coords); +typedef void (GLAPIENTRY * PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum zfunc); +typedef void (GLAPIENTRY * PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat* dashArray); +typedef void (GLAPIENTRY * PFNGLPATHFOGGENNVPROC) (GLenum genMode); +typedef void (GLAPIENTRY * PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void* fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GLAPIENTRY * PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void* fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void*charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); +typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); +typedef void (GLAPIENTRY * PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); +typedef void (GLAPIENTRY * PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void* pathString); +typedef void (GLAPIENTRY * PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const void*coords); +typedef void (GLAPIENTRY * PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void* coords); +typedef void (GLAPIENTRY * PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat* coeffs); +typedef GLboolean (GLAPIENTRY * PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat* x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); +typedef void (GLAPIENTRY * PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat* transformValues); +typedef void (GLAPIENTRY * PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint paths[], const GLfloat weights[]); + +#define glCopyPathNV GLEW_GET_FUN(__glewCopyPathNV) +#define glCoverFillPathInstancedNV GLEW_GET_FUN(__glewCoverFillPathInstancedNV) +#define glCoverFillPathNV GLEW_GET_FUN(__glewCoverFillPathNV) +#define glCoverStrokePathInstancedNV GLEW_GET_FUN(__glewCoverStrokePathInstancedNV) +#define glCoverStrokePathNV GLEW_GET_FUN(__glewCoverStrokePathNV) +#define glDeletePathsNV GLEW_GET_FUN(__glewDeletePathsNV) +#define glGenPathsNV GLEW_GET_FUN(__glewGenPathsNV) +#define glGetPathColorGenfvNV GLEW_GET_FUN(__glewGetPathColorGenfvNV) +#define glGetPathColorGenivNV GLEW_GET_FUN(__glewGetPathColorGenivNV) +#define glGetPathCommandsNV GLEW_GET_FUN(__glewGetPathCommandsNV) +#define glGetPathCoordsNV GLEW_GET_FUN(__glewGetPathCoordsNV) +#define glGetPathDashArrayNV GLEW_GET_FUN(__glewGetPathDashArrayNV) +#define glGetPathLengthNV GLEW_GET_FUN(__glewGetPathLengthNV) +#define glGetPathMetricRangeNV GLEW_GET_FUN(__glewGetPathMetricRangeNV) +#define glGetPathMetricsNV GLEW_GET_FUN(__glewGetPathMetricsNV) +#define glGetPathParameterfvNV GLEW_GET_FUN(__glewGetPathParameterfvNV) +#define glGetPathParameterivNV GLEW_GET_FUN(__glewGetPathParameterivNV) +#define glGetPathSpacingNV GLEW_GET_FUN(__glewGetPathSpacingNV) +#define glGetPathTexGenfvNV GLEW_GET_FUN(__glewGetPathTexGenfvNV) +#define glGetPathTexGenivNV GLEW_GET_FUN(__glewGetPathTexGenivNV) +#define glInterpolatePathsNV GLEW_GET_FUN(__glewInterpolatePathsNV) +#define glIsPathNV GLEW_GET_FUN(__glewIsPathNV) +#define glIsPointInFillPathNV GLEW_GET_FUN(__glewIsPointInFillPathNV) +#define glIsPointInStrokePathNV GLEW_GET_FUN(__glewIsPointInStrokePathNV) +#define glPathColorGenNV GLEW_GET_FUN(__glewPathColorGenNV) +#define glPathCommandsNV GLEW_GET_FUN(__glewPathCommandsNV) +#define glPathCoordsNV GLEW_GET_FUN(__glewPathCoordsNV) +#define glPathCoverDepthFuncNV GLEW_GET_FUN(__glewPathCoverDepthFuncNV) +#define glPathDashArrayNV GLEW_GET_FUN(__glewPathDashArrayNV) +#define glPathFogGenNV GLEW_GET_FUN(__glewPathFogGenNV) +#define glPathGlyphRangeNV GLEW_GET_FUN(__glewPathGlyphRangeNV) +#define glPathGlyphsNV GLEW_GET_FUN(__glewPathGlyphsNV) +#define glPathParameterfNV GLEW_GET_FUN(__glewPathParameterfNV) +#define glPathParameterfvNV GLEW_GET_FUN(__glewPathParameterfvNV) +#define glPathParameteriNV GLEW_GET_FUN(__glewPathParameteriNV) +#define glPathParameterivNV GLEW_GET_FUN(__glewPathParameterivNV) +#define glPathStencilDepthOffsetNV GLEW_GET_FUN(__glewPathStencilDepthOffsetNV) +#define glPathStencilFuncNV GLEW_GET_FUN(__glewPathStencilFuncNV) +#define glPathStringNV GLEW_GET_FUN(__glewPathStringNV) +#define glPathSubCommandsNV GLEW_GET_FUN(__glewPathSubCommandsNV) +#define glPathSubCoordsNV GLEW_GET_FUN(__glewPathSubCoordsNV) +#define glPathTexGenNV GLEW_GET_FUN(__glewPathTexGenNV) +#define glPointAlongPathNV GLEW_GET_FUN(__glewPointAlongPathNV) +#define glStencilFillPathInstancedNV GLEW_GET_FUN(__glewStencilFillPathInstancedNV) +#define glStencilFillPathNV GLEW_GET_FUN(__glewStencilFillPathNV) +#define glStencilStrokePathInstancedNV GLEW_GET_FUN(__glewStencilStrokePathInstancedNV) +#define glStencilStrokePathNV GLEW_GET_FUN(__glewStencilStrokePathNV) +#define glTransformPathNV GLEW_GET_FUN(__glewTransformPathNV) +#define glWeightPathsNV GLEW_GET_FUN(__glewWeightPathsNV) + +#define GLEW_NV_path_rendering GLEW_GET_VAR(__GLEW_NV_path_rendering) + +#endif /* GL_NV_path_rendering */ + +/* ------------------------- 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); + +#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 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_shader_atomic_counters --------------------- */ + +#ifndef GL_NV_shader_atomic_counters +#define GL_NV_shader_atomic_counters 1 + +#define GLEW_NV_shader_atomic_counters GLEW_GET_VAR(__GLEW_NV_shader_atomic_counters) + +#endif /* GL_NV_shader_atomic_counters */ + +/* ----------------------- GL_NV_shader_atomic_float ----------------------- */ + +#ifndef GL_NV_shader_atomic_float +#define GL_NV_shader_atomic_float 1 + +#define GLEW_NV_shader_atomic_float GLEW_GET_VAR(__GLEW_NV_shader_atomic_float) + +#endif /* GL_NV_shader_atomic_float */ + +/* ------------------------ GL_NV_shader_buffer_load ----------------------- */ + +#ifndef GL_NV_shader_buffer_load +#define GL_NV_shader_buffer_load 1 + +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 + +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT* result); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); +typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); +typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); + +#define glGetBufferParameterui64vNV GLEW_GET_FUN(__glewGetBufferParameterui64vNV) +#define glGetIntegerui64vNV GLEW_GET_FUN(__glewGetIntegerui64vNV) +#define glGetNamedBufferParameterui64vNV GLEW_GET_FUN(__glewGetNamedBufferParameterui64vNV) +#define glIsBufferResidentNV GLEW_GET_FUN(__glewIsBufferResidentNV) +#define glIsNamedBufferResidentNV GLEW_GET_FUN(__glewIsNamedBufferResidentNV) +#define glMakeBufferNonResidentNV GLEW_GET_FUN(__glewMakeBufferNonResidentNV) +#define glMakeBufferResidentNV GLEW_GET_FUN(__glewMakeBufferResidentNV) +#define glMakeNamedBufferNonResidentNV GLEW_GET_FUN(__glewMakeNamedBufferNonResidentNV) +#define glMakeNamedBufferResidentNV GLEW_GET_FUN(__glewMakeNamedBufferResidentNV) +#define glProgramUniformui64NV GLEW_GET_FUN(__glewProgramUniformui64NV) +#define glProgramUniformui64vNV GLEW_GET_FUN(__glewProgramUniformui64vNV) +#define glUniformui64NV GLEW_GET_FUN(__glewUniformui64NV) +#define glUniformui64vNV GLEW_GET_FUN(__glewUniformui64vNV) + +#define GLEW_NV_shader_buffer_load GLEW_GET_VAR(__GLEW_NV_shader_buffer_load) + +#endif /* GL_NV_shader_buffer_load */ + +/* ------------------- GL_NV_shader_storage_buffer_object ------------------ */ + +#ifndef GL_NV_shader_storage_buffer_object +#define GL_NV_shader_storage_buffer_object 1 + +#define GLEW_NV_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_NV_shader_storage_buffer_object) + +#endif /* GL_NV_shader_storage_buffer_object */ + +/* ----------------------- GL_NV_shader_thread_group ----------------------- */ + +#ifndef GL_NV_shader_thread_group +#define GL_NV_shader_thread_group 1 + +#define GL_WARP_SIZE_NV 0x9339 +#define GL_WARPS_PER_SM_NV 0x933A +#define GL_SM_COUNT_NV 0x933B + +#define GLEW_NV_shader_thread_group GLEW_GET_VAR(__GLEW_NV_shader_thread_group) + +#endif /* GL_NV_shader_thread_group */ + +/* ---------------------- GL_NV_shader_thread_shuffle ---------------------- */ + +#ifndef GL_NV_shader_thread_shuffle +#define GL_NV_shader_thread_shuffle 1 + +#define GLEW_NV_shader_thread_shuffle GLEW_GET_VAR(__GLEW_NV_shader_thread_shuffle) + +#endif /* GL_NV_shader_thread_shuffle */ + +/* ---------------------- GL_NV_tessellation_program5 ---------------------- */ + +#ifndef GL_NV_tessellation_program5 +#define GL_NV_tessellation_program5 1 + +#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 +#define GL_TESS_CONTROL_PROGRAM_NV 0x891E +#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F +#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 +#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 + +#define GLEW_NV_tessellation_program5 GLEW_GET_VAR(__GLEW_NV_tessellation_program5) + +#endif /* GL_NV_tessellation_program5 */ + +/* -------------------------- 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_barrier ------------------------- */ + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 + +typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (void); + +#define glTextureBarrierNV GLEW_GET_FUN(__glewTextureBarrierNV) + +#define GLEW_NV_texture_barrier GLEW_GET_VAR(__GLEW_NV_texture_barrier) + +#endif /* GL_NV_texture_barrier */ + +/* --------------------- 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_multisample ----------------------- */ + +#ifndef GL_NV_texture_multisample +#define GL_NV_texture_multisample 1 + +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); + +#define glTexImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage2DMultisampleCoverageNV) +#define glTexImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage3DMultisampleCoverageNV) +#define glTextureImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage2DMultisampleCoverageNV) +#define glTextureImage2DMultisampleNV GLEW_GET_FUN(__glewTextureImage2DMultisampleNV) +#define glTextureImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage3DMultisampleCoverageNV) +#define glTextureImage3DMultisampleNV GLEW_GET_FUN(__glewTextureImage3DMultisampleNV) + +#define GLEW_NV_texture_multisample GLEW_GET_VAR(__GLEW_NV_texture_multisample) + +#endif /* GL_NV_texture_multisample */ + +/* ------------------------ 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_2D_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_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_transform_feedback2 ----------------------- */ + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 1 + +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 + +typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); +typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint* ids); +typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); + +#define glBindTransformFeedbackNV GLEW_GET_FUN(__glewBindTransformFeedbackNV) +#define glDeleteTransformFeedbacksNV GLEW_GET_FUN(__glewDeleteTransformFeedbacksNV) +#define glDrawTransformFeedbackNV GLEW_GET_FUN(__glewDrawTransformFeedbackNV) +#define glGenTransformFeedbacksNV GLEW_GET_FUN(__glewGenTransformFeedbacksNV) +#define glIsTransformFeedbackNV GLEW_GET_FUN(__glewIsTransformFeedbackNV) +#define glPauseTransformFeedbackNV GLEW_GET_FUN(__glewPauseTransformFeedbackNV) +#define glResumeTransformFeedbackNV GLEW_GET_FUN(__glewResumeTransformFeedbackNV) + +#define GLEW_NV_transform_feedback2 GLEW_GET_VAR(__GLEW_NV_transform_feedback2) + +#endif /* GL_NV_transform_feedback2 */ + +/* -------------------------- GL_NV_vdpau_interop -------------------------- */ + +#ifndef GL_NV_vdpau_interop +#define GL_NV_vdpau_interop 1 + +#define GL_SURFACE_STATE_NV 0x86EB +#define GL_SURFACE_REGISTERED_NV 0x86FD +#define GL_SURFACE_MAPPED_NV 0x8700 +#define GL_WRITE_DISCARD_NV 0x88BE + +typedef GLintptr GLvdpauSurfaceNV; + +typedef void (GLAPIENTRY * PFNGLVDPAUFININVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values); +typedef void (GLAPIENTRY * PFNGLVDPAUINITNVPROC) (const void* vdpDevice, const void*getProcAddress); +typedef void (GLAPIENTRY * PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (GLAPIENTRY * PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV* surfaces); +typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef void (GLAPIENTRY * PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); +typedef void (GLAPIENTRY * PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV* surfaces); +typedef void (GLAPIENTRY * PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); + +#define glVDPAUFiniNV GLEW_GET_FUN(__glewVDPAUFiniNV) +#define glVDPAUGetSurfaceivNV GLEW_GET_FUN(__glewVDPAUGetSurfaceivNV) +#define glVDPAUInitNV GLEW_GET_FUN(__glewVDPAUInitNV) +#define glVDPAUIsSurfaceNV GLEW_GET_FUN(__glewVDPAUIsSurfaceNV) +#define glVDPAUMapSurfacesNV GLEW_GET_FUN(__glewVDPAUMapSurfacesNV) +#define glVDPAURegisterOutputSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterOutputSurfaceNV) +#define glVDPAURegisterVideoSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterVideoSurfaceNV) +#define glVDPAUSurfaceAccessNV GLEW_GET_FUN(__glewVDPAUSurfaceAccessNV) +#define glVDPAUUnmapSurfacesNV GLEW_GET_FUN(__glewVDPAUUnmapSurfacesNV) +#define glVDPAUUnregisterSurfaceNV GLEW_GET_FUN(__glewVDPAUUnregisterSurfaceNV) + +#define GLEW_NV_vdpau_interop GLEW_GET_VAR(__GLEW_NV_vdpau_interop) + +#endif /* GL_NV_vdpau_interop */ + +/* ------------------------ 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_attrib_integer_64bit ------------------- */ + +#ifndef GL_NV_vertex_attrib_integer_64bit +#define GL_NV_vertex_attrib_integer_64bit 1 + +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); + +#define glGetVertexAttribLi64vNV GLEW_GET_FUN(__glewGetVertexAttribLi64vNV) +#define glGetVertexAttribLui64vNV GLEW_GET_FUN(__glewGetVertexAttribLui64vNV) +#define glVertexAttribL1i64NV GLEW_GET_FUN(__glewVertexAttribL1i64NV) +#define glVertexAttribL1i64vNV GLEW_GET_FUN(__glewVertexAttribL1i64vNV) +#define glVertexAttribL1ui64NV GLEW_GET_FUN(__glewVertexAttribL1ui64NV) +#define glVertexAttribL1ui64vNV GLEW_GET_FUN(__glewVertexAttribL1ui64vNV) +#define glVertexAttribL2i64NV GLEW_GET_FUN(__glewVertexAttribL2i64NV) +#define glVertexAttribL2i64vNV GLEW_GET_FUN(__glewVertexAttribL2i64vNV) +#define glVertexAttribL2ui64NV GLEW_GET_FUN(__glewVertexAttribL2ui64NV) +#define glVertexAttribL2ui64vNV GLEW_GET_FUN(__glewVertexAttribL2ui64vNV) +#define glVertexAttribL3i64NV GLEW_GET_FUN(__glewVertexAttribL3i64NV) +#define glVertexAttribL3i64vNV GLEW_GET_FUN(__glewVertexAttribL3i64vNV) +#define glVertexAttribL3ui64NV GLEW_GET_FUN(__glewVertexAttribL3ui64NV) +#define glVertexAttribL3ui64vNV GLEW_GET_FUN(__glewVertexAttribL3ui64vNV) +#define glVertexAttribL4i64NV GLEW_GET_FUN(__glewVertexAttribL4i64NV) +#define glVertexAttribL4i64vNV GLEW_GET_FUN(__glewVertexAttribL4i64vNV) +#define glVertexAttribL4ui64NV GLEW_GET_FUN(__glewVertexAttribL4ui64NV) +#define glVertexAttribL4ui64vNV GLEW_GET_FUN(__glewVertexAttribL4ui64vNV) +#define glVertexAttribLFormatNV GLEW_GET_FUN(__glewVertexAttribLFormatNV) + +#define GLEW_NV_vertex_attrib_integer_64bit GLEW_GET_VAR(__GLEW_NV_vertex_attrib_integer_64bit) + +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +/* ------------------- GL_NV_vertex_buffer_unified_memory ------------------ */ + +#ifndef GL_NV_vertex_buffer_unified_memory +#define GL_NV_vertex_buffer_unified_memory 1 + +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 +#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 +#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 + +typedef void (GLAPIENTRY * PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT result[]); +typedef void (GLAPIENTRY * PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); + +#define glBufferAddressRangeNV GLEW_GET_FUN(__glewBufferAddressRangeNV) +#define glColorFormatNV GLEW_GET_FUN(__glewColorFormatNV) +#define glEdgeFlagFormatNV GLEW_GET_FUN(__glewEdgeFlagFormatNV) +#define glFogCoordFormatNV GLEW_GET_FUN(__glewFogCoordFormatNV) +#define glGetIntegerui64i_vNV GLEW_GET_FUN(__glewGetIntegerui64i_vNV) +#define glIndexFormatNV GLEW_GET_FUN(__glewIndexFormatNV) +#define glNormalFormatNV GLEW_GET_FUN(__glewNormalFormatNV) +#define glSecondaryColorFormatNV GLEW_GET_FUN(__glewSecondaryColorFormatNV) +#define glTexCoordFormatNV GLEW_GET_FUN(__glewTexCoordFormatNV) +#define glVertexAttribFormatNV GLEW_GET_FUN(__glewVertexAttribFormatNV) +#define glVertexAttribIFormatNV GLEW_GET_FUN(__glewVertexAttribIFormatNV) +#define glVertexFormatNV GLEW_GET_FUN(__glewVertexFormatNV) + +#define GLEW_NV_vertex_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_vertex_buffer_unified_memory) + +#endif /* GL_NV_vertex_buffer_unified_memory */ + +/* -------------------------- 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, void** 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, GLsizei num, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei 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 GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD + +#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4) + +#endif /* GL_NV_vertex_program4 */ + +/* -------------------------- GL_NV_video_capture -------------------------- */ + +#ifndef GL_NV_video_capture +#define GL_NV_video_capture 1 + +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_SUCCESS_NV 0x902F +#define GL_FAILURE_NV 0x9030 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C + +typedef void (GLAPIENTRY * PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint* params); +typedef GLenum (GLAPIENTRY * PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint* sequence_num, GLuint64EXT *capture_time); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint* params); + +#define glBeginVideoCaptureNV GLEW_GET_FUN(__glewBeginVideoCaptureNV) +#define glBindVideoCaptureStreamBufferNV GLEW_GET_FUN(__glewBindVideoCaptureStreamBufferNV) +#define glBindVideoCaptureStreamTextureNV GLEW_GET_FUN(__glewBindVideoCaptureStreamTextureNV) +#define glEndVideoCaptureNV GLEW_GET_FUN(__glewEndVideoCaptureNV) +#define glGetVideoCaptureStreamdvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamdvNV) +#define glGetVideoCaptureStreamfvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamfvNV) +#define glGetVideoCaptureStreamivNV GLEW_GET_FUN(__glewGetVideoCaptureStreamivNV) +#define glGetVideoCaptureivNV GLEW_GET_FUN(__glewGetVideoCaptureivNV) +#define glVideoCaptureNV GLEW_GET_FUN(__glewVideoCaptureNV) +#define glVideoCaptureStreamParameterdvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterdvNV) +#define glVideoCaptureStreamParameterfvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterfvNV) +#define glVideoCaptureStreamParameterivNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterivNV) + +#define GLEW_NV_video_capture GLEW_GET_VAR(__GLEW_NV_video_capture) + +#endif /* GL_NV_video_capture */ + +/* ------------------------ GL_OES_byte_coordinates ------------------------ */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 + +#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_REGAL_ES1_0_compatibility --------------------- */ + +#ifndef GL_REGAL_ES1_0_compatibility +#define GL_REGAL_ES1_0_compatibility 1 + +typedef int GLclampx; + +typedef void (GLAPIENTRY * PFNGLALPHAFUNCXPROC) (GLenum func, GLclampx ref); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORXPROC) (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha); +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHXPROC) (GLclampx depth); +typedef void (GLAPIENTRY * PFNGLCOLOR4XPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEXPROC) (GLclampx zNear, GLclampx zFar); +typedef void (GLAPIENTRY * PFNGLFOGXPROC) (GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLFOGXVPROC) (GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLFRUSTUMFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); +typedef void (GLAPIENTRY * PFNGLFRUSTUMXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar); +typedef void (GLAPIENTRY * PFNGLLIGHTMODELXPROC) (GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLLIGHTMODELXVPROC) (GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLLIGHTXPROC) (GLenum light, GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLLIGHTXVPROC) (GLenum light, GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLLINEWIDTHXPROC) (GLfixed width); +typedef void (GLAPIENTRY * PFNGLLOADMATRIXXPROC) (const GLfixed* m); +typedef void (GLAPIENTRY * PFNGLMATERIALXPROC) (GLenum face, GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLMATERIALXVPROC) (GLenum face, GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLMULTMATRIXXPROC) (const GLfixed* m); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4XPROC) (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (GLAPIENTRY * PFNGLNORMAL3XPROC) (GLfixed nx, GLfixed ny, GLfixed nz); +typedef void (GLAPIENTRY * PFNGLORTHOFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); +typedef void (GLAPIENTRY * PFNGLORTHOXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar); +typedef void (GLAPIENTRY * PFNGLPOINTSIZEXPROC) (GLfixed size); +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETXPROC) (GLfixed factor, GLfixed units); +typedef void (GLAPIENTRY * PFNGLROTATEXPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEXPROC) (GLclampx value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSCALEXPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAPIENTRY * PFNGLTEXENVXPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLTEXENVXVPROC) (GLenum target, GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLTRANSLATEXPROC) (GLfixed x, GLfixed y, GLfixed z); + +#define glAlphaFuncx GLEW_GET_FUN(__glewAlphaFuncx) +#define glClearColorx GLEW_GET_FUN(__glewClearColorx) +#define glClearDepthx GLEW_GET_FUN(__glewClearDepthx) +#define glColor4x GLEW_GET_FUN(__glewColor4x) +#define glDepthRangex GLEW_GET_FUN(__glewDepthRangex) +#define glFogx GLEW_GET_FUN(__glewFogx) +#define glFogxv GLEW_GET_FUN(__glewFogxv) +#define glFrustumf GLEW_GET_FUN(__glewFrustumf) +#define glFrustumx GLEW_GET_FUN(__glewFrustumx) +#define glLightModelx GLEW_GET_FUN(__glewLightModelx) +#define glLightModelxv GLEW_GET_FUN(__glewLightModelxv) +#define glLightx GLEW_GET_FUN(__glewLightx) +#define glLightxv GLEW_GET_FUN(__glewLightxv) +#define glLineWidthx GLEW_GET_FUN(__glewLineWidthx) +#define glLoadMatrixx GLEW_GET_FUN(__glewLoadMatrixx) +#define glMaterialx GLEW_GET_FUN(__glewMaterialx) +#define glMaterialxv GLEW_GET_FUN(__glewMaterialxv) +#define glMultMatrixx GLEW_GET_FUN(__glewMultMatrixx) +#define glMultiTexCoord4x GLEW_GET_FUN(__glewMultiTexCoord4x) +#define glNormal3x GLEW_GET_FUN(__glewNormal3x) +#define glOrthof GLEW_GET_FUN(__glewOrthof) +#define glOrthox GLEW_GET_FUN(__glewOrthox) +#define glPointSizex GLEW_GET_FUN(__glewPointSizex) +#define glPolygonOffsetx GLEW_GET_FUN(__glewPolygonOffsetx) +#define glRotatex GLEW_GET_FUN(__glewRotatex) +#define glSampleCoveragex GLEW_GET_FUN(__glewSampleCoveragex) +#define glScalex GLEW_GET_FUN(__glewScalex) +#define glTexEnvx GLEW_GET_FUN(__glewTexEnvx) +#define glTexEnvxv GLEW_GET_FUN(__glewTexEnvxv) +#define glTexParameterx GLEW_GET_FUN(__glewTexParameterx) +#define glTranslatex GLEW_GET_FUN(__glewTranslatex) + +#define GLEW_REGAL_ES1_0_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_0_compatibility) + +#endif /* GL_REGAL_ES1_0_compatibility */ + +/* ---------------------- GL_REGAL_ES1_1_compatibility --------------------- */ + +#ifndef GL_REGAL_ES1_1_compatibility +#define GL_REGAL_ES1_1_compatibility 1 + +typedef void (GLAPIENTRY * PFNGLCLIPPLANEFPROC) (GLenum plane, const GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLCLIPPLANEXPROC) (GLenum plane, const GLfixed* equation); +typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFPROC) (GLenum pname, GLfloat eqn[4]); +typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEXPROC) (GLenum pname, GLfixed eqn[4]); +typedef void (GLAPIENTRY * PFNGLGETFIXEDVPROC) (GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLGETLIGHTXVPROC) (GLenum light, GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLGETMATERIALXVPROC) (GLenum face, GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLGETTEXENVXVPROC) (GLenum env, GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERXVPROC) (GLenum target, GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXPROC) (GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXVPROC) (GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLPOINTSIZEPOINTEROESPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXVPROC) (GLenum target, GLenum pname, const GLfixed* params); + +#define glClipPlanef GLEW_GET_FUN(__glewClipPlanef) +#define glClipPlanex GLEW_GET_FUN(__glewClipPlanex) +#define glGetClipPlanef GLEW_GET_FUN(__glewGetClipPlanef) +#define glGetClipPlanex GLEW_GET_FUN(__glewGetClipPlanex) +#define glGetFixedv GLEW_GET_FUN(__glewGetFixedv) +#define glGetLightxv GLEW_GET_FUN(__glewGetLightxv) +#define glGetMaterialxv GLEW_GET_FUN(__glewGetMaterialxv) +#define glGetTexEnvxv GLEW_GET_FUN(__glewGetTexEnvxv) +#define glGetTexParameterxv GLEW_GET_FUN(__glewGetTexParameterxv) +#define glPointParameterx GLEW_GET_FUN(__glewPointParameterx) +#define glPointParameterxv GLEW_GET_FUN(__glewPointParameterxv) +#define glPointSizePointerOES GLEW_GET_FUN(__glewPointSizePointerOES) +#define glTexParameterxv GLEW_GET_FUN(__glewTexParameterxv) + +#define GLEW_REGAL_ES1_1_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_1_compatibility) + +#endif /* GL_REGAL_ES1_1_compatibility */ + +/* ---------------------------- GL_REGAL_enable ---------------------------- */ + +#ifndef GL_REGAL_enable +#define GL_REGAL_enable 1 + +#define GL_ERROR_REGAL 0x9322 +#define GL_DEBUG_REGAL 0x9323 +#define GL_LOG_REGAL 0x9324 +#define GL_EMULATION_REGAL 0x9325 +#define GL_DRIVER_REGAL 0x9326 +#define GL_MISSING_REGAL 0x9360 +#define GL_TRACE_REGAL 0x9361 +#define GL_CACHE_REGAL 0x9362 +#define GL_CODE_REGAL 0x9363 +#define GL_STATISTICS_REGAL 0x9364 + +#define GLEW_REGAL_enable GLEW_GET_VAR(__GLEW_REGAL_enable) + +#endif /* GL_REGAL_enable */ + +/* ------------------------- GL_REGAL_error_string ------------------------- */ + +#ifndef GL_REGAL_error_string +#define GL_REGAL_error_string 1 + +typedef const GLchar* (GLAPIENTRY * PFNGLERRORSTRINGREGALPROC) (GLenum error); + +#define glErrorStringREGAL GLEW_GET_FUN(__glewErrorStringREGAL) + +#define GLEW_REGAL_error_string GLEW_GET_VAR(__GLEW_REGAL_error_string) + +#endif /* GL_REGAL_error_string */ + +/* ------------------------ GL_REGAL_extension_query ----------------------- */ + +#ifndef GL_REGAL_extension_query +#define GL_REGAL_extension_query 1 + +typedef GLboolean (GLAPIENTRY * PFNGLGETEXTENSIONREGALPROC) (const GLchar* ext); +typedef GLboolean (GLAPIENTRY * PFNGLISSUPPORTEDREGALPROC) (const GLchar* ext); + +#define glGetExtensionREGAL GLEW_GET_FUN(__glewGetExtensionREGAL) +#define glIsSupportedREGAL GLEW_GET_FUN(__glewIsSupportedREGAL) + +#define GLEW_REGAL_extension_query GLEW_GET_VAR(__GLEW_REGAL_extension_query) + +#endif /* GL_REGAL_extension_query */ + +/* ------------------------------ GL_REGAL_log ----------------------------- */ + +#ifndef GL_REGAL_log +#define GL_REGAL_log 1 + +#define GL_LOG_ERROR_REGAL 0x9319 +#define GL_LOG_WARNING_REGAL 0x931A +#define GL_LOG_INFO_REGAL 0x931B +#define GL_LOG_APP_REGAL 0x931C +#define GL_LOG_DRIVER_REGAL 0x931D +#define GL_LOG_INTERNAL_REGAL 0x931E +#define GL_LOG_DEBUG_REGAL 0x931F +#define GL_LOG_STATUS_REGAL 0x9320 +#define GL_LOG_HTTP_REGAL 0x9321 + +typedef void (APIENTRY *GLLOGPROCREGAL)(GLenum stream, GLsizei length, const GLchar *message, void *context); + +typedef void (GLAPIENTRY * PFNGLLOGMESSAGECALLBACKREGALPROC) (GLLOGPROCREGAL callback); + +#define glLogMessageCallbackREGAL GLEW_GET_FUN(__glewLogMessageCallbackREGAL) + +#define GLEW_REGAL_log GLEW_GET_VAR(__GLEW_REGAL_log) + +#endif /* GL_REGAL_log */ + +/* ------------------------- GL_REGAL_proc_address ------------------------- */ + +#ifndef GL_REGAL_proc_address +#define GL_REGAL_proc_address 1 + +typedef void * (GLAPIENTRY * PFNGLGETPROCADDRESSREGALPROC) (const GLchar *name); + +#define glGetProcAddressREGAL GLEW_GET_FUN(__glewGetProcAddressREGAL) + +#define GLEW_REGAL_proc_address GLEW_GET_VAR(__GLEW_REGAL_proc_address) + +#endif /* GL_REGAL_proc_address */ + +/* ----------------------- 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 + +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_FOG_PATCHY_FACTOR_SGIX 0 +#define GL_FRAGMENT_FOG_SGIX 0 +#define GL_TEXTURE_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, void* 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 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 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 PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex; +GLEW_FUN_EXPORT PFNGLTEXBUFFERPROC __glewTexBuffer; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v; +GLEW_FUN_EXPORT PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIPROC __glewBlendEquationi; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIPROC __glewBlendFunci; +GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading; + +GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; + +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD; +GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD; + +GLEW_FUN_EXPORT PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD; +GLEW_FUN_EXPORT PFNGLGENNAMESAMDPROC __glewGenNamesAMD; +GLEW_FUN_EXPORT PFNGLISNAMEAMDPROC __glewIsNameAMD; + +GLEW_FUN_EXPORT PFNGLQUERYOBJECTPARAMETERUIAMDPROC __glewQueryObjectParameteruiAMD; + +GLEW_FUN_EXPORT PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD; +GLEW_FUN_EXPORT PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD; +GLEW_FUN_EXPORT PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD; +GLEW_FUN_EXPORT PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD; +GLEW_FUN_EXPORT PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD; + +GLEW_FUN_EXPORT PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD; + +GLEW_FUN_EXPORT PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD; + +GLEW_FUN_EXPORT PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD; + +GLEW_FUN_EXPORT PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD; +GLEW_FUN_EXPORT PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE; +GLEW_FUN_EXPORT PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE; +GLEW_FUN_EXPORT PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE; +GLEW_FUN_EXPORT PFNGLISQUERYANGLEPROC __glewIsQueryANGLE; +GLEW_FUN_EXPORT PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE; + +GLEW_FUN_EXPORT PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE; + +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 PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE; +GLEW_FUN_EXPORT PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE; +GLEW_FUN_EXPORT PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE; + +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 PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHFPROC __glewClearDepthf; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEFPROC __glewDepthRangef; +GLEW_FUN_EXPORT PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat; +GLEW_FUN_EXPORT PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler; +GLEW_FUN_EXPORT PFNGLSHADERBINARYPROC __glewShaderBinary; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance; + +GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB; +GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB; +GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB; +GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB; +GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB; +GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB; +GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB; +GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB; +GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed; +GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex; + +GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEPROC __glewBufferStorage; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT; + +GLEW_FUN_EXPORT PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB; + +GLEW_FUN_EXPORT PFNGLCLEARBUFFERDATAPROC __glewClearBufferData; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT; + +GLEW_FUN_EXPORT PFNGLCLEARTEXIMAGEPROC __glewClearTexImage; +GLEW_FUN_EXPORT PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage; + +GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; + +GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute; +GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect; + +GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB; + +GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData; + +GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData; + +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB; +GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT; + +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 PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer; +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 PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary; +GLEW_FUN_EXPORT PFNGLPROGRAMBINARYPROC __glewProgramBinary; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMDVPROC __glewGetUniformdv; +GLEW_FUN_EXPORT PFNGLUNIFORM1DPROC __glewUniform1d; +GLEW_FUN_EXPORT PFNGLUNIFORM1DVPROC __glewUniform1dv; +GLEW_FUN_EXPORT PFNGLUNIFORM2DPROC __glewUniform2d; +GLEW_FUN_EXPORT PFNGLUNIFORM2DVPROC __glewUniform2dv; +GLEW_FUN_EXPORT PFNGLUNIFORM3DPROC __glewUniform3d; +GLEW_FUN_EXPORT PFNGLUNIFORM3DVPROC __glewUniform3dv; +GLEW_FUN_EXPORT PFNGLUNIFORM4DPROC __glewUniform4d; +GLEW_FUN_EXPORT PFNGLUNIFORM4DVPROC __glewUniform4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv; + +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 PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB; + +GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ; + +GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v; + +GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData; +GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData; +GLEW_FUN_EXPORT PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer; +GLEW_FUN_EXPORT PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer; +GLEW_FUN_EXPORT PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage; +GLEW_FUN_EXPORT PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage; + +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 PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase; +GLEW_FUN_EXPORT PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange; +GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures; +GLEW_FUN_EXPORT PFNGLBINDSAMPLERSPROC __glewBindSamplers; +GLEW_FUN_EXPORT PFNGLBINDTEXTURESPROC __glewBindTextures; +GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect; + +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 PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv; + +GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex; + +GLEW_FUN_EXPORT PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB; +GLEW_FUN_EXPORT PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB; +GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB; +GLEW_FUN_EXPORT PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB; +GLEW_FUN_EXPORT PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB; +GLEW_FUN_EXPORT PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB; +GLEW_FUN_EXPORT PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB; +GLEW_FUN_EXPORT PFNGLGETNMAPIVARBPROC __glewGetnMapivARB; +GLEW_FUN_EXPORT PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB; +GLEW_FUN_EXPORT PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB; +GLEW_FUN_EXPORT PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB; +GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB; +GLEW_FUN_EXPORT PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB; + +GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB; + +GLEW_FUN_EXPORT PFNGLBINDSAMPLERPROC __glewBindSampler; +GLEW_FUN_EXPORT PFNGLDELETESAMPLERSPROC __glewDeleteSamplers; +GLEW_FUN_EXPORT PFNGLGENSAMPLERSPROC __glewGenSamplers; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv; +GLEW_FUN_EXPORT PFNGLISSAMPLERPROC __glewIsSampler; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv; + +GLEW_FUN_EXPORT PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines; +GLEW_FUN_EXPORT PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline; + +GLEW_FUN_EXPORT PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv; + +GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture; +GLEW_FUN_EXPORT PFNGLMEMORYBARRIERPROC __glewMemoryBarrier; + +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 PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding; + +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName; +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName; +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv; +GLEW_FUN_EXPORT PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex; +GLEW_FUN_EXPORT PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv; +GLEW_FUN_EXPORT PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv; + +GLEW_FUN_EXPORT PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB; +GLEW_FUN_EXPORT PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB; +GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB; +GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB; +GLEW_FUN_EXPORT PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB; +GLEW_FUN_EXPORT PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB; + +GLEW_FUN_EXPORT PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB; +GLEW_FUN_EXPORT PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT; + +GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync; +GLEW_FUN_EXPORT PFNGLDELETESYNCPROC __glewDeleteSync; +GLEW_FUN_EXPORT PFNGLFENCESYNCPROC __glewFenceSync; +GLEW_FUN_EXPORT PFNGLGETINTEGER64VPROC __glewGetInteger64v; +GLEW_FUN_EXPORT PFNGLGETSYNCIVPROC __glewGetSynciv; +GLEW_FUN_EXPORT PFNGLISSYNCPROC __glewIsSync; +GLEW_FUN_EXPORT PFNGLWAITSYNCPROC __glewWaitSync; + +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv; +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERIPROC __glewPatchParameteri; + +GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB; + +GLEW_FUN_EXPORT PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT; + +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 PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKIPROC __glewSampleMaski; +GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample; + +GLEW_FUN_EXPORT PFNGLTEXSTORAGE1DPROC __glewTexStorage1D; +GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DPROC __glewTexStorage2D; +GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DPROC __glewTexStorage3D; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample; +GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLTEXTUREVIEWPROC __glewTextureView; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v; +GLEW_FUN_EXPORT PFNGLQUERYCOUNTERPROC __glewQueryCounter; + +GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback; +GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback; +GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback; +GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback; +GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream; +GLEW_FUN_EXPORT PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed; +GLEW_FUN_EXPORT PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv; + +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced; + +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv; +GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v; +GLEW_FUN_EXPORT PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex; +GLEW_FUN_EXPORT PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices; +GLEW_FUN_EXPORT PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC __glewVertexArrayBindVertexBufferEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC __glewVertexArrayVertexAttribBindingEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC __glewVertexArrayVertexAttribFormatEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC __glewVertexArrayVertexAttribIFormatEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC __glewVertexArrayVertexAttribLFormatEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC __glewVertexArrayVertexBindingDivisorEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat; +GLEW_FUN_EXPORT PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor; + +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 PFNGLCOLORP3UIPROC __glewColorP3ui; +GLEW_FUN_EXPORT PFNGLCOLORP3UIVPROC __glewColorP3uiv; +GLEW_FUN_EXPORT PFNGLCOLORP4UIPROC __glewColorP4ui; +GLEW_FUN_EXPORT PFNGLCOLORP4UIVPROC __glewColorP4uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv; +GLEW_FUN_EXPORT PFNGLNORMALP3UIPROC __glewNormalP3ui; +GLEW_FUN_EXPORT PFNGLNORMALP3UIVPROC __glewNormalP3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP2UIPROC __glewVertexP2ui; +GLEW_FUN_EXPORT PFNGLVERTEXP2UIVPROC __glewVertexP2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP3UIPROC __glewVertexP3ui; +GLEW_FUN_EXPORT PFNGLVERTEXP3UIVPROC __glewVertexP3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP4UIPROC __glewVertexP4ui; +GLEW_FUN_EXPORT PFNGLVERTEXP4UIVPROC __glewVertexP4uiv; + +GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed; +GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v; +GLEW_FUN_EXPORT PFNGLGETFLOATI_VPROC __glewGetFloati_v; +GLEW_FUN_EXPORT PFNGLSCISSORARRAYVPROC __glewScissorArrayv; +GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDPROC __glewScissorIndexed; +GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv; +GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv; +GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf; +GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv; + +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 __glewPNTrianglesfATI; +GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI; + +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 PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI; +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 PFNGLGETOBJECTLABELEXTPROC __glewGetObjectLabelEXT; +GLEW_FUN_EXPORT PFNGLLABELOBJECTEXTPROC __glewLabelObjectEXT; + +GLEW_FUN_EXPORT PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT; +GLEW_FUN_EXPORT PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT; +GLEW_FUN_EXPORT PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT; + +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 PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT; +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 PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT; +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 PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT; +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 PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT; +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 PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT; +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 PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC __glewVertexArrayVertexAttribDivisorEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT; + +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 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 PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT; + +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 PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT; +GLEW_FUN_EXPORT PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT; + +GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT; +GLEW_FUN_EXPORT PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT; + +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 PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT; + +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 PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; +GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT; + +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 PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT; + +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 PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL; +GLEW_FUN_EXPORT PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL; +GLEW_FUN_EXPORT PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; + +GLEW_FUN_EXPORT PFNGLBEGINPERFQUERYINTELPROC __glewBeginPerfQueryINTEL; +GLEW_FUN_EXPORT PFNGLCREATEPERFQUERYINTELPROC __glewCreatePerfQueryINTEL; +GLEW_FUN_EXPORT PFNGLDELETEPERFQUERYINTELPROC __glewDeletePerfQueryINTEL; +GLEW_FUN_EXPORT PFNGLENDPERFQUERYINTELPROC __glewEndPerfQueryINTEL; +GLEW_FUN_EXPORT PFNGLGETFIRSTPERFQUERYIDINTELPROC __glewGetFirstPerfQueryIdINTEL; +GLEW_FUN_EXPORT PFNGLGETNEXTPERFQUERYIDINTELPROC __glewGetNextPerfQueryIdINTEL; +GLEW_FUN_EXPORT PFNGLGETPERFCOUNTERINFOINTELPROC __glewGetPerfCounterInfoINTEL; +GLEW_FUN_EXPORT PFNGLGETPERFQUERYDATAINTELPROC __glewGetPerfQueryDataINTEL; +GLEW_FUN_EXPORT PFNGLGETPERFQUERYIDBYNAMEINTELPROC __glewGetPerfQueryIdByNameINTEL; +GLEW_FUN_EXPORT PFNGLGETPERFQUERYINFOINTELPROC __glewGetPerfQueryInfoINTEL; + +GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; +GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; + +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert; +GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog; +GLEW_FUN_EXPORT PFNGLGETOBJECTLABELPROC __glewGetObjectLabel; +GLEW_FUN_EXPORT PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel; +GLEW_FUN_EXPORT PFNGLOBJECTLABELPROC __glewObjectLabel; +GLEW_FUN_EXPORT PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel; +GLEW_FUN_EXPORT PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup; +GLEW_FUN_EXPORT PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup; + +GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion; +GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion; +GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion; + +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 PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV; + +GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV; +GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV; +GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV; +GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV; +GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV; +GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV; + +GLEW_FUN_EXPORT PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV; +GLEW_FUN_EXPORT PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV; + +GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV; +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV; + +GLEW_FUN_EXPORT PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV; + +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 PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV; + +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 PFNGLCOPYPATHNVPROC __glewCopyPathNV; +GLEW_FUN_EXPORT PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV; +GLEW_FUN_EXPORT PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV; +GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV; +GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV; +GLEW_FUN_EXPORT PFNGLDELETEPATHSNVPROC __glewDeletePathsNV; +GLEW_FUN_EXPORT PFNGLGENPATHSNVPROC __glewGenPathsNV; +GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV; +GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV; +GLEW_FUN_EXPORT PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV; +GLEW_FUN_EXPORT PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV; +GLEW_FUN_EXPORT PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV; +GLEW_FUN_EXPORT PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV; +GLEW_FUN_EXPORT PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV; +GLEW_FUN_EXPORT PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV; +GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV; +GLEW_FUN_EXPORT PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV; +GLEW_FUN_EXPORT PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV; +GLEW_FUN_EXPORT PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV; +GLEW_FUN_EXPORT PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV; +GLEW_FUN_EXPORT PFNGLISPATHNVPROC __glewIsPathNV; +GLEW_FUN_EXPORT PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV; +GLEW_FUN_EXPORT PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV; +GLEW_FUN_EXPORT PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV; +GLEW_FUN_EXPORT PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV; +GLEW_FUN_EXPORT PFNGLPATHCOORDSNVPROC __glewPathCoordsNV; +GLEW_FUN_EXPORT PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV; +GLEW_FUN_EXPORT PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV; +GLEW_FUN_EXPORT PFNGLPATHFOGGENNVPROC __glewPathFogGenNV; +GLEW_FUN_EXPORT PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV; +GLEW_FUN_EXPORT PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV; +GLEW_FUN_EXPORT PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV; +GLEW_FUN_EXPORT PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV; +GLEW_FUN_EXPORT PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV; +GLEW_FUN_EXPORT PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV; +GLEW_FUN_EXPORT PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV; +GLEW_FUN_EXPORT PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV; +GLEW_FUN_EXPORT PFNGLPATHSTRINGNVPROC __glewPathStringNV; +GLEW_FUN_EXPORT PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV; +GLEW_FUN_EXPORT PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV; +GLEW_FUN_EXPORT PFNGLPATHTEXGENNVPROC __glewPathTexGenNV; +GLEW_FUN_EXPORT PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV; +GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV; +GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV; +GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV; +GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV; +GLEW_FUN_EXPORT PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV; + +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 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 PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV; +GLEW_FUN_EXPORT PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV; +GLEW_FUN_EXPORT PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV; +GLEW_FUN_EXPORT PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV; +GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORMUI64NVPROC __glewUniformui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV; + +GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV; + +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 PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV; +GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV; + +GLEW_FUN_EXPORT PFNGLVDPAUFININVPROC __glewVDPAUFiniNV; +GLEW_FUN_EXPORT PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV; +GLEW_FUN_EXPORT PFNGLVDPAUINITNVPROC __glewVDPAUInitNV; +GLEW_FUN_EXPORT PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV; +GLEW_FUN_EXPORT PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV; +GLEW_FUN_EXPORT PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV; +GLEW_FUN_EXPORT PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV; + +GLEW_FUN_EXPORT PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV; +GLEW_FUN_EXPORT PFNGLCOLORFORMATNVPROC __glewColorFormatNV; +GLEW_FUN_EXPORT PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV; +GLEW_FUN_EXPORT PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV; +GLEW_FUN_EXPORT PFNGLINDEXFORMATNVPROC __glewIndexFormatNV; +GLEW_FUN_EXPORT PFNGLNORMALFORMATNVPROC __glewNormalFormatNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV; +GLEW_FUN_EXPORT PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV; + +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 PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV; +GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV; +GLEW_FUN_EXPORT PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV; + +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 PFNGLALPHAFUNCXPROC __glewAlphaFuncx; +GLEW_FUN_EXPORT PFNGLCLEARCOLORXPROC __glewClearColorx; +GLEW_FUN_EXPORT PFNGLCLEARDEPTHXPROC __glewClearDepthx; +GLEW_FUN_EXPORT PFNGLCOLOR4XPROC __glewColor4x; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEXPROC __glewDepthRangex; +GLEW_FUN_EXPORT PFNGLFOGXPROC __glewFogx; +GLEW_FUN_EXPORT PFNGLFOGXVPROC __glewFogxv; +GLEW_FUN_EXPORT PFNGLFRUSTUMFPROC __glewFrustumf; +GLEW_FUN_EXPORT PFNGLFRUSTUMXPROC __glewFrustumx; +GLEW_FUN_EXPORT PFNGLLIGHTMODELXPROC __glewLightModelx; +GLEW_FUN_EXPORT PFNGLLIGHTMODELXVPROC __glewLightModelxv; +GLEW_FUN_EXPORT PFNGLLIGHTXPROC __glewLightx; +GLEW_FUN_EXPORT PFNGLLIGHTXVPROC __glewLightxv; +GLEW_FUN_EXPORT PFNGLLINEWIDTHXPROC __glewLineWidthx; +GLEW_FUN_EXPORT PFNGLLOADMATRIXXPROC __glewLoadMatrixx; +GLEW_FUN_EXPORT PFNGLMATERIALXPROC __glewMaterialx; +GLEW_FUN_EXPORT PFNGLMATERIALXVPROC __glewMaterialxv; +GLEW_FUN_EXPORT PFNGLMULTMATRIXXPROC __glewMultMatrixx; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x; +GLEW_FUN_EXPORT PFNGLNORMAL3XPROC __glewNormal3x; +GLEW_FUN_EXPORT PFNGLORTHOFPROC __glewOrthof; +GLEW_FUN_EXPORT PFNGLORTHOXPROC __glewOrthox; +GLEW_FUN_EXPORT PFNGLPOINTSIZEXPROC __glewPointSizex; +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx; +GLEW_FUN_EXPORT PFNGLROTATEXPROC __glewRotatex; +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex; +GLEW_FUN_EXPORT PFNGLSCALEXPROC __glewScalex; +GLEW_FUN_EXPORT PFNGLTEXENVXPROC __glewTexEnvx; +GLEW_FUN_EXPORT PFNGLTEXENVXVPROC __glewTexEnvxv; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERXPROC __glewTexParameterx; +GLEW_FUN_EXPORT PFNGLTRANSLATEXPROC __glewTranslatex; + +GLEW_FUN_EXPORT PFNGLCLIPPLANEFPROC __glewClipPlanef; +GLEW_FUN_EXPORT PFNGLCLIPPLANEXPROC __glewClipPlanex; +GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef; +GLEW_FUN_EXPORT PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex; +GLEW_FUN_EXPORT PFNGLGETFIXEDVPROC __glewGetFixedv; +GLEW_FUN_EXPORT PFNGLGETLIGHTXVPROC __glewGetLightxv; +GLEW_FUN_EXPORT PFNGLGETMATERIALXVPROC __glewGetMaterialxv; +GLEW_FUN_EXPORT PFNGLGETTEXENVXVPROC __glewGetTexEnvxv; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXPROC __glewPointParameterx; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv; +GLEW_FUN_EXPORT PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERXVPROC __glewTexParameterxv; + +GLEW_FUN_EXPORT PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL; + +GLEW_FUN_EXPORT PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL; +GLEW_FUN_EXPORT PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL; + +GLEW_FUN_EXPORT PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL; + +GLEW_FUN_EXPORT PFNGLGETPROCADDRESSREGALPROC __glewGetProcAddressREGAL; + +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_2_1; +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_VERSION_3_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_4; +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_AMD_blend_minmax_factor; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_conservative_depth; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_debug_output; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_depth_clamp_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_draw_buffers_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gcn_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_int64; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_interleaved_elements; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_multi_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_name_gen_delete; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_occlusion_query_event; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_performance_monitor; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_pinned_memory; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_query_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sample_positions; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_seamless_cubemap_per_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_atomic_counter_ops; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_export; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_value_export; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_trinary_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sparse_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_stencil_operation_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_texture4; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback3_lines_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback4; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_layer; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_tessellator; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_viewport_index; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_pack_reverse_row_order; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_program_binary; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt1; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt3; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt5; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_usage; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_translated_shader_source; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_aux_depth_stencil; +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_object_purgeable; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_rgb_422; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_row_bytes; +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_vertex_program_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES2_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_arrays_of_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_base_instance; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_bindless_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_blend_func_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_buffer_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cl_event; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compressed_texture_pixel_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_variable_group_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_conservative_depth; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_image; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_debug_output; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_elements_base_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_enhanced_layouts; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_attrib_location; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_uniform_location; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_coord_conventions; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_layer_viewport; +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_no_attachments; +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_get_program_binary; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_fp64; +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_indirect_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_invalidate_subdata; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_alignment; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_bind; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_draw_indirect; +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_occlusion_query2; +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_program_interface_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_provoking_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_query_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robust_buffer_access_behavior; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_application_isolation; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_share_group_isolation; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sampler_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cubemap_per_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_separate_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_atomic_counters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_bit_encoding; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_draw_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_group_vote; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_load_store; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_precision; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_stencil_export; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_storage_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_subroutine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_420pack; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_include; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_packing; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_stencil_texturing; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sync; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_tessellation_shader; +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_buffer_object_rgb32; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_bptc; +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_cube_map_array; +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_gather; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_levels; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rgb10_a2ui; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_stencil8; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_view; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_uniform_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_binding; +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_vertex_type_10f_11f_11f_rev; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_viewport_array; +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_meminfo; +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_debug_label; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_debug_marker; +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_multisample_blit_scaled; +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_provoking_vertex; +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_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_formatted; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_store; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_integer_mix; +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_sRGB_decode; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_snorm; +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_attrib_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_x11_sync_object; +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_fragment_shader_ordering; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_map_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_performance_query; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_debug; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_hdr; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_ldr; +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_NVX_conditional_render; +GLEW_VAR_EXPORT GLboolean __GLEW_NVX_gpu_memory_info; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced_coherent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_compute_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_deep_texture3D; +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_draw_texture; +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_gpu_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5_mem_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program_fp64; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_coverage; +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_parameter_buffer_object2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_path_rendering; +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_shader_atomic_counters; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_storage_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_group; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_shuffle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_tessellation_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_barrier; +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_multisample; +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_transform_feedback2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vdpau_interop; +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_attrib_integer_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_buffer_unified_memory; +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_NV_video_capture; +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_REGAL_ES1_0_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_1_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_enable; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_error_string; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_extension_query; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_log; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_proc_address; +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 /* Need at least OpenGL 1.1 */ +#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* Need at least GLX 1.2 */ + +/* 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 GLEWAPIENTRY glewContextInit (GLEWContext *ctx); +GLEWAPI GLboolean GLEWAPIENTRY glewContextIsSupported (const 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 GLEWAPIENTRY glewInit (void); +GLEWAPI GLboolean GLEWAPIENTRY 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 GLEWAPIENTRY glewGetExtension (const char *name); +GLEWAPI const GLubyte * GLEWAPIENTRY glewGetErrorString (GLenum error); +GLEWAPI const GLubyte * GLEWAPIENTRY glewGetString (GLenum name); + +#ifdef __cplusplus +} +#endif + +#ifdef GLEW_APIENTRY_DEFINED +#undef GLEW_APIENTRY_DEFINED +#undef APIENTRY +#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/ext/native/ext/glew/GL/glxew.h b/ext/native/ext/glew/GL/glxew.h new file mode 100644 index 0000000000..ab3a7d98da --- /dev/null +++ b/ext/native/ext/glew/GL/glxew.h @@ -0,0 +1,1738 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2014, Nigel Stewart +** 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 + +#if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__) +#error glx.h included before glxew.h +#endif + +#define __glxext_h_ + +#define GLX_H +#define __GLX_glx_h__ +#define __glx_h__ + +#include +#include +#include +#include "glew.h" + +#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_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_PIXMAP_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_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_CONFIG_CAVEAT 0x20 +#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 GLXPbuffer; +typedef XID GLXWindow; +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_AMD_gpu_association ------------------------ */ + +#ifndef GLX_AMD_gpu_association +#define GLX_AMD_gpu_association 1 + +#define GLX_GPU_VENDOR_AMD 0x1F00 +#define GLX_GPU_RENDERER_STRING_AMD 0x1F01 +#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define GLX_GPU_RAM_AMD 0x21A3 +#define GLX_GPU_CLOCK_AMD 0x21A4 +#define GLX_GPU_NUM_PIPES_AMD 0x21A5 +#define GLX_GPU_NUM_SIMD_AMD 0x21A6 +#define GLX_GPU_NUM_RB_AMD 0x21A7 +#define GLX_GPU_NUM_SPI_AMD 0x21A8 + +typedef void ( * PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) (unsigned int id, GLXContext share_list); +typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (unsigned int id, GLXContext share_context, const int* attribList); +typedef Bool ( * PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) (GLXContext ctx); +typedef unsigned int ( * PFNGLXGETCONTEXTGPUIDAMDPROC) (GLXContext ctx); +typedef GLXContext ( * PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); +typedef unsigned int ( * PFNGLXGETGPUIDSAMDPROC) (unsigned int maxCount, unsigned int* ids); +typedef int ( * PFNGLXGETGPUINFOAMDPROC) (unsigned int id, int property, GLenum dataType, unsigned int size, void* data); +typedef Bool ( * PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (GLXContext ctx); + +#define glXBlitContextFramebufferAMD GLXEW_GET_FUN(__glewXBlitContextFramebufferAMD) +#define glXCreateAssociatedContextAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAMD) +#define glXCreateAssociatedContextAttribsAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAttribsAMD) +#define glXDeleteAssociatedContextAMD GLXEW_GET_FUN(__glewXDeleteAssociatedContextAMD) +#define glXGetContextGPUIDAMD GLXEW_GET_FUN(__glewXGetContextGPUIDAMD) +#define glXGetCurrentAssociatedContextAMD GLXEW_GET_FUN(__glewXGetCurrentAssociatedContextAMD) +#define glXGetGPUIDsAMD GLXEW_GET_FUN(__glewXGetGPUIDsAMD) +#define glXGetGPUInfoAMD GLXEW_GET_FUN(__glewXGetGPUInfoAMD) +#define glXMakeAssociatedContextCurrentAMD GLXEW_GET_FUN(__glewXMakeAssociatedContextCurrentAMD) + +#define GLXEW_AMD_gpu_association GLXEW_GET_VAR(__GLXEW_AMD_gpu_association) + +#endif /* GLX_AMD_gpu_association */ + +/* ------------------------- 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_create_context_profile -------------------- */ + +#ifndef GLX_ARB_create_context_profile +#define GLX_ARB_create_context_profile 1 + +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 + +#define GLXEW_ARB_create_context_profile GLXEW_GET_VAR(__GLXEW_ARB_create_context_profile) + +#endif /* GLX_ARB_create_context_profile */ + +/* ------------------- GLX_ARB_create_context_robustness ------------------- */ + +#ifndef GLX_ARB_create_context_robustness +#define GLX_ARB_create_context_robustness 1 + +#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 + +#define GLXEW_ARB_create_context_robustness GLXEW_GET_VAR(__GLXEW_ARB_create_context_robustness) + +#endif /* GLX_ARB_create_context_robustness */ + +/* ------------------------- 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_ARB_robustness_application_isolation --------------- */ + +#ifndef GLX_ARB_robustness_application_isolation +#define GLX_ARB_robustness_application_isolation 1 + +#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 + +#define GLXEW_ARB_robustness_application_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_application_isolation) + +#endif /* GLX_ARB_robustness_application_isolation */ + +/* ---------------- GLX_ARB_robustness_share_group_isolation --------------- */ + +#ifndef GLX_ARB_robustness_share_group_isolation +#define GLX_ARB_robustness_share_group_isolation 1 + +#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 + +#define GLXEW_ARB_robustness_share_group_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_share_group_isolation) + +#endif /* GLX_ARB_robustness_share_group_isolation */ + +/* ---------------------- GLX_ARB_vertex_buffer_object --------------------- */ + +#ifndef GLX_ARB_vertex_buffer_object +#define GLX_ARB_vertex_buffer_object 1 + +#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 + +#define GLXEW_ARB_vertex_buffer_object GLXEW_GET_VAR(__GLXEW_ARB_vertex_buffer_object) + +#endif /* GLX_ARB_vertex_buffer_object */ + +/* ----------------------- 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_buffer_age -------------------------- */ + +#ifndef GLX_EXT_buffer_age +#define GLX_EXT_buffer_age 1 + +#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 + +#define GLXEW_EXT_buffer_age GLXEW_GET_VAR(__GLXEW_EXT_buffer_age) + +#endif /* GLX_EXT_buffer_age */ + +/* ------------------- GLX_EXT_create_context_es2_profile ------------------ */ + +#ifndef GLX_EXT_create_context_es2_profile +#define GLX_EXT_create_context_es2_profile 1 + +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 + +#define GLXEW_EXT_create_context_es2_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es2_profile) + +#endif /* GLX_EXT_create_context_es2_profile */ + +/* ------------------- GLX_EXT_create_context_es_profile ------------------- */ + +#ifndef GLX_EXT_create_context_es_profile +#define GLX_EXT_create_context_es_profile 1 + +#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 + +#define GLXEW_EXT_create_context_es_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es_profile) + +#endif /* GLX_EXT_create_context_es_profile */ + +/* --------------------- 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_stereo_tree -------------------------- */ + +#ifndef GLX_EXT_stereo_tree +#define GLX_EXT_stereo_tree 1 + +#define GLX_STEREO_NOTIFY_EXT 0x00000000 +#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001 +#define GLX_STEREO_TREE_EXT 0x20F5 + +#define GLXEW_EXT_stereo_tree GLXEW_GET_VAR(__GLXEW_EXT_stereo_tree) + +#endif /* GLX_EXT_stereo_tree */ + +/* -------------------------- GLX_EXT_swap_control ------------------------- */ + +#ifndef GLX_EXT_swap_control +#define GLX_EXT_swap_control 1 + +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 + +typedef void ( * PFNGLXSWAPINTERVALEXTPROC) (Display* dpy, GLXDrawable drawable, int interval); + +#define glXSwapIntervalEXT GLXEW_GET_FUN(__glewXSwapIntervalEXT) + +#define GLXEW_EXT_swap_control GLXEW_GET_VAR(__GLXEW_EXT_swap_control) + +#endif /* GLX_EXT_swap_control */ + +/* ----------------------- GLX_EXT_swap_control_tear ----------------------- */ + +#ifndef GLX_EXT_swap_control_tear +#define GLX_EXT_swap_control_tear 1 + +#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 + +#define GLXEW_EXT_swap_control_tear GLXEW_GET_VAR(__GLXEW_EXT_swap_control_tear) + +#endif /* GLX_EXT_swap_control_tear */ + +/* ---------------------- 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_INTEL_swap_event ------------------------- */ + +#ifndef GLX_INTEL_swap_event +#define GLX_INTEL_swap_event 1 + +#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 +#define GLX_COPY_COMPLETE_INTEL 0x8181 +#define GLX_FLIP_COMPLETE_INTEL 0x8182 +#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 + +#define GLXEW_INTEL_swap_event GLXEW_GET_VAR(__GLXEW_INTEL_swap_event) + +#endif /* GLX_INTEL_swap_event */ + +/* -------------------------- 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_query_renderer ------------------------ */ + +#ifndef GLX_MESA_query_renderer +#define GLX_MESA_query_renderer 1 + +#define GLX_RENDERER_VENDOR_ID_MESA 0x8183 +#define GLX_RENDERER_DEVICE_ID_MESA 0x8184 +#define GLX_RENDERER_VERSION_MESA 0x8185 +#define GLX_RENDERER_ACCELERATED_MESA 0x8186 +#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187 +#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188 +#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189 +#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A +#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B +#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C +#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D +#define GLX_RENDERER_ID_MESA 0x818E + +typedef Bool ( * PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int* value); +typedef const char* ( * PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute); +typedef Bool ( * PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display* dpy, int screen, int renderer, int attribute, unsigned int *value); +typedef const char* ( * PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute); + +#define glXQueryCurrentRendererIntegerMESA GLXEW_GET_FUN(__glewXQueryCurrentRendererIntegerMESA) +#define glXQueryCurrentRendererStringMESA GLXEW_GET_FUN(__glewXQueryCurrentRendererStringMESA) +#define glXQueryRendererIntegerMESA GLXEW_GET_FUN(__glewXQueryRendererIntegerMESA) +#define glXQueryRendererStringMESA GLXEW_GET_FUN(__glewXQueryRendererStringMESA) + +#define GLXEW_MESA_query_renderer GLXEW_GET_VAR(__GLXEW_MESA_query_renderer) + +#endif /* GLX_MESA_query_renderer */ + +/* ------------------------ 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_MESA_swap_control ------------------------- */ + +#ifndef GLX_MESA_swap_control +#define GLX_MESA_swap_control 1 + +typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC) (void); +typedef int ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval); + +#define glXGetSwapIntervalMESA GLXEW_GET_FUN(__glewXGetSwapIntervalMESA) +#define glXSwapIntervalMESA GLXEW_GET_FUN(__glewXSwapIntervalMESA) + +#define GLXEW_MESA_swap_control GLXEW_GET_VAR(__GLXEW_MESA_swap_control) + +#endif /* GLX_MESA_swap_control */ + +/* --------------------------- GLX_NV_copy_image --------------------------- */ + +#ifndef GLX_NV_copy_image +#define GLX_NV_copy_image 1 + +typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + +#define glXCopyImageSubDataNV GLXEW_GET_FUN(__glewXCopyImageSubDataNV) + +#define GLXEW_NV_copy_image GLXEW_GET_VAR(__GLXEW_NV_copy_image) + +#endif /* GLX_NV_copy_image */ + +/* ------------------------ GLX_NV_delay_before_swap ----------------------- */ + +#ifndef GLX_NV_delay_before_swap +#define GLX_NV_delay_before_swap 1 + +typedef Bool ( * PFNGLXDELAYBEFORESWAPNVPROC) (Display* dpy, GLXDrawable drawable, GLfloat seconds); + +#define glXDelayBeforeSwapNV GLXEW_GET_FUN(__glewXDelayBeforeSwapNV) + +#define GLXEW_NV_delay_before_swap GLXEW_GET_VAR(__GLXEW_NV_delay_before_swap) + +#endif /* GLX_NV_delay_before_swap */ + +/* -------------------------- 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_multisample_coverage ---------------------- */ + +#ifndef GLX_NV_multisample_coverage +#define GLX_NV_multisample_coverage 1 + +#define GLX_COLOR_SAMPLES_NV 0x20B3 +#define GLX_COVERAGE_SAMPLES_NV 100001 + +#define GLXEW_NV_multisample_coverage GLXEW_GET_VAR(__GLXEW_NV_multisample_coverage) + +#endif /* GLX_NV_multisample_coverage */ + +/* -------------------------- 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_capture ------------------------- */ + +#ifndef GLX_NV_video_capture +#define GLX_NV_video_capture 1 + +#define GLX_DEVICE_ID_NV 0x20CD +#define GLX_UNIQUE_ID_NV 0x20CE +#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF + +typedef XID GLXVideoCaptureDeviceNV; + +typedef int ( * PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display* dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); +typedef GLXVideoCaptureDeviceNV * ( * PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display* dpy, int screen, int *nelements); +typedef void ( * PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device); +typedef int ( * PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value); +typedef void ( * PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device); + +#define glXBindVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXBindVideoCaptureDeviceNV) +#define glXEnumerateVideoCaptureDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoCaptureDevicesNV) +#define glXLockVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXLockVideoCaptureDeviceNV) +#define glXQueryVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXQueryVideoCaptureDeviceNV) +#define glXReleaseVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoCaptureDeviceNV) + +#define GLXEW_NV_video_capture GLXEW_GET_VAR(__GLXEW_NV_video_capture) + +#endif /* GLX_NV_video_capture */ + +/* ---------------------------- GLX_NV_video_out --------------------------- */ + +#ifndef GLX_NV_video_out +#define GLX_NV_video_out 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_out GLXEW_GET_VAR(__GLXEW_NV_video_out) + +#endif /* GLX_NV_video_out */ + +/* -------------------------- 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 ------------------------- */ + +#ifndef GLX_OML_sync_control +#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 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_RGBA_BIT_SGIX 0x00000001 +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_PIXMAP_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_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_PIPE_RECT_LIMITS_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_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_PBUFFER_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) (unsigned int* 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_FUN_EXPORT GLEW_FUN_EXPORT +#define GLXEW_VAR_EXPORT +#else +#define GLXEW_FUN_EXPORT GLEW_FUN_EXPORT +#define GLXEW_VAR_EXPORT GLEW_VAR_EXPORT +#endif /* GLEW_MX */ + +GLXEW_FUN_EXPORT PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; + +GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; +GLXEW_FUN_EXPORT PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; +GLXEW_FUN_EXPORT PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; +GLXEW_FUN_EXPORT PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; +GLXEW_FUN_EXPORT PFNGLXCREATEWINDOWPROC __glewXCreateWindow; +GLXEW_FUN_EXPORT PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; +GLXEW_FUN_EXPORT PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; +GLXEW_FUN_EXPORT PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; +GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; +GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; +GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; +GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; +GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; +GLXEW_FUN_EXPORT PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; +GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTPROC __glewXQueryContext; +GLXEW_FUN_EXPORT PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; +GLXEW_FUN_EXPORT PFNGLXSELECTEVENTPROC __glewXSelectEvent; + +GLXEW_FUN_EXPORT PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC __glewXBlitContextFramebufferAMD; +GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC __glewXCreateAssociatedContextAMD; +GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __glewXCreateAssociatedContextAttribsAMD; +GLXEW_FUN_EXPORT PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC __glewXDeleteAssociatedContextAMD; +GLXEW_FUN_EXPORT PFNGLXGETCONTEXTGPUIDAMDPROC __glewXGetContextGPUIDAMD; +GLXEW_FUN_EXPORT PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC __glewXGetCurrentAssociatedContextAMD; +GLXEW_FUN_EXPORT PFNGLXGETGPUIDSAMDPROC __glewXGetGPUIDsAMD; +GLXEW_FUN_EXPORT PFNGLXGETGPUINFOAMDPROC __glewXGetGPUInfoAMD; +GLXEW_FUN_EXPORT PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __glewXMakeAssociatedContextCurrentAMD; + +GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB; + +GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; +GLXEW_FUN_EXPORT PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; +GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; + +GLXEW_FUN_EXPORT PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; +GLXEW_FUN_EXPORT PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; +GLXEW_FUN_EXPORT PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; +GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; + +GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT; + +GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT; +GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT; + +GLXEW_FUN_EXPORT PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; + +GLXEW_FUN_EXPORT PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; + +GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; + +GLXEW_FUN_EXPORT PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC __glewXQueryCurrentRendererIntegerMESA; +GLXEW_FUN_EXPORT PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC __glewXQueryCurrentRendererStringMESA; +GLXEW_FUN_EXPORT PFNGLXQUERYRENDERERINTEGERMESAPROC __glewXQueryRendererIntegerMESA; +GLXEW_FUN_EXPORT PFNGLXQUERYRENDERERSTRINGMESAPROC __glewXQueryRendererStringMESA; + +GLXEW_FUN_EXPORT PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; + +GLXEW_FUN_EXPORT PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; + +GLXEW_FUN_EXPORT PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA; +GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA; + +GLXEW_FUN_EXPORT PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV; + +GLXEW_FUN_EXPORT PFNGLXDELAYBEFORESWAPNVPROC __glewXDelayBeforeSwapNV; + +GLXEW_FUN_EXPORT PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV; +GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV; + +GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV; +GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV; +GLXEW_FUN_EXPORT PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV; +GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV; +GLXEW_FUN_EXPORT PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV; +GLXEW_FUN_EXPORT PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV; + +GLXEW_FUN_EXPORT PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; +GLXEW_FUN_EXPORT PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; + +GLXEW_FUN_EXPORT PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV; +GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV; +GLXEW_FUN_EXPORT PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV; +GLXEW_FUN_EXPORT PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV; +GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV; + +GLXEW_FUN_EXPORT PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV; +GLXEW_FUN_EXPORT PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV; +GLXEW_FUN_EXPORT PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV; +GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV; +GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV; +GLXEW_FUN_EXPORT PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV; + +GLXEW_FUN_EXPORT PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; +GLXEW_FUN_EXPORT PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; +GLXEW_FUN_EXPORT PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; +GLXEW_FUN_EXPORT PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; +GLXEW_FUN_EXPORT PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; + +GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; +GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; +GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; + +GLXEW_FUN_EXPORT PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX; +GLXEW_FUN_EXPORT PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX; +GLXEW_FUN_EXPORT PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX; + +GLXEW_FUN_EXPORT PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; +GLXEW_FUN_EXPORT PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; +GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; +GLXEW_FUN_EXPORT PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; + +GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; + +GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; + +GLXEW_FUN_EXPORT PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; +GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; +GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; + +GLXEW_FUN_EXPORT PFNGLXCUSHIONSGIPROC __glewXCushionSGI; + +GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; +GLXEW_FUN_EXPORT PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; + +GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; + +GLXEW_FUN_EXPORT PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; +GLXEW_FUN_EXPORT PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; + +GLXEW_FUN_EXPORT PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; + +GLXEW_FUN_EXPORT PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; +GLXEW_FUN_EXPORT PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; + +#if defined(GLEW_MX) +struct GLXEWContextStruct +{ +#endif /* GLEW_MX */ + +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_0; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_1; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_3; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_4; +GLXEW_VAR_EXPORT GLboolean __GLXEW_3DFX_multisample; +GLXEW_VAR_EXPORT GLboolean __GLXEW_AMD_gpu_association; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_profile; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_robustness; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_get_proc_address; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_multisample; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_application_isolation; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_share_group_isolation; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_vertex_buffer_object; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_render_texture; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_buffer_age; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es2_profile; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es_profile; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_import_context; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_scene_marker; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_stereo_tree; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control_tear; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_info; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_rating; +GLXEW_VAR_EXPORT GLboolean __GLXEW_INTEL_swap_event; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_agp_offset; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_query_renderer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_release_buffers; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_swap_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_copy_image; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_delay_before_swap; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_float_buffer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_multisample_coverage; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_present_video; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_swap_group; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_vertex_array_range; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_capture; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_out; +GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_swap_method; +GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_sync_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_color_range; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_multisample; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_fbconfig; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_hyperpipe; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_pbuffer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_group; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_video_resize; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_cushion; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_make_current_read; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_swap_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_video_sync; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_video_resize; + +#ifdef GLEW_MX +}; /* GLXEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------ */ + +#ifdef GLEW_MX + +typedef struct GLXEWContextStruct GLXEWContext; +GLEWAPI GLenum GLEWAPIENTRY glxewContextInit (GLXEWContext *ctx); +GLEWAPI GLboolean GLEWAPIENTRY glxewContextIsSupported (const 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 + +GLEWAPI GLboolean GLEWAPIENTRY glxewIsSupported (const char *name); + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean GLEWAPIENTRY glxewGetExtension (const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* __glxew_h__ */ diff --git a/ext/native/ext/glew/GL/wglew.h b/ext/native/ext/glew/GL/wglew.h new file mode 100644 index 0000000000..da63e40378 --- /dev/null +++ b/ext/native/ext/glew/GL/wglew.h @@ -0,0 +1,1438 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2014, Nigel Stewart +** 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(WINAPI) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +#include +# undef WIN32_LEAN_AND_MEAN +#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_AMD_gpu_association ------------------------ */ + +#ifndef WGL_AMD_gpu_association +#define WGL_AMD_gpu_association 1 + +#define WGL_GPU_VENDOR_AMD 0x1F00 +#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 +#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define WGL_GPU_RAM_AMD 0x21A3 +#define WGL_GPU_CLOCK_AMD 0x21A4 +#define WGL_GPU_NUM_PIPES_AMD 0x21A5 +#define WGL_GPU_NUM_SIMD_AMD 0x21A6 +#define WGL_GPU_NUM_RB_AMD 0x21A7 +#define WGL_GPU_NUM_SPI_AMD 0x21A8 + +typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int* attribList); +typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); +typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); +typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT* ids); +typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, INT property, GLenum dataType, UINT size, void* data); +typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); + +#define wglBlitContextFramebufferAMD WGLEW_GET_FUN(__wglewBlitContextFramebufferAMD) +#define wglCreateAssociatedContextAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAMD) +#define wglCreateAssociatedContextAttribsAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAttribsAMD) +#define wglDeleteAssociatedContextAMD WGLEW_GET_FUN(__wglewDeleteAssociatedContextAMD) +#define wglGetContextGPUIDAMD WGLEW_GET_FUN(__wglewGetContextGPUIDAMD) +#define wglGetCurrentAssociatedContextAMD WGLEW_GET_FUN(__wglewGetCurrentAssociatedContextAMD) +#define wglGetGPUIDsAMD WGLEW_GET_FUN(__wglewGetGPUIDsAMD) +#define wglGetGPUInfoAMD WGLEW_GET_FUN(__wglewGetGPUInfoAMD) +#define wglMakeAssociatedContextCurrentAMD WGLEW_GET_FUN(__wglewMakeAssociatedContextCurrentAMD) + +#define WGLEW_AMD_gpu_association WGLEW_GET_VAR(__WGLEW_AMD_gpu_association) + +#endif /* WGL_AMD_gpu_association */ + +/* ------------------------- 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 +#define ERROR_INVALID_VERSION_ARB 0x2095 +#define ERROR_INVALID_PROFILE_ARB 0x2096 + +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_create_context_profile -------------------- */ + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile 1 + +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 + +#define WGLEW_ARB_create_context_profile WGLEW_GET_VAR(__WGLEW_ARB_create_context_profile) + +#endif /* WGL_ARB_create_context_profile */ + +/* ------------------- WGL_ARB_create_context_robustness ------------------- */ + +#ifndef WGL_ARB_create_context_robustness +#define WGL_ARB_create_context_robustness 1 + +#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 + +#define WGLEW_ARB_create_context_robustness WGLEW_GET_VAR(__WGLEW_ARB_create_context_robustness) + +#endif /* WGL_ARB_create_context_robustness */ + +/* ----------------------- 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_ARB_robustness_application_isolation --------------- */ + +#ifndef WGL_ARB_robustness_application_isolation +#define WGL_ARB_robustness_application_isolation 1 + +#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 + +#define WGLEW_ARB_robustness_application_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_application_isolation) + +#endif /* WGL_ARB_robustness_application_isolation */ + +/* ---------------- WGL_ARB_robustness_share_group_isolation --------------- */ + +#ifndef WGL_ARB_robustness_share_group_isolation +#define WGL_ARB_robustness_share_group_isolation 1 + +#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 + +#define WGLEW_ARB_robustness_share_group_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_share_group_isolation) + +#endif /* WGL_ARB_robustness_share_group_isolation */ + +/* ----------------------- 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_create_context_es2_profile ------------------ */ + +#ifndef WGL_EXT_create_context_es2_profile +#define WGL_EXT_create_context_es2_profile 1 + +#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 + +#define WGLEW_EXT_create_context_es2_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es2_profile) + +#endif /* WGL_EXT_create_context_es2_profile */ + +/* ------------------- WGL_EXT_create_context_es_profile ------------------- */ + +#ifndef WGL_EXT_create_context_es_profile +#define WGL_EXT_create_context_es_profile 1 + +#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 + +#define WGLEW_EXT_create_context_es_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es_profile) + +#endif /* WGL_EXT_create_context_es_profile */ + +/* -------------------------- 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_EXT_swap_control_tear ----------------------- */ + +#ifndef WGL_EXT_swap_control_tear +#define WGL_EXT_swap_control_tear 1 + +#define WGLEW_EXT_swap_control_tear WGLEW_GET_VAR(__WGLEW_EXT_swap_control_tear) + +#endif /* WGL_EXT_swap_control_tear */ + +/* --------------------- 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_DX_interop --------------------------- */ + +#ifndef WGL_NV_DX_interop +#define WGL_NV_DX_interop 1 + +#define WGL_ACCESS_READ_ONLY_NV 0x0000 +#define WGL_ACCESS_READ_WRITE_NV 0x0001 +#define WGL_ACCESS_WRITE_DISCARD_NV 0x0002 + +typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); +typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); +typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); +typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice); +typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access); +typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void* dxObject, HANDLE shareHandle); +typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); +typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); + +#define wglDXCloseDeviceNV WGLEW_GET_FUN(__wglewDXCloseDeviceNV) +#define wglDXLockObjectsNV WGLEW_GET_FUN(__wglewDXLockObjectsNV) +#define wglDXObjectAccessNV WGLEW_GET_FUN(__wglewDXObjectAccessNV) +#define wglDXOpenDeviceNV WGLEW_GET_FUN(__wglewDXOpenDeviceNV) +#define wglDXRegisterObjectNV WGLEW_GET_FUN(__wglewDXRegisterObjectNV) +#define wglDXSetResourceShareHandleNV WGLEW_GET_FUN(__wglewDXSetResourceShareHandleNV) +#define wglDXUnlockObjectsNV WGLEW_GET_FUN(__wglewDXUnlockObjectsNV) +#define wglDXUnregisterObjectNV WGLEW_GET_FUN(__wglewDXUnregisterObjectNV) + +#define WGLEW_NV_DX_interop WGLEW_GET_VAR(__WGLEW_NV_DX_interop) + +#endif /* WGL_NV_DX_interop */ + +/* --------------------------- WGL_NV_DX_interop2 -------------------------- */ + +#ifndef WGL_NV_DX_interop2 +#define WGL_NV_DX_interop2 1 + +#define WGLEW_NV_DX_interop2 WGLEW_GET_VAR(__WGLEW_NV_DX_interop2) + +#endif /* WGL_NV_DX_interop2 */ + +/* --------------------------- WGL_NV_copy_image --------------------------- */ + +#ifndef WGL_NV_copy_image +#define WGL_NV_copy_image 1 + +typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + +#define wglCopyImageSubDataNV WGLEW_GET_FUN(__wglewCopyImageSubDataNV) + +#define WGLEW_NV_copy_image WGLEW_GET_VAR(__WGLEW_NV_copy_image) + +#endif /* WGL_NV_copy_image */ + +/* ------------------------ WGL_NV_delay_before_swap ----------------------- */ + +#ifndef WGL_NV_delay_before_swap +#define WGL_NV_delay_before_swap 1 + +typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds); + +#define wglDelayBeforeSwapNV WGLEW_GET_FUN(__wglewDelayBeforeSwapNV) + +#define WGLEW_NV_delay_before_swap WGLEW_GET_VAR(__WGLEW_NV_delay_before_swap) + +#endif /* WGL_NV_delay_before_swap */ + +/* -------------------------- 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_multisample_coverage ---------------------- */ + +#ifndef WGL_NV_multisample_coverage +#define WGL_NV_multisample_coverage 1 + +#define WGL_COVERAGE_SAMPLES_NV 0x2042 +#define WGL_COLOR_SAMPLES_NV 0x20B9 + +#define WGLEW_NV_multisample_coverage WGLEW_GET_VAR(__WGLEW_NV_multisample_coverage) + +#endif /* WGL_NV_multisample_coverage */ + +/* -------------------------- 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, GLuint *barrier); +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_capture ------------------------- */ + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture 1 + +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF + +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); +typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV* phDeviceList); +typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); + +#define wglBindVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewBindVideoCaptureDeviceNV) +#define wglEnumerateVideoCaptureDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoCaptureDevicesNV) +#define wglLockVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewLockVideoCaptureDeviceNV) +#define wglQueryVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewQueryVideoCaptureDeviceNV) +#define wglReleaseVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoCaptureDeviceNV) + +#define WGLEW_NV_video_capture WGLEW_GET_VAR(__WGLEW_NV_video_capture) + +#endif /* WGL_NV_video_capture */ + +/* -------------------------- 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_FUN_EXPORT +#define WGLEW_VAR_EXPORT +#else +#define WGLEW_FUN_EXPORT GLEW_FUN_EXPORT +#define WGLEW_VAR_EXPORT GLEW_VAR_EXPORT +#endif /* GLEW_MX */ + +#ifdef GLEW_MX +struct WGLEWContextStruct +{ +#endif /* GLEW_MX */ + +WGLEW_FUN_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; + +WGLEW_FUN_EXPORT PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD; +WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD; +WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD; +WGLEW_FUN_EXPORT PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD; +WGLEW_FUN_EXPORT PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD; +WGLEW_FUN_EXPORT PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD; +WGLEW_FUN_EXPORT PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD; +WGLEW_FUN_EXPORT PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD; +WGLEW_FUN_EXPORT PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD; + +WGLEW_FUN_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; +WGLEW_FUN_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; +WGLEW_FUN_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; +WGLEW_FUN_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; + +WGLEW_FUN_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB; + +WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; + +WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; +WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; + +WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; +WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; +WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; +WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; +WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; + +WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; +WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; +WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; + +WGLEW_FUN_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; +WGLEW_FUN_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; +WGLEW_FUN_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; + +WGLEW_FUN_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; +WGLEW_FUN_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; +WGLEW_FUN_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; +WGLEW_FUN_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; + +WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; + +WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; +WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; + +WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; +WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; +WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; +WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; +WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; + +WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; +WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; +WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; + +WGLEW_FUN_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; +WGLEW_FUN_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; + +WGLEW_FUN_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; +WGLEW_FUN_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; + +WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; +WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; +WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; +WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; + +WGLEW_FUN_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; +WGLEW_FUN_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; +WGLEW_FUN_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; +WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; +WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; +WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; +WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; +WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; +WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; +WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; +WGLEW_FUN_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; +WGLEW_FUN_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; + +WGLEW_FUN_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; +WGLEW_FUN_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; +WGLEW_FUN_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; +WGLEW_FUN_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; + +WGLEW_FUN_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; +WGLEW_FUN_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; +WGLEW_FUN_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; +WGLEW_FUN_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; + +WGLEW_FUN_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; +WGLEW_FUN_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; +WGLEW_FUN_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; +WGLEW_FUN_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; + +WGLEW_FUN_EXPORT PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV; +WGLEW_FUN_EXPORT PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV; +WGLEW_FUN_EXPORT PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV; +WGLEW_FUN_EXPORT PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV; +WGLEW_FUN_EXPORT PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV; +WGLEW_FUN_EXPORT PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV; +WGLEW_FUN_EXPORT PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV; +WGLEW_FUN_EXPORT PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV; + +WGLEW_FUN_EXPORT PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV; + +WGLEW_FUN_EXPORT PFNWGLDELAYBEFORESWAPNVPROC __wglewDelayBeforeSwapNV; + +WGLEW_FUN_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV; +WGLEW_FUN_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV; +WGLEW_FUN_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV; +WGLEW_FUN_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV; +WGLEW_FUN_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV; + +WGLEW_FUN_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV; +WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV; +WGLEW_FUN_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV; + +WGLEW_FUN_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV; +WGLEW_FUN_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV; +WGLEW_FUN_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV; +WGLEW_FUN_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV; +WGLEW_FUN_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV; +WGLEW_FUN_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV; + +WGLEW_FUN_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; +WGLEW_FUN_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; + +WGLEW_FUN_EXPORT PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV; +WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV; +WGLEW_FUN_EXPORT PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV; +WGLEW_FUN_EXPORT PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV; +WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV; + +WGLEW_FUN_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV; +WGLEW_FUN_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV; +WGLEW_FUN_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV; +WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV; +WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV; +WGLEW_FUN_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV; + +WGLEW_FUN_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; +WGLEW_FUN_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; +WGLEW_FUN_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; +WGLEW_FUN_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; +WGLEW_FUN_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; +WGLEW_FUN_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; +WGLEW_VAR_EXPORT GLboolean __WGLEW_3DFX_multisample; +WGLEW_VAR_EXPORT GLboolean __WGLEW_3DL_stereo_control; +WGLEW_VAR_EXPORT GLboolean __WGLEW_AMD_gpu_association; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_buffer_region; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_profile; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_robustness; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_extensions_string; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_make_current_read; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_multisample; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pbuffer; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_render_texture; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_application_isolation; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_share_group_isolation; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es2_profile; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es_profile; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_depth_float; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_display_color_table; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_extensions_string; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_make_current_read; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_multisample; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pbuffer; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control_tear; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_digital_video_control; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_gamma; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_genlock; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_image_buffer; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop2; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_copy_image; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_delay_before_swap; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_float_buffer; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_gpu_affinity; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_multisample_coverage; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_present_video; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_depth_texture; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_swap_group; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_vertex_array_range; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_capture; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_output; +WGLEW_VAR_EXPORT GLboolean __WGLEW_OML_sync_control; + +#ifdef GLEW_MX +}; /* WGLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX + +typedef struct WGLEWContextStruct WGLEWContext; +GLEWAPI GLenum GLEWAPIENTRY wglewContextInit (WGLEWContext *ctx); +GLEWAPI GLboolean GLEWAPIENTRY wglewContextIsSupported (const 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 GLEWAPIENTRY wglewIsSupported (const char *name); + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean GLEWAPIENTRY wglewGetExtension (const char *name); + +#ifdef __cplusplus +} +#endif + +#undef GLEWAPI + +#endif /* __wglew_h__ */ diff --git a/ext/native/ext/glew/glew.c b/ext/native/ext/glew/glew.c new file mode 100644 index 0000000000..9d43a24bdd --- /dev/null +++ b/ext/native/ext/glew/glew.c @@ -0,0 +1,18569 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2014, Nigel Stewart +** 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 "GL/glew.h" + +#if defined(_WIN32) +# include +#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) +# include "GL/glxew.h" +#endif + +#include /* For size_t */ + +/* + * 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(GLEW_REGAL) + +/* In GLEW_REGAL mode we call direcly into the linked + libRegal.so glGetProcAddressREGAL for looking up + the GL function pointers. */ + +# undef glGetProcAddressREGAL +# ifdef WIN32 +extern void * __stdcall glGetProcAddressREGAL(const GLchar *name); +static void * (__stdcall * regalGetProcAddress) (const GLchar *) = glGetProcAddressREGAL; +# else +extern void * glGetProcAddressREGAL(const GLchar *name); +static void * (*regalGetProcAddress) (const GLchar *) = glGetProcAddressREGAL; +# endif +# define glGetProcAddressREGAL GLEW_GET_FUN(__glewGetProcAddressREGAL) + +#elif defined(__sgi) || defined (__sun) || defined(__HAIKU__) || defined(GLEW_APPLE_GLX) +#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 || GLEW_APPLE_GLX */ + +#if defined(__APPLE__) +#include +#include +#include + +#ifdef MAC_OS_X_VERSION_10_3 + +#include + +void* NSGLGetProcAddress (const GLubyte *name) +{ + static void* image = NULL; + void* addr; + if (NULL == image) + { + image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); + } + if( !image ) return NULL; + addr = dlsym(image, (const char*)name); + if( addr ) return addr; +#ifdef GLEW_APPLE_GLX + return dlGetProcAddress( name ); // try next for glx symbols +#else + return NULL; +#endif +} +#else + +#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); + if( symbol ) return NSAddressOfSymbol(symbol); +#ifdef GLEW_APPLE_GLX + return dlGetProcAddress( name ); // try next for glx symbols +#else + return NULL; +#endif +} +#endif /* MAC_OS_X_VERSION_10_3 */ +#endif /* __APPLE__ */ + +/* + * Define glewGetProcAddress. + */ +#if defined(GLEW_REGAL) +# define glewGetProcAddress(name) regalGetProcAddress((const GLchar *) name) +#elif defined(_WIN32) +# define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name) +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) +# define glewGetProcAddress(name) NSGLGetProcAddress(name) +#elif defined(__sgi) || defined(__sun) || defined(__HAIKU__) +# define glewGetProcAddress(name) dlGetProcAddress(name) +#elif defined(__ANDROID__) +# define glewGetProcAddress(name) NULL /* TODO */ +#elif defined(__native_client__) +# define glewGetProcAddress(name) NULL /* TODO */ +#else /* __linux */ +# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name) +#endif + +/* + * Redefine GLEW_GET_VAR etc without const cast + */ + +#undef GLEW_GET_VAR +#ifdef GLEW_MX +# define GLEW_GET_VAR(x) (glewGetContext()->x) +#else /* GLEW_MX */ +# define GLEW_GET_VAR(x) (x) +#endif /* GLEW_MX */ + +#ifdef WGLEW_GET_VAR +# undef WGLEW_GET_VAR +# ifdef GLEW_MX +# define WGLEW_GET_VAR(x) (wglewGetContext()->x) +# else /* GLEW_MX */ +# define WGLEW_GET_VAR(x) (x) +# endif /* GLEW_MX */ +#endif /* WGLEW_GET_VAR */ + +#ifdef GLXEW_GET_VAR +# undef GLXEW_GET_VAR +# ifdef GLEW_MX +# define GLXEW_GET_VAR(x) (glxewGetContext()->x) +# else /* GLEW_MX */ +# define GLXEW_GET_VAR(x) (x) +# endif /* GLEW_MX */ +#endif /* GLXEW_GET_VAR */ + +/* + * 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; +} + +/* + * 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. + */ +static GLboolean _glewSearchExtension (const char* name, const GLubyte *start, const GLubyte *end) +{ + const GLubyte* p; + GLuint len = _glewStrLen((const GLubyte*)name); + p = start; + 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; +} + +#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; +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; +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; + +PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced = NULL; +PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex = NULL; +PFNGLTEXBUFFERPROC __glewTexBuffer = NULL; + +PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v = NULL; +PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v = NULL; + +PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor = NULL; + +PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei = NULL; +PFNGLBLENDEQUATIONIPROC __glewBlendEquationi = NULL; +PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei = NULL; +PFNGLBLENDFUNCIPROC __glewBlendFunci = NULL; +PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading = NULL; + +PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL; + +PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD = NULL; +PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD = NULL; +PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD = NULL; +PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD = NULL; + +PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD = NULL; +PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD = NULL; +PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD = NULL; +PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD = NULL; + +PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD = NULL; + +PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD = NULL; +PFNGLGENNAMESAMDPROC __glewGenNamesAMD = NULL; +PFNGLISNAMEAMDPROC __glewIsNameAMD = NULL; + +PFNGLQUERYOBJECTPARAMETERUIAMDPROC __glewQueryObjectParameteruiAMD = NULL; + +PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD = NULL; +PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD = NULL; +PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD = NULL; +PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD = NULL; +PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD = NULL; +PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD = NULL; +PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD = NULL; +PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD = NULL; +PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD = NULL; +PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD = NULL; +PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD = NULL; + +PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD = NULL; + +PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD = NULL; +PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD = NULL; + +PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD = NULL; + +PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD = NULL; +PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD = NULL; + +PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE = NULL; + +PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE = NULL; +PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE = NULL; +PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE = NULL; + +PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE = NULL; +PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE = NULL; +PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE = NULL; +PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE = NULL; +PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE = NULL; +PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE = NULL; +PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE = NULL; +PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE = NULL; +PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE = NULL; +PFNGLISQUERYANGLEPROC __glewIsQueryANGLE = NULL; +PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE = NULL; + +PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE = 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; + +PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE = NULL; +PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE = NULL; +PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE = 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; + +PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE = NULL; +PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE = NULL; +PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE = NULL; +PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE = NULL; +PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE = NULL; +PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE = NULL; +PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE = NULL; + +PFNGLCLEARDEPTHFPROC __glewClearDepthf = NULL; +PFNGLDEPTHRANGEFPROC __glewDepthRangef = NULL; +PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat = NULL; +PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler = NULL; +PFNGLSHADERBINARYPROC __glewShaderBinary = NULL; + +PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance = NULL; + +PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB = NULL; +PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB = NULL; +PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB = NULL; +PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB = NULL; +PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB = NULL; +PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB = NULL; +PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB = NULL; +PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB = NULL; +PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB = NULL; +PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB = NULL; +PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB = NULL; +PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB = NULL; +PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB = NULL; +PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB = NULL; + +PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed = NULL; +PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex = NULL; + +PFNGLBUFFERSTORAGEPROC __glewBufferStorage = NULL; +PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT = NULL; + +PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB = NULL; + +PFNGLCLEARBUFFERDATAPROC __glewClearBufferData = NULL; +PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData = NULL; +PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT = NULL; +PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT = NULL; + +PFNGLCLEARTEXIMAGEPROC __glewClearTexImage = NULL; +PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage = NULL; + +PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL; + +PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute = NULL; +PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect = NULL; + +PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB = NULL; + +PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData = NULL; + +PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData = NULL; + +PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB = NULL; +PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB = NULL; +PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB = NULL; +PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB = NULL; + +PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL; + +PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB = NULL; +PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB = NULL; +PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB = NULL; +PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB = NULL; + +PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex = NULL; + +PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect = NULL; +PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect = NULL; + +PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT = NULL; +PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT = NULL; + +PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer = NULL; +PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer = NULL; +PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus = NULL; +PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL; +PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer = 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; + +PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary = NULL; +PFNGLPROGRAMBINARYPROC __glewProgramBinary = NULL; +PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri = NULL; + +PFNGLGETUNIFORMDVPROC __glewGetUniformdv = NULL; +PFNGLUNIFORM1DPROC __glewUniform1d = NULL; +PFNGLUNIFORM1DVPROC __glewUniform1dv = NULL; +PFNGLUNIFORM2DPROC __glewUniform2d = NULL; +PFNGLUNIFORM2DVPROC __glewUniform2dv = NULL; +PFNGLUNIFORM3DPROC __glewUniform3d = NULL; +PFNGLUNIFORM3DVPROC __glewUniform3dv = NULL; +PFNGLUNIFORM4DPROC __glewUniform4d = NULL; +PFNGLUNIFORM4DVPROC __glewUniform4dv = NULL; +PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv = NULL; +PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv = NULL; +PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv = NULL; +PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv = NULL; +PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv = NULL; +PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv = NULL; +PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv = NULL; +PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv = NULL; +PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv = 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; + +PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB = NULL; + +PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB = NULL; +PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB = NULL; +PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB = NULL; + +PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ = NULL; + +PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v = NULL; + +PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData = NULL; +PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData = NULL; +PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer = NULL; +PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer = NULL; +PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage = NULL; +PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage = NULL; + +PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange = NULL; +PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange = NULL; + +PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB = NULL; +PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB = NULL; +PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB = NULL; +PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB = NULL; +PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB = NULL; + +PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase = NULL; +PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange = NULL; +PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures = NULL; +PFNGLBINDSAMPLERSPROC __glewBindSamplers = NULL; +PFNGLBINDTEXTURESPROC __glewBindTextures = NULL; +PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect = 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; + +PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv = NULL; +PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex = NULL; +PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName = NULL; +PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv = NULL; + +PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex = NULL; + +PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB = NULL; +PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB = NULL; +PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB = NULL; +PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB = NULL; +PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB = NULL; +PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB = NULL; +PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB = NULL; +PFNGLGETNMAPIVARBPROC __glewGetnMapivARB = NULL; +PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB = NULL; +PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB = NULL; +PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB = NULL; +PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB = NULL; +PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB = NULL; +PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB = NULL; +PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB = NULL; +PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB = NULL; +PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB = NULL; +PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB = NULL; +PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB = NULL; +PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB = NULL; + +PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB = NULL; + +PFNGLBINDSAMPLERPROC __glewBindSampler = NULL; +PFNGLDELETESAMPLERSPROC __glewDeleteSamplers = NULL; +PFNGLGENSAMPLERSPROC __glewGenSamplers = NULL; +PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv = NULL; +PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv = NULL; +PFNGLISSAMPLERPROC __glewIsSampler = NULL; +PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv = NULL; +PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv = NULL; +PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf = NULL; +PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv = NULL; +PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv = NULL; + +PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram = NULL; +PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline = NULL; +PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv = NULL; +PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines = NULL; +PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines = NULL; +PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog = NULL; +PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv = NULL; +PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline = NULL; +PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d = NULL; +PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv = NULL; +PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f = NULL; +PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv = NULL; +PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i = NULL; +PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv = NULL; +PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui = NULL; +PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv = NULL; +PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d = NULL; +PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv = NULL; +PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f = NULL; +PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv = NULL; +PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i = NULL; +PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv = NULL; +PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui = NULL; +PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv = NULL; +PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d = NULL; +PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv = NULL; +PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f = NULL; +PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv = NULL; +PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i = NULL; +PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv = NULL; +PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui = NULL; +PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv = NULL; +PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d = NULL; +PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv = NULL; +PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f = NULL; +PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv = NULL; +PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i = NULL; +PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv = NULL; +PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui = NULL; +PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv = NULL; +PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages = NULL; +PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline = NULL; + +PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv = NULL; + +PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture = NULL; +PFNGLMEMORYBARRIERPROC __glewMemoryBarrier = 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; + +PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding = NULL; + +PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv = NULL; +PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv = NULL; +PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex = NULL; +PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation = NULL; +PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv = NULL; +PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv = NULL; + +PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB = NULL; +PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB = NULL; +PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB = NULL; +PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB = NULL; +PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB = NULL; +PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB = NULL; + +PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB = NULL; +PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT = NULL; + +PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync = NULL; +PFNGLDELETESYNCPROC __glewDeleteSync = NULL; +PFNGLFENCESYNCPROC __glewFenceSync = NULL; +PFNGLGETINTEGER64VPROC __glewGetInteger64v = NULL; +PFNGLGETSYNCIVPROC __glewGetSynciv = NULL; +PFNGLISSYNCPROC __glewIsSync = NULL; +PFNGLWAITSYNCPROC __glewWaitSync = NULL; + +PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv = NULL; +PFNGLPATCHPARAMETERIPROC __glewPatchParameteri = NULL; + +PFNGLTEXBUFFERARBPROC __glewTexBufferARB = NULL; + +PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange = NULL; +PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT = NULL; + +PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL; + +PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv = NULL; +PFNGLSAMPLEMASKIPROC __glewSampleMaski = NULL; +PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample = NULL; +PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample = NULL; + +PFNGLTEXSTORAGE1DPROC __glewTexStorage1D = NULL; +PFNGLTEXSTORAGE2DPROC __glewTexStorage2D = NULL; +PFNGLTEXSTORAGE3DPROC __glewTexStorage3D = NULL; +PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT = NULL; +PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT = NULL; +PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT = NULL; + +PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample = NULL; +PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample = NULL; +PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT = NULL; + +PFNGLTEXTUREVIEWPROC __glewTextureView = NULL; + +PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v = NULL; +PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v = NULL; +PFNGLQUERYCOUNTERPROC __glewQueryCounter = NULL; + +PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback = NULL; +PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks = NULL; +PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback = NULL; +PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks = NULL; +PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback = NULL; +PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback = NULL; +PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback = NULL; + +PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream = NULL; +PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed = NULL; +PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv = NULL; + +PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced = NULL; + +PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL; +PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL; +PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL; +PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL; + +PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv = NULL; +PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex = NULL; +PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding = NULL; + +PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL; +PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL; +PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL; +PFNGLISVERTEXARRAYPROC __glewIsVertexArray = NULL; + +PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv = NULL; +PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d = NULL; +PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv = NULL; +PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d = NULL; +PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv = NULL; +PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d = NULL; +PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv = NULL; +PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d = NULL; +PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv = NULL; +PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer = NULL; + +PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer = NULL; +PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC __glewVertexArrayBindVertexBufferEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC __glewVertexArrayVertexAttribBindingEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC __glewVertexArrayVertexAttribFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC __glewVertexArrayVertexAttribIFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC __glewVertexArrayVertexAttribLFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC __glewVertexArrayVertexBindingDivisorEXT = NULL; +PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding = NULL; +PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat = NULL; +PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat = NULL; +PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat = NULL; +PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor = 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; + +PFNGLCOLORP3UIPROC __glewColorP3ui = NULL; +PFNGLCOLORP3UIVPROC __glewColorP3uiv = NULL; +PFNGLCOLORP4UIPROC __glewColorP4ui = NULL; +PFNGLCOLORP4UIVPROC __glewColorP4uiv = NULL; +PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui = NULL; +PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv = NULL; +PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui = NULL; +PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv = NULL; +PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui = NULL; +PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv = NULL; +PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui = NULL; +PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv = NULL; +PFNGLNORMALP3UIPROC __glewNormalP3ui = NULL; +PFNGLNORMALP3UIVPROC __glewNormalP3uiv = NULL; +PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui = NULL; +PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv = NULL; +PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui = NULL; +PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv = NULL; +PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui = NULL; +PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv = NULL; +PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui = NULL; +PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv = NULL; +PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui = NULL; +PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv = NULL; +PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui = NULL; +PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv = NULL; +PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui = NULL; +PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv = NULL; +PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui = NULL; +PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv = NULL; +PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui = NULL; +PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv = NULL; +PFNGLVERTEXP2UIPROC __glewVertexP2ui = NULL; +PFNGLVERTEXP2UIVPROC __glewVertexP2uiv = NULL; +PFNGLVERTEXP3UIPROC __glewVertexP3ui = NULL; +PFNGLVERTEXP3UIVPROC __glewVertexP3uiv = NULL; +PFNGLVERTEXP4UIPROC __glewVertexP4ui = NULL; +PFNGLVERTEXP4UIVPROC __glewVertexP4uiv = NULL; + +PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv = NULL; +PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed = NULL; +PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v = NULL; +PFNGLGETFLOATI_VPROC __glewGetFloati_v = NULL; +PFNGLSCISSORARRAYVPROC __glewScissorArrayv = NULL; +PFNGLSCISSORINDEXEDPROC __glewScissorIndexed = NULL; +PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv = NULL; +PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv = NULL; +PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf = NULL; +PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv = 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 __glewPNTrianglesfATI = NULL; +PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI = 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; +PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI = NULL; +PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI = NULL; +PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI = NULL; +PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI = NULL; +PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI = NULL; +PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI = NULL; +PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI = NULL; +PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI = 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; + +PFNGLGETOBJECTLABELEXTPROC __glewGetObjectLabelEXT = NULL; +PFNGLLABELOBJECTEXTPROC __glewLabelObjectEXT = NULL; + +PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT = NULL; +PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT = NULL; +PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT = 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; +PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT = NULL; +PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT = NULL; +PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT = NULL; +PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT = NULL; +PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT = NULL; +PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT = NULL; +PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT = NULL; +PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT = 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; +PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT = NULL; +PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT = NULL; +PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT = 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; +PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT = NULL; +PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT = NULL; +PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT = NULL; +PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT = NULL; +PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT = NULL; +PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT = NULL; +PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT = NULL; +PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT = NULL; +PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT = NULL; +PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT = 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; +PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT = 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; +PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT = NULL; +PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT = NULL; +PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT = NULL; +PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT = NULL; +PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT = NULL; +PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC __glewVertexArrayVertexAttribDivisorEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT = 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; +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; + +PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT = 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; + +PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT = NULL; +PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT = NULL; +PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT = NULL; + +PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT = NULL; +PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT = NULL; + +PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL; + +PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL; +PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT = NULL; +PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT = NULL; + +PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT = NULL; + +PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT = 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; +PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT = NULL; +PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT = NULL; +PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT = NULL; +PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT = NULL; + +PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT = NULL; +PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT = NULL; +PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT = NULL; +PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT = NULL; +PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT = NULL; +PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT = NULL; +PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT = NULL; +PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT = NULL; +PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT = NULL; +PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT = 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; + +PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT = 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; + +PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL = NULL; +PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL = NULL; +PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL = NULL; + +PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL = NULL; +PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL = NULL; +PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL = NULL; +PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL = NULL; + +PFNGLBEGINPERFQUERYINTELPROC __glewBeginPerfQueryINTEL = NULL; +PFNGLCREATEPERFQUERYINTELPROC __glewCreatePerfQueryINTEL = NULL; +PFNGLDELETEPERFQUERYINTELPROC __glewDeletePerfQueryINTEL = NULL; +PFNGLENDPERFQUERYINTELPROC __glewEndPerfQueryINTEL = NULL; +PFNGLGETFIRSTPERFQUERYIDINTELPROC __glewGetFirstPerfQueryIdINTEL = NULL; +PFNGLGETNEXTPERFQUERYIDINTELPROC __glewGetNextPerfQueryIdINTEL = NULL; +PFNGLGETPERFCOUNTERINFOINTELPROC __glewGetPerfCounterInfoINTEL = NULL; +PFNGLGETPERFQUERYDATAINTELPROC __glewGetPerfQueryDataINTEL = NULL; +PFNGLGETPERFQUERYIDBYNAMEINTELPROC __glewGetPerfQueryIdByNameINTEL = NULL; +PFNGLGETPERFQUERYINFOINTELPROC __glewGetPerfQueryInfoINTEL = NULL; + +PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL = NULL; +PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL = NULL; + +PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback = NULL; +PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl = NULL; +PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert = NULL; +PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog = NULL; +PFNGLGETOBJECTLABELPROC __glewGetObjectLabel = NULL; +PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel = NULL; +PFNGLOBJECTLABELPROC __glewObjectLabel = NULL; +PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel = NULL; +PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup = NULL; +PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup = NULL; + +PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled = NULL; +PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion = NULL; +PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion = NULL; +PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion = NULL; +PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion = 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; + +PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX = NULL; +PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV = NULL; + +PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV = NULL; +PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV = NULL; +PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV = NULL; +PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV = NULL; +PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV = NULL; +PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV = NULL; +PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV = NULL; +PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV = NULL; +PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV = NULL; +PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV = NULL; +PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV = NULL; + +PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV = NULL; +PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV = NULL; + +PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL; +PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL; + +PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV = NULL; + +PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL; +PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV = NULL; +PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL; + +PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV = 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; + +PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV = NULL; +PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV = NULL; +PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV = NULL; +PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV = NULL; +PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV = NULL; +PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV = NULL; +PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV = NULL; +PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV = NULL; +PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV = NULL; +PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV = NULL; +PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV = NULL; +PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV = NULL; +PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV = NULL; +PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV = NULL; +PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV = NULL; +PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV = NULL; +PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV = NULL; +PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV = NULL; +PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV = NULL; +PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV = NULL; +PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV = NULL; +PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV = NULL; +PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV = NULL; +PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV = NULL; +PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV = NULL; +PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV = NULL; +PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV = NULL; +PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV = NULL; +PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV = NULL; +PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV = NULL; +PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV = NULL; +PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV = NULL; +PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV = NULL; +PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV = 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; + +PFNGLCOPYPATHNVPROC __glewCopyPathNV = NULL; +PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV = NULL; +PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV = NULL; +PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV = NULL; +PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV = NULL; +PFNGLDELETEPATHSNVPROC __glewDeletePathsNV = NULL; +PFNGLGENPATHSNVPROC __glewGenPathsNV = NULL; +PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV = NULL; +PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV = NULL; +PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV = NULL; +PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV = NULL; +PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV = NULL; +PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV = NULL; +PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV = NULL; +PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV = NULL; +PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV = NULL; +PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV = NULL; +PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV = NULL; +PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV = NULL; +PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV = NULL; +PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV = NULL; +PFNGLISPATHNVPROC __glewIsPathNV = NULL; +PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV = NULL; +PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV = NULL; +PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV = NULL; +PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV = NULL; +PFNGLPATHCOORDSNVPROC __glewPathCoordsNV = NULL; +PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV = NULL; +PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV = NULL; +PFNGLPATHFOGGENNVPROC __glewPathFogGenNV = NULL; +PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV = NULL; +PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV = NULL; +PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV = NULL; +PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV = NULL; +PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV = NULL; +PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV = NULL; +PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV = NULL; +PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV = NULL; +PFNGLPATHSTRINGNVPROC __glewPathStringNV = NULL; +PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV = NULL; +PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV = NULL; +PFNGLPATHTEXGENNVPROC __glewPathTexGenNV = NULL; +PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV = NULL; +PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV = NULL; +PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV = NULL; +PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV = NULL; +PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV = NULL; +PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV = NULL; +PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV = 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; + +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; + +PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV = NULL; +PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV = NULL; +PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV = NULL; +PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV = NULL; +PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV = NULL; +PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV = NULL; +PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV = NULL; +PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV = NULL; +PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV = NULL; +PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV = NULL; +PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV = NULL; +PFNGLUNIFORMUI64NVPROC __glewUniformui64NV = NULL; +PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV = NULL; + +PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV = NULL; + +PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV = NULL; +PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV = NULL; +PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV = 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; + +PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV = NULL; +PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV = NULL; +PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV = NULL; +PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV = NULL; +PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV = NULL; +PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV = NULL; +PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV = NULL; + +PFNGLVDPAUFININVPROC __glewVDPAUFiniNV = NULL; +PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV = NULL; +PFNGLVDPAUINITNVPROC __glewVDPAUInitNV = NULL; +PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV = NULL; +PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV = NULL; +PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV = NULL; +PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV = NULL; +PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV = NULL; +PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV = NULL; +PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV = NULL; + +PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL; +PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL; + +PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV = NULL; +PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV = NULL; +PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV = NULL; +PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV = NULL; +PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV = NULL; +PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV = NULL; +PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV = NULL; +PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV = NULL; +PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV = NULL; +PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV = NULL; +PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV = NULL; +PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV = NULL; +PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV = NULL; +PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV = NULL; +PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV = NULL; +PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV = NULL; +PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV = NULL; +PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV = NULL; +PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV = NULL; + +PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV = NULL; +PFNGLCOLORFORMATNVPROC __glewColorFormatNV = NULL; +PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV = NULL; +PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV = NULL; +PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV = NULL; +PFNGLINDEXFORMATNVPROC __glewIndexFormatNV = NULL; +PFNGLNORMALFORMATNVPROC __glewNormalFormatNV = NULL; +PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV = NULL; +PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV = NULL; +PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV = NULL; +PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV = NULL; +PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV = 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; + +PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV = NULL; +PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV = NULL; +PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV = NULL; +PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV = NULL; +PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV = NULL; +PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV = NULL; + +PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES = NULL; +PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES = NULL; +PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES = NULL; +PFNGLFRUSTUMFOESPROC __glewFrustumfOES = NULL; +PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES = NULL; +PFNGLORTHOFOESPROC __glewOrthofOES = NULL; + +PFNGLALPHAFUNCXPROC __glewAlphaFuncx = NULL; +PFNGLCLEARCOLORXPROC __glewClearColorx = NULL; +PFNGLCLEARDEPTHXPROC __glewClearDepthx = NULL; +PFNGLCOLOR4XPROC __glewColor4x = NULL; +PFNGLDEPTHRANGEXPROC __glewDepthRangex = NULL; +PFNGLFOGXPROC __glewFogx = NULL; +PFNGLFOGXVPROC __glewFogxv = NULL; +PFNGLFRUSTUMFPROC __glewFrustumf = NULL; +PFNGLFRUSTUMXPROC __glewFrustumx = NULL; +PFNGLLIGHTMODELXPROC __glewLightModelx = NULL; +PFNGLLIGHTMODELXVPROC __glewLightModelxv = NULL; +PFNGLLIGHTXPROC __glewLightx = NULL; +PFNGLLIGHTXVPROC __glewLightxv = NULL; +PFNGLLINEWIDTHXPROC __glewLineWidthx = NULL; +PFNGLLOADMATRIXXPROC __glewLoadMatrixx = NULL; +PFNGLMATERIALXPROC __glewMaterialx = NULL; +PFNGLMATERIALXVPROC __glewMaterialxv = NULL; +PFNGLMULTMATRIXXPROC __glewMultMatrixx = NULL; +PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x = NULL; +PFNGLNORMAL3XPROC __glewNormal3x = NULL; +PFNGLORTHOFPROC __glewOrthof = NULL; +PFNGLORTHOXPROC __glewOrthox = NULL; +PFNGLPOINTSIZEXPROC __glewPointSizex = NULL; +PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx = NULL; +PFNGLROTATEXPROC __glewRotatex = NULL; +PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex = NULL; +PFNGLSCALEXPROC __glewScalex = NULL; +PFNGLTEXENVXPROC __glewTexEnvx = NULL; +PFNGLTEXENVXVPROC __glewTexEnvxv = NULL; +PFNGLTEXPARAMETERXPROC __glewTexParameterx = NULL; +PFNGLTRANSLATEXPROC __glewTranslatex = NULL; + +PFNGLCLIPPLANEFPROC __glewClipPlanef = NULL; +PFNGLCLIPPLANEXPROC __glewClipPlanex = NULL; +PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef = NULL; +PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex = NULL; +PFNGLGETFIXEDVPROC __glewGetFixedv = NULL; +PFNGLGETLIGHTXVPROC __glewGetLightxv = NULL; +PFNGLGETMATERIALXVPROC __glewGetMaterialxv = NULL; +PFNGLGETTEXENVXVPROC __glewGetTexEnvxv = NULL; +PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv = NULL; +PFNGLPOINTPARAMETERXPROC __glewPointParameterx = NULL; +PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv = NULL; +PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES = NULL; +PFNGLTEXPARAMETERXVPROC __glewTexParameterxv = NULL; + +PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL = NULL; + +PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL = NULL; +PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL = NULL; + +PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL = NULL; + +PFNGLGETPROCADDRESSREGALPROC __glewGetProcAddressREGAL = 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_2_1 = 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_VERSION_3_1 = GL_FALSE; +GLboolean __GLEW_VERSION_3_2 = GL_FALSE; +GLboolean __GLEW_VERSION_3_3 = GL_FALSE; +GLboolean __GLEW_VERSION_4_0 = GL_FALSE; +GLboolean __GLEW_VERSION_4_1 = GL_FALSE; +GLboolean __GLEW_VERSION_4_2 = GL_FALSE; +GLboolean __GLEW_VERSION_4_3 = GL_FALSE; +GLboolean __GLEW_VERSION_4_4 = GL_FALSE; +GLboolean __GLEW_3DFX_multisample = GL_FALSE; +GLboolean __GLEW_3DFX_tbuffer = GL_FALSE; +GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE; +GLboolean __GLEW_AMD_blend_minmax_factor = GL_FALSE; +GLboolean __GLEW_AMD_conservative_depth = GL_FALSE; +GLboolean __GLEW_AMD_debug_output = GL_FALSE; +GLboolean __GLEW_AMD_depth_clamp_separate = GL_FALSE; +GLboolean __GLEW_AMD_draw_buffers_blend = GL_FALSE; +GLboolean __GLEW_AMD_gcn_shader = GL_FALSE; +GLboolean __GLEW_AMD_gpu_shader_int64 = GL_FALSE; +GLboolean __GLEW_AMD_interleaved_elements = GL_FALSE; +GLboolean __GLEW_AMD_multi_draw_indirect = GL_FALSE; +GLboolean __GLEW_AMD_name_gen_delete = GL_FALSE; +GLboolean __GLEW_AMD_occlusion_query_event = GL_FALSE; +GLboolean __GLEW_AMD_performance_monitor = GL_FALSE; +GLboolean __GLEW_AMD_pinned_memory = GL_FALSE; +GLboolean __GLEW_AMD_query_buffer_object = GL_FALSE; +GLboolean __GLEW_AMD_sample_positions = GL_FALSE; +GLboolean __GLEW_AMD_seamless_cubemap_per_texture = GL_FALSE; +GLboolean __GLEW_AMD_shader_atomic_counter_ops = GL_FALSE; +GLboolean __GLEW_AMD_shader_stencil_export = GL_FALSE; +GLboolean __GLEW_AMD_shader_stencil_value_export = GL_FALSE; +GLboolean __GLEW_AMD_shader_trinary_minmax = GL_FALSE; +GLboolean __GLEW_AMD_sparse_texture = GL_FALSE; +GLboolean __GLEW_AMD_stencil_operation_extended = GL_FALSE; +GLboolean __GLEW_AMD_texture_texture4 = GL_FALSE; +GLboolean __GLEW_AMD_transform_feedback3_lines_triangles = GL_FALSE; +GLboolean __GLEW_AMD_transform_feedback4 = GL_FALSE; +GLboolean __GLEW_AMD_vertex_shader_layer = GL_FALSE; +GLboolean __GLEW_AMD_vertex_shader_tessellator = GL_FALSE; +GLboolean __GLEW_AMD_vertex_shader_viewport_index = GL_FALSE; +GLboolean __GLEW_ANGLE_depth_texture = GL_FALSE; +GLboolean __GLEW_ANGLE_framebuffer_blit = GL_FALSE; +GLboolean __GLEW_ANGLE_framebuffer_multisample = GL_FALSE; +GLboolean __GLEW_ANGLE_instanced_arrays = GL_FALSE; +GLboolean __GLEW_ANGLE_pack_reverse_row_order = GL_FALSE; +GLboolean __GLEW_ANGLE_program_binary = GL_FALSE; +GLboolean __GLEW_ANGLE_texture_compression_dxt1 = GL_FALSE; +GLboolean __GLEW_ANGLE_texture_compression_dxt3 = GL_FALSE; +GLboolean __GLEW_ANGLE_texture_compression_dxt5 = GL_FALSE; +GLboolean __GLEW_ANGLE_texture_usage = GL_FALSE; +GLboolean __GLEW_ANGLE_timer_query = GL_FALSE; +GLboolean __GLEW_ANGLE_translated_shader_source = GL_FALSE; +GLboolean __GLEW_APPLE_aux_depth_stencil = 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_object_purgeable = GL_FALSE; +GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE; +GLboolean __GLEW_APPLE_rgb_422 = GL_FALSE; +GLboolean __GLEW_APPLE_row_bytes = 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_vertex_program_evaluators = GL_FALSE; +GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE; +GLboolean __GLEW_ARB_ES2_compatibility = GL_FALSE; +GLboolean __GLEW_ARB_ES3_compatibility = GL_FALSE; +GLboolean __GLEW_ARB_arrays_of_arrays = GL_FALSE; +GLboolean __GLEW_ARB_base_instance = GL_FALSE; +GLboolean __GLEW_ARB_bindless_texture = GL_FALSE; +GLboolean __GLEW_ARB_blend_func_extended = GL_FALSE; +GLboolean __GLEW_ARB_buffer_storage = GL_FALSE; +GLboolean __GLEW_ARB_cl_event = GL_FALSE; +GLboolean __GLEW_ARB_clear_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_clear_texture = GL_FALSE; +GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_compatibility = GL_FALSE; +GLboolean __GLEW_ARB_compressed_texture_pixel_storage = GL_FALSE; +GLboolean __GLEW_ARB_compute_shader = GL_FALSE; +GLboolean __GLEW_ARB_compute_variable_group_size = GL_FALSE; +GLboolean __GLEW_ARB_conservative_depth = GL_FALSE; +GLboolean __GLEW_ARB_copy_buffer = GL_FALSE; +GLboolean __GLEW_ARB_copy_image = GL_FALSE; +GLboolean __GLEW_ARB_debug_output = GL_FALSE; +GLboolean __GLEW_ARB_depth_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_depth_clamp = GL_FALSE; +GLboolean __GLEW_ARB_depth_texture = GL_FALSE; +GLboolean __GLEW_ARB_draw_buffers = GL_FALSE; +GLboolean __GLEW_ARB_draw_buffers_blend = GL_FALSE; +GLboolean __GLEW_ARB_draw_elements_base_vertex = GL_FALSE; +GLboolean __GLEW_ARB_draw_indirect = GL_FALSE; +GLboolean __GLEW_ARB_draw_instanced = GL_FALSE; +GLboolean __GLEW_ARB_enhanced_layouts = GL_FALSE; +GLboolean __GLEW_ARB_explicit_attrib_location = GL_FALSE; +GLboolean __GLEW_ARB_explicit_uniform_location = GL_FALSE; +GLboolean __GLEW_ARB_fragment_coord_conventions = GL_FALSE; +GLboolean __GLEW_ARB_fragment_layer_viewport = 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_no_attachments = 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_get_program_binary = GL_FALSE; +GLboolean __GLEW_ARB_gpu_shader5 = GL_FALSE; +GLboolean __GLEW_ARB_gpu_shader_fp64 = 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_indirect_parameters = GL_FALSE; +GLboolean __GLEW_ARB_instanced_arrays = GL_FALSE; +GLboolean __GLEW_ARB_internalformat_query = GL_FALSE; +GLboolean __GLEW_ARB_internalformat_query2 = GL_FALSE; +GLboolean __GLEW_ARB_invalidate_subdata = GL_FALSE; +GLboolean __GLEW_ARB_map_buffer_alignment = GL_FALSE; +GLboolean __GLEW_ARB_map_buffer_range = GL_FALSE; +GLboolean __GLEW_ARB_matrix_palette = GL_FALSE; +GLboolean __GLEW_ARB_multi_bind = GL_FALSE; +GLboolean __GLEW_ARB_multi_draw_indirect = GL_FALSE; +GLboolean __GLEW_ARB_multisample = GL_FALSE; +GLboolean __GLEW_ARB_multitexture = GL_FALSE; +GLboolean __GLEW_ARB_occlusion_query = GL_FALSE; +GLboolean __GLEW_ARB_occlusion_query2 = 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_program_interface_query = GL_FALSE; +GLboolean __GLEW_ARB_provoking_vertex = GL_FALSE; +GLboolean __GLEW_ARB_query_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_robust_buffer_access_behavior = GL_FALSE; +GLboolean __GLEW_ARB_robustness = GL_FALSE; +GLboolean __GLEW_ARB_robustness_application_isolation = GL_FALSE; +GLboolean __GLEW_ARB_robustness_share_group_isolation = GL_FALSE; +GLboolean __GLEW_ARB_sample_shading = GL_FALSE; +GLboolean __GLEW_ARB_sampler_objects = GL_FALSE; +GLboolean __GLEW_ARB_seamless_cube_map = GL_FALSE; +GLboolean __GLEW_ARB_seamless_cubemap_per_texture = GL_FALSE; +GLboolean __GLEW_ARB_separate_shader_objects = GL_FALSE; +GLboolean __GLEW_ARB_shader_atomic_counters = GL_FALSE; +GLboolean __GLEW_ARB_shader_bit_encoding = GL_FALSE; +GLboolean __GLEW_ARB_shader_draw_parameters = GL_FALSE; +GLboolean __GLEW_ARB_shader_group_vote = GL_FALSE; +GLboolean __GLEW_ARB_shader_image_load_store = GL_FALSE; +GLboolean __GLEW_ARB_shader_image_size = GL_FALSE; +GLboolean __GLEW_ARB_shader_objects = GL_FALSE; +GLboolean __GLEW_ARB_shader_precision = GL_FALSE; +GLboolean __GLEW_ARB_shader_stencil_export = GL_FALSE; +GLboolean __GLEW_ARB_shader_storage_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_shader_subroutine = GL_FALSE; +GLboolean __GLEW_ARB_shader_texture_lod = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_420pack = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_include = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_packing = GL_FALSE; +GLboolean __GLEW_ARB_shadow = GL_FALSE; +GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE; +GLboolean __GLEW_ARB_sparse_texture = GL_FALSE; +GLboolean __GLEW_ARB_stencil_texturing = GL_FALSE; +GLboolean __GLEW_ARB_sync = GL_FALSE; +GLboolean __GLEW_ARB_tessellation_shader = GL_FALSE; +GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_ARB_texture_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_texture_buffer_object_rgb32 = GL_FALSE; +GLboolean __GLEW_ARB_texture_buffer_range = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression_bptc = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression_rgtc = GL_FALSE; +GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE; +GLboolean __GLEW_ARB_texture_cube_map_array = 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_gather = GL_FALSE; +GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge = GL_FALSE; +GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_ARB_texture_multisample = GL_FALSE; +GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE; +GLboolean __GLEW_ARB_texture_query_levels = GL_FALSE; +GLboolean __GLEW_ARB_texture_query_lod = GL_FALSE; +GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE; +GLboolean __GLEW_ARB_texture_rg = GL_FALSE; +GLboolean __GLEW_ARB_texture_rgb10_a2ui = GL_FALSE; +GLboolean __GLEW_ARB_texture_stencil8 = GL_FALSE; +GLboolean __GLEW_ARB_texture_storage = GL_FALSE; +GLboolean __GLEW_ARB_texture_storage_multisample = GL_FALSE; +GLboolean __GLEW_ARB_texture_swizzle = GL_FALSE; +GLboolean __GLEW_ARB_texture_view = GL_FALSE; +GLboolean __GLEW_ARB_timer_query = GL_FALSE; +GLboolean __GLEW_ARB_transform_feedback2 = GL_FALSE; +GLboolean __GLEW_ARB_transform_feedback3 = GL_FALSE; +GLboolean __GLEW_ARB_transform_feedback_instanced = GL_FALSE; +GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE; +GLboolean __GLEW_ARB_uniform_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_array_bgra = GL_FALSE; +GLboolean __GLEW_ARB_vertex_array_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_attrib_64bit = GL_FALSE; +GLboolean __GLEW_ARB_vertex_attrib_binding = 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_vertex_type_10f_11f_11f_rev = GL_FALSE; +GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev = GL_FALSE; +GLboolean __GLEW_ARB_viewport_array = 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_meminfo = 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_debug_label = GL_FALSE; +GLboolean __GLEW_EXT_debug_marker = 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_multisample_blit_scaled = 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_provoking_vertex = 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_shader_objects = GL_FALSE; +GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE; +GLboolean __GLEW_EXT_shader_image_load_formatted = GL_FALSE; +GLboolean __GLEW_EXT_shader_image_load_store = GL_FALSE; +GLboolean __GLEW_EXT_shader_integer_mix = 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_sRGB_decode = GL_FALSE; +GLboolean __GLEW_EXT_texture_shared_exponent = GL_FALSE; +GLboolean __GLEW_EXT_texture_snorm = 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_attrib_64bit = GL_FALSE; +GLboolean __GLEW_EXT_vertex_shader = GL_FALSE; +GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE; +GLboolean __GLEW_EXT_x11_sync_object = 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_fragment_shader_ordering = GL_FALSE; +GLboolean __GLEW_INTEL_map_texture = GL_FALSE; +GLboolean __GLEW_INTEL_parallel_arrays = GL_FALSE; +GLboolean __GLEW_INTEL_performance_query = GL_FALSE; +GLboolean __GLEW_INTEL_texture_scissor = GL_FALSE; +GLboolean __GLEW_KHR_debug = GL_FALSE; +GLboolean __GLEW_KHR_texture_compression_astc_hdr = GL_FALSE; +GLboolean __GLEW_KHR_texture_compression_astc_ldr = 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_NVX_conditional_render = GL_FALSE; +GLboolean __GLEW_NVX_gpu_memory_info = GL_FALSE; +GLboolean __GLEW_NV_bindless_multi_draw_indirect = GL_FALSE; +GLboolean __GLEW_NV_bindless_texture = GL_FALSE; +GLboolean __GLEW_NV_blend_equation_advanced = GL_FALSE; +GLboolean __GLEW_NV_blend_equation_advanced_coherent = GL_FALSE; +GLboolean __GLEW_NV_blend_square = GL_FALSE; +GLboolean __GLEW_NV_compute_program5 = GL_FALSE; +GLboolean __GLEW_NV_conditional_render = GL_FALSE; +GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE; +GLboolean __GLEW_NV_copy_image = GL_FALSE; +GLboolean __GLEW_NV_deep_texture3D = 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_draw_texture = 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_gpu_program5 = GL_FALSE; +GLboolean __GLEW_NV_gpu_program5_mem_extended = GL_FALSE; +GLboolean __GLEW_NV_gpu_program_fp64 = GL_FALSE; +GLboolean __GLEW_NV_gpu_shader5 = GL_FALSE; +GLboolean __GLEW_NV_half_float = GL_FALSE; +GLboolean __GLEW_NV_light_max_exponent = GL_FALSE; +GLboolean __GLEW_NV_multisample_coverage = 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_parameter_buffer_object2 = GL_FALSE; +GLboolean __GLEW_NV_path_rendering = 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_shader_atomic_counters = GL_FALSE; +GLboolean __GLEW_NV_shader_atomic_float = GL_FALSE; +GLboolean __GLEW_NV_shader_buffer_load = GL_FALSE; +GLboolean __GLEW_NV_shader_storage_buffer_object = GL_FALSE; +GLboolean __GLEW_NV_shader_thread_group = GL_FALSE; +GLboolean __GLEW_NV_shader_thread_shuffle = GL_FALSE; +GLboolean __GLEW_NV_tessellation_program5 = GL_FALSE; +GLboolean __GLEW_NV_texgen_emboss = GL_FALSE; +GLboolean __GLEW_NV_texgen_reflection = GL_FALSE; +GLboolean __GLEW_NV_texture_barrier = 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_multisample = 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_transform_feedback2 = GL_FALSE; +GLboolean __GLEW_NV_vdpau_interop = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_attrib_integer_64bit = GL_FALSE; +GLboolean __GLEW_NV_vertex_buffer_unified_memory = 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_NV_video_capture = 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_REGAL_ES1_0_compatibility = GL_FALSE; +GLboolean __GLEW_REGAL_ES1_1_compatibility = GL_FALSE; +GLboolean __GLEW_REGAL_enable = GL_FALSE; +GLboolean __GLEW_REGAL_error_string = GL_FALSE; +GLboolean __GLEW_REGAL_extension_query = GL_FALSE; +GLboolean __GLEW_REGAL_log = GL_FALSE; +GLboolean __GLEW_REGAL_proc_address = 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_2_1 + +#endif /* GL_VERSION_1_2_1 */ + +#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 = ((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 = ((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_VERSION_3_1 + +static GLboolean _glewInit_GL_VERSION_3_1 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstanced")) == NULL) || r; + r = ((glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstanced")) == NULL) || r; + r = ((glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndex")) == NULL) || r; + r = ((glTexBuffer = (PFNGLTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glTexBuffer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_1 */ + +#ifdef GL_VERSION_3_2 + +static GLboolean _glewInit_GL_VERSION_3_2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture")) == NULL) || r; + r = ((glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteri64v")) == NULL) || r; + r = ((glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64i_v")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_2 */ + +#ifdef GL_VERSION_3_3 + +static GLboolean _glewInit_GL_VERSION_3_3 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisor")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_3 */ + +#ifdef GL_VERSION_4_0 + +static GLboolean _glewInit_GL_VERSION_4_0 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparatei")) == NULL) || r; + r = ((glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationi")) == NULL) || r; + r = ((glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparatei")) == NULL) || r; + r = ((glBlendFunci = (PFNGLBLENDFUNCIPROC)glewGetProcAddress((const GLubyte*)"glBlendFunci")) == NULL) || r; + r = ((glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShading")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_4_0 */ + +#ifdef GL_VERSION_4_1 + +#endif /* GL_VERSION_4_1 */ + +#ifdef GL_VERSION_4_2 + +#endif /* GL_VERSION_4_2 */ + +#ifdef GL_VERSION_4_3 + +#endif /* GL_VERSION_4_3 */ + +#ifdef GL_VERSION_4_4 + +#endif /* GL_VERSION_4_4 */ + +#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_AMD_blend_minmax_factor + +#endif /* GL_AMD_blend_minmax_factor */ + +#ifdef GL_AMD_conservative_depth + +#endif /* GL_AMD_conservative_depth */ + +#ifdef GL_AMD_debug_output + +static GLboolean _glewInit_GL_AMD_debug_output (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDebugMessageCallbackAMD = (PFNGLDEBUGMESSAGECALLBACKAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallbackAMD")) == NULL) || r; + r = ((glDebugMessageEnableAMD = (PFNGLDEBUGMESSAGEENABLEAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageEnableAMD")) == NULL) || r; + r = ((glDebugMessageInsertAMD = (PFNGLDEBUGMESSAGEINSERTAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsertAMD")) == NULL) || r; + r = ((glGetDebugMessageLogAMD = (PFNGLGETDEBUGMESSAGELOGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLogAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_debug_output */ + +#ifdef GL_AMD_depth_clamp_separate + +#endif /* GL_AMD_depth_clamp_separate */ + +#ifdef GL_AMD_draw_buffers_blend + +static GLboolean _glewInit_GL_AMD_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationIndexedAMD")) == NULL) || r; + r = ((glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateIndexedAMD")) == NULL) || r; + r = ((glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncIndexedAMD")) == NULL) || r; + r = ((glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateIndexedAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_draw_buffers_blend */ + +#ifdef GL_AMD_gcn_shader + +#endif /* GL_AMD_gcn_shader */ + +#ifdef GL_AMD_gpu_shader_int64 + +#endif /* GL_AMD_gpu_shader_int64 */ + +#ifdef GL_AMD_interleaved_elements + +static GLboolean _glewInit_GL_AMD_interleaved_elements (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexAttribParameteriAMD = (PFNGLVERTEXATTRIBPARAMETERIAMDPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribParameteriAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_interleaved_elements */ + +#ifdef GL_AMD_multi_draw_indirect + +static GLboolean _glewInit_GL_AMD_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectAMD = (PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectAMD")) == NULL) || r; + r = ((glMultiDrawElementsIndirectAMD = (PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_multi_draw_indirect */ + +#ifdef GL_AMD_name_gen_delete + +static GLboolean _glewInit_GL_AMD_name_gen_delete (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteNamesAMD = (PFNGLDELETENAMESAMDPROC)glewGetProcAddress((const GLubyte*)"glDeleteNamesAMD")) == NULL) || r; + r = ((glGenNamesAMD = (PFNGLGENNAMESAMDPROC)glewGetProcAddress((const GLubyte*)"glGenNamesAMD")) == NULL) || r; + r = ((glIsNameAMD = (PFNGLISNAMEAMDPROC)glewGetProcAddress((const GLubyte*)"glIsNameAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_name_gen_delete */ + +#ifdef GL_AMD_occlusion_query_event + +static GLboolean _glewInit_GL_AMD_occlusion_query_event (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glQueryObjectParameteruiAMD = (PFNGLQUERYOBJECTPARAMETERUIAMDPROC)glewGetProcAddress((const GLubyte*)"glQueryObjectParameteruiAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_occlusion_query_event */ + +#ifdef GL_AMD_performance_monitor + +static GLboolean _glewInit_GL_AMD_performance_monitor (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginPerfMonitorAMD = (PFNGLBEGINPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glBeginPerfMonitorAMD")) == NULL) || r; + r = ((glDeletePerfMonitorsAMD = (PFNGLDELETEPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glDeletePerfMonitorsAMD")) == NULL) || r; + r = ((glEndPerfMonitorAMD = (PFNGLENDPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glEndPerfMonitorAMD")) == NULL) || r; + r = ((glGenPerfMonitorsAMD = (PFNGLGENPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glGenPerfMonitorsAMD")) == NULL) || r; + r = ((glGetPerfMonitorCounterDataAMD = (PFNGLGETPERFMONITORCOUNTERDATAAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterDataAMD")) == NULL) || r; + r = ((glGetPerfMonitorCounterInfoAMD = (PFNGLGETPERFMONITORCOUNTERINFOAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterInfoAMD")) == NULL) || r; + r = ((glGetPerfMonitorCounterStringAMD = (PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterStringAMD")) == NULL) || r; + r = ((glGetPerfMonitorCountersAMD = (PFNGLGETPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCountersAMD")) == NULL) || r; + r = ((glGetPerfMonitorGroupStringAMD = (PFNGLGETPERFMONITORGROUPSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupStringAMD")) == NULL) || r; + r = ((glGetPerfMonitorGroupsAMD = (PFNGLGETPERFMONITORGROUPSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupsAMD")) == NULL) || r; + r = ((glSelectPerfMonitorCountersAMD = (PFNGLSELECTPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glSelectPerfMonitorCountersAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_performance_monitor */ + +#ifdef GL_AMD_pinned_memory + +#endif /* GL_AMD_pinned_memory */ + +#ifdef GL_AMD_query_buffer_object + +#endif /* GL_AMD_query_buffer_object */ + +#ifdef GL_AMD_sample_positions + +static GLboolean _glewInit_GL_AMD_sample_positions (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSetMultisamplefvAMD = (PFNGLSETMULTISAMPLEFVAMDPROC)glewGetProcAddress((const GLubyte*)"glSetMultisamplefvAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_sample_positions */ + +#ifdef GL_AMD_seamless_cubemap_per_texture + +#endif /* GL_AMD_seamless_cubemap_per_texture */ + +#ifdef GL_AMD_shader_atomic_counter_ops + +#endif /* GL_AMD_shader_atomic_counter_ops */ + +#ifdef GL_AMD_shader_stencil_export + +#endif /* GL_AMD_shader_stencil_export */ + +#ifdef GL_AMD_shader_stencil_value_export + +#endif /* GL_AMD_shader_stencil_value_export */ + +#ifdef GL_AMD_shader_trinary_minmax + +#endif /* GL_AMD_shader_trinary_minmax */ + +#ifdef GL_AMD_sparse_texture + +static GLboolean _glewInit_GL_AMD_sparse_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexStorageSparseAMD = (PFNGLTEXSTORAGESPARSEAMDPROC)glewGetProcAddress((const GLubyte*)"glTexStorageSparseAMD")) == NULL) || r; + r = ((glTextureStorageSparseAMD = (PFNGLTEXTURESTORAGESPARSEAMDPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageSparseAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_sparse_texture */ + +#ifdef GL_AMD_stencil_operation_extended + +static GLboolean _glewInit_GL_AMD_stencil_operation_extended (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glStencilOpValueAMD = (PFNGLSTENCILOPVALUEAMDPROC)glewGetProcAddress((const GLubyte*)"glStencilOpValueAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_stencil_operation_extended */ + +#ifdef GL_AMD_texture_texture4 + +#endif /* GL_AMD_texture_texture4 */ + +#ifdef GL_AMD_transform_feedback3_lines_triangles + +#endif /* GL_AMD_transform_feedback3_lines_triangles */ + +#ifdef GL_AMD_transform_feedback4 + +#endif /* GL_AMD_transform_feedback4 */ + +#ifdef GL_AMD_vertex_shader_layer + +#endif /* GL_AMD_vertex_shader_layer */ + +#ifdef GL_AMD_vertex_shader_tessellator + +static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTessellationFactorAMD = (PFNGLTESSELLATIONFACTORAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationFactorAMD")) == NULL) || r; + r = ((glTessellationModeAMD = (PFNGLTESSELLATIONMODEAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationModeAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_vertex_shader_tessellator */ + +#ifdef GL_AMD_vertex_shader_viewport_index + +#endif /* GL_AMD_vertex_shader_viewport_index */ + +#ifdef GL_ANGLE_depth_texture + +#endif /* GL_ANGLE_depth_texture */ + +#ifdef GL_ANGLE_framebuffer_blit + +static GLboolean _glewInit_GL_ANGLE_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlitFramebufferANGLE = (PFNGLBLITFRAMEBUFFERANGLEPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_framebuffer_blit */ + +#ifdef GL_ANGLE_framebuffer_multisample + +static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_framebuffer_multisample */ + +#ifdef GL_ANGLE_instanced_arrays + +static GLboolean _glewInit_GL_ANGLE_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedANGLE")) == NULL) || r; + r = ((glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedANGLE")) == NULL) || r; + r = ((glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_instanced_arrays */ + +#ifdef GL_ANGLE_pack_reverse_row_order + +#endif /* GL_ANGLE_pack_reverse_row_order */ + +#ifdef GL_ANGLE_program_binary + +#endif /* GL_ANGLE_program_binary */ + +#ifdef GL_ANGLE_texture_compression_dxt1 + +#endif /* GL_ANGLE_texture_compression_dxt1 */ + +#ifdef GL_ANGLE_texture_compression_dxt3 + +#endif /* GL_ANGLE_texture_compression_dxt3 */ + +#ifdef GL_ANGLE_texture_compression_dxt5 + +#endif /* GL_ANGLE_texture_compression_dxt5 */ + +#ifdef GL_ANGLE_texture_usage + +#endif /* GL_ANGLE_texture_usage */ + +#ifdef GL_ANGLE_timer_query + +static GLboolean _glewInit_GL_ANGLE_timer_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQueryANGLE = (PFNGLBEGINQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryANGLE")) == NULL) || r; + r = ((glDeleteQueriesANGLE = (PFNGLDELETEQUERIESANGLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesANGLE")) == NULL) || r; + r = ((glEndQueryANGLE = (PFNGLENDQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glEndQueryANGLE")) == NULL) || r; + r = ((glGenQueriesANGLE = (PFNGLGENQUERIESANGLEPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesANGLE")) == NULL) || r; + r = ((glGetQueryObjecti64vANGLE = (PFNGLGETQUERYOBJECTI64VANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vANGLE")) == NULL) || r; + r = ((glGetQueryObjectivANGLE = (PFNGLGETQUERYOBJECTIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivANGLE")) == NULL) || r; + r = ((glGetQueryObjectui64vANGLE = (PFNGLGETQUERYOBJECTUI64VANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vANGLE")) == NULL) || r; + r = ((glGetQueryObjectuivANGLE = (PFNGLGETQUERYOBJECTUIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivANGLE")) == NULL) || r; + r = ((glGetQueryivANGLE = (PFNGLGETQUERYIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivANGLE")) == NULL) || r; + r = ((glIsQueryANGLE = (PFNGLISQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glIsQueryANGLE")) == NULL) || r; + r = ((glQueryCounterANGLE = (PFNGLQUERYCOUNTERANGLEPROC)glewGetProcAddress((const GLubyte*)"glQueryCounterANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_timer_query */ + +#ifdef GL_ANGLE_translated_shader_source + +static GLboolean _glewInit_GL_ANGLE_translated_shader_source (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTranslatedShaderSourceANGLE = (PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetTranslatedShaderSourceANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_translated_shader_source */ + +#ifdef GL_APPLE_aux_depth_stencil + +#endif /* GL_APPLE_aux_depth_stencil */ + +#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_object_purgeable + +static GLboolean _glewInit_GL_APPLE_object_purgeable (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetObjectParameterivAPPLE = (PFNGLGETOBJECTPARAMETERIVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivAPPLE")) == NULL) || r; + r = ((glObjectPurgeableAPPLE = (PFNGLOBJECTPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectPurgeableAPPLE")) == NULL) || r; + r = ((glObjectUnpurgeableAPPLE = (PFNGLOBJECTUNPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectUnpurgeableAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_object_purgeable */ + +#ifdef GL_APPLE_pixel_buffer + +#endif /* GL_APPLE_pixel_buffer */ + +#ifdef GL_APPLE_rgb_422 + +#endif /* GL_APPLE_rgb_422 */ + +#ifdef GL_APPLE_row_bytes + +#endif /* GL_APPLE_row_bytes */ + +#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_vertex_program_evaluators + +static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDisableVertexAttribAPPLE = (PFNGLDISABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribAPPLE")) == NULL) || r; + r = ((glEnableVertexAttribAPPLE = (PFNGLENABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribAPPLE")) == NULL) || r; + r = ((glIsVertexAttribEnabledAPPLE = (PFNGLISVERTEXATTRIBENABLEDAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexAttribEnabledAPPLE")) == NULL) || r; + r = ((glMapVertexAttrib1dAPPLE = (PFNGLMAPVERTEXATTRIB1DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1dAPPLE")) == NULL) || r; + r = ((glMapVertexAttrib1fAPPLE = (PFNGLMAPVERTEXATTRIB1FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1fAPPLE")) == NULL) || r; + r = ((glMapVertexAttrib2dAPPLE = (PFNGLMAPVERTEXATTRIB2DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2dAPPLE")) == NULL) || r; + r = ((glMapVertexAttrib2fAPPLE = (PFNGLMAPVERTEXATTRIB2FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2fAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_program_evaluators */ + +#ifdef GL_APPLE_ycbcr_422 + +#endif /* GL_APPLE_ycbcr_422 */ + +#ifdef GL_ARB_ES2_compatibility + +static GLboolean _glewInit_GL_ARB_ES2_compatibility (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearDepthf = (PFNGLCLEARDEPTHFPROC)glewGetProcAddress((const GLubyte*)"glClearDepthf")) == NULL) || r; + r = ((glDepthRangef = (PFNGLDEPTHRANGEFPROC)glewGetProcAddress((const GLubyte*)"glDepthRangef")) == NULL) || r; + r = ((glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)glewGetProcAddress((const GLubyte*)"glGetShaderPrecisionFormat")) == NULL) || r; + r = ((glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)glewGetProcAddress((const GLubyte*)"glReleaseShaderCompiler")) == NULL) || r; + r = ((glShaderBinary = (PFNGLSHADERBINARYPROC)glewGetProcAddress((const GLubyte*)"glShaderBinary")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_ES2_compatibility */ + +#ifdef GL_ARB_ES3_compatibility + +#endif /* GL_ARB_ES3_compatibility */ + +#ifdef GL_ARB_arrays_of_arrays + +#endif /* GL_ARB_arrays_of_arrays */ + +#ifdef GL_ARB_base_instance + +static GLboolean _glewInit_GL_ARB_base_instance (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedBaseInstance")) == NULL) || r; + r = ((glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseInstance")) == NULL) || r; + r = ((glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertexBaseInstance")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_base_instance */ + +#ifdef GL_ARB_bindless_texture + +static GLboolean _glewInit_GL_ARB_bindless_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetImageHandleARB = (PFNGLGETIMAGEHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetImageHandleARB")) == NULL) || r; + r = ((glGetTextureHandleARB = (PFNGLGETTEXTUREHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetTextureHandleARB")) == NULL) || r; + r = ((glGetTextureSamplerHandleARB = (PFNGLGETTEXTURESAMPLERHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSamplerHandleARB")) == NULL) || r; + r = ((glGetVertexAttribLui64vARB = (PFNGLGETVERTEXATTRIBLUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLui64vARB")) == NULL) || r; + r = ((glIsImageHandleResidentARB = (PFNGLISIMAGEHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glIsImageHandleResidentARB")) == NULL) || r; + r = ((glIsTextureHandleResidentARB = (PFNGLISTEXTUREHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glIsTextureHandleResidentARB")) == NULL) || r; + r = ((glMakeImageHandleNonResidentARB = (PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleNonResidentARB")) == NULL) || r; + r = ((glMakeImageHandleResidentARB = (PFNGLMAKEIMAGEHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleResidentARB")) == NULL) || r; + r = ((glMakeTextureHandleNonResidentARB = (PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleNonResidentARB")) == NULL) || r; + r = ((glMakeTextureHandleResidentARB = (PFNGLMAKETEXTUREHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleResidentARB")) == NULL) || r; + r = ((glProgramUniformHandleui64ARB = (PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64ARB")) == NULL) || r; + r = ((glProgramUniformHandleui64vARB = (PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64vARB")) == NULL) || r; + r = ((glUniformHandleui64ARB = (PFNGLUNIFORMHANDLEUI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64ARB")) == NULL) || r; + r = ((glUniformHandleui64vARB = (PFNGLUNIFORMHANDLEUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64vARB")) == NULL) || r; + r = ((glVertexAttribL1ui64ARB = (PFNGLVERTEXATTRIBL1UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64ARB")) == NULL) || r; + r = ((glVertexAttribL1ui64vARB = (PFNGLVERTEXATTRIBL1UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64vARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_bindless_texture */ + +#ifdef GL_ARB_blend_func_extended + +static GLboolean _glewInit_GL_ARB_blend_func_extended (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationIndexed")) == NULL) || r; + r = ((glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataIndex")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_blend_func_extended */ + +#ifdef GL_ARB_buffer_storage + +static GLboolean _glewInit_GL_ARB_buffer_storage (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBufferStorage = (PFNGLBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glBufferStorage")) == NULL) || r; + r = ((glNamedBufferStorageEXT = (PFNGLNAMEDBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorageEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_buffer_storage */ + +#ifdef GL_ARB_cl_event + +static GLboolean _glewInit_GL_ARB_cl_event (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCreateSyncFromCLeventARB = (PFNGLCREATESYNCFROMCLEVENTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateSyncFromCLeventARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_cl_event */ + +#ifdef GL_ARB_clear_buffer_object + +static GLboolean _glewInit_GL_ARB_clear_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glClearBufferData")) == NULL) || r; + r = ((glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glClearBufferSubData")) == NULL) || r; + r = ((glClearNamedBufferDataEXT = (PFNGLCLEARNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferDataEXT")) == NULL) || r; + r = ((glClearNamedBufferSubDataEXT = (PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferSubDataEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_clear_buffer_object */ + +#ifdef GL_ARB_clear_texture + +static GLboolean _glewInit_GL_ARB_clear_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glClearTexImage")) == NULL) || r; + r = ((glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glClearTexSubImage")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_clear_texture */ + +#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_compatibility + +#endif /* GL_ARB_compatibility */ + +#ifdef GL_ARB_compressed_texture_pixel_storage + +#endif /* GL_ARB_compressed_texture_pixel_storage */ + +#ifdef GL_ARB_compute_shader + +static GLboolean _glewInit_GL_ARB_compute_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)glewGetProcAddress((const GLubyte*)"glDispatchCompute")) == NULL) || r; + r = ((glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDispatchComputeIndirect")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_compute_shader */ + +#ifdef GL_ARB_compute_variable_group_size + +static GLboolean _glewInit_GL_ARB_compute_variable_group_size (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDispatchComputeGroupSizeARB = (PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC)glewGetProcAddress((const GLubyte*)"glDispatchComputeGroupSizeARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_compute_variable_group_size */ + +#ifdef GL_ARB_conservative_depth + +#endif /* GL_ARB_conservative_depth */ + +#ifdef GL_ARB_copy_buffer + +static GLboolean _glewInit_GL_ARB_copy_buffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyBufferSubData")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_copy_buffer */ + +#ifdef GL_ARB_copy_image + +static GLboolean _glewInit_GL_ARB_copy_image (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubData")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_copy_image */ + +#ifdef GL_ARB_debug_output + +static GLboolean _glewInit_GL_ARB_debug_output (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallbackARB")) == NULL) || r; + r = ((glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageControlARB")) == NULL) || r; + r = ((glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsertARB")) == NULL) || r; + r = ((glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLogARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_debug_output */ + +#ifdef GL_ARB_depth_buffer_float + +#endif /* GL_ARB_depth_buffer_float */ + +#ifdef GL_ARB_depth_clamp + +#endif /* GL_ARB_depth_clamp */ + +#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_buffers_blend + +static GLboolean _glewInit_GL_ARB_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateiARB")) == NULL) || r; + r = ((glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationiARB")) == NULL) || r; + r = ((glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateiARB")) == NULL) || r; + r = ((glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFunciARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_buffers_blend */ + +#ifdef GL_ARB_draw_elements_base_vertex + +static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsBaseVertex")) == NULL) || r; + r = ((glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertex")) == NULL) || r; + r = ((glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsBaseVertex")) == NULL) || r; + r = ((glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsBaseVertex")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_elements_base_vertex */ + +#ifdef GL_ARB_draw_indirect + +static GLboolean _glewInit_GL_ARB_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysIndirect")) == NULL) || r; + r = ((glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsIndirect")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_indirect */ + +#ifdef GL_ARB_draw_instanced + +#endif /* GL_ARB_draw_instanced */ + +#ifdef GL_ARB_enhanced_layouts + +#endif /* GL_ARB_enhanced_layouts */ + +#ifdef GL_ARB_explicit_attrib_location + +#endif /* GL_ARB_explicit_attrib_location */ + +#ifdef GL_ARB_explicit_uniform_location + +#endif /* GL_ARB_explicit_uniform_location */ + +#ifdef GL_ARB_fragment_coord_conventions + +#endif /* GL_ARB_fragment_coord_conventions */ + +#ifdef GL_ARB_fragment_layer_viewport + +#endif /* GL_ARB_fragment_layer_viewport */ + +#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_no_attachments + +static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glFramebufferParameteri")) == NULL) || r; + r = ((glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameteriv")) == NULL) || r; + r = ((glGetNamedFramebufferParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferParameterivEXT")) == NULL) || r; + r = ((glNamedFramebufferParameteriEXT = (PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferParameteriEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_framebuffer_no_attachments */ + +#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 = ((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 = ((glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayer")) == 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_get_program_binary + +static GLboolean _glewInit_GL_ARB_get_program_binary (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)glewGetProcAddress((const GLubyte*)"glGetProgramBinary")) == NULL) || r; + r = ((glProgramBinary = (PFNGLPROGRAMBINARYPROC)glewGetProcAddress((const GLubyte*)"glProgramBinary")) == NULL) || r; + r = ((glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteri")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_get_program_binary */ + +#ifdef GL_ARB_gpu_shader5 + +#endif /* GL_ARB_gpu_shader5 */ + +#ifdef GL_ARB_gpu_shader_fp64 + +static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetUniformdv = (PFNGLGETUNIFORMDVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformdv")) == NULL) || r; + r = ((glUniform1d = (PFNGLUNIFORM1DPROC)glewGetProcAddress((const GLubyte*)"glUniform1d")) == NULL) || r; + r = ((glUniform1dv = (PFNGLUNIFORM1DVPROC)glewGetProcAddress((const GLubyte*)"glUniform1dv")) == NULL) || r; + r = ((glUniform2d = (PFNGLUNIFORM2DPROC)glewGetProcAddress((const GLubyte*)"glUniform2d")) == NULL) || r; + r = ((glUniform2dv = (PFNGLUNIFORM2DVPROC)glewGetProcAddress((const GLubyte*)"glUniform2dv")) == NULL) || r; + r = ((glUniform3d = (PFNGLUNIFORM3DPROC)glewGetProcAddress((const GLubyte*)"glUniform3d")) == NULL) || r; + r = ((glUniform3dv = (PFNGLUNIFORM3DVPROC)glewGetProcAddress((const GLubyte*)"glUniform3dv")) == NULL) || r; + r = ((glUniform4d = (PFNGLUNIFORM4DPROC)glewGetProcAddress((const GLubyte*)"glUniform4d")) == NULL) || r; + r = ((glUniform4dv = (PFNGLUNIFORM4DVPROC)glewGetProcAddress((const GLubyte*)"glUniform4dv")) == NULL) || r; + r = ((glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2dv")) == NULL) || r; + r = ((glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3dv")) == NULL) || r; + r = ((glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4dv")) == NULL) || r; + r = ((glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3dv")) == NULL) || r; + r = ((glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2dv")) == NULL) || r; + r = ((glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4dv")) == NULL) || r; + r = ((glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4dv")) == NULL) || r; + r = ((glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2dv")) == NULL) || r; + r = ((glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3dv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_gpu_shader_fp64 */ + +#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_indirect_parameters + +static GLboolean _glewInit_GL_ARB_indirect_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectCountARB = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectCountARB")) == NULL) || r; + r = ((glMultiDrawElementsIndirectCountARB = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectCountARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_indirect_parameters */ + +#ifdef GL_ARB_instanced_arrays + +static GLboolean _glewInit_GL_ARB_instanced_arrays (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; + r = ((glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_instanced_arrays */ + +#ifdef GL_ARB_internalformat_query + +static GLboolean _glewInit_GL_ARB_internalformat_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformativ")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_internalformat_query */ + +#ifdef GL_ARB_internalformat_query2 + +static GLboolean _glewInit_GL_ARB_internalformat_query2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformati64v")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_internalformat_query2 */ + +#ifdef GL_ARB_invalidate_subdata + +static GLboolean _glewInit_GL_ARB_invalidate_subdata (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateBufferData")) == NULL) || r; + r = ((glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateBufferSubData")) == NULL) || r; + r = ((glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glInvalidateFramebuffer")) == NULL) || r; + r = ((glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glInvalidateSubFramebuffer")) == NULL) || r; + r = ((glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glInvalidateTexImage")) == NULL) || r; + r = ((glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glInvalidateTexSubImage")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_invalidate_subdata */ + +#ifdef GL_ARB_map_buffer_alignment + +#endif /* GL_ARB_map_buffer_alignment */ + +#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_multi_bind + +static GLboolean _glewInit_GL_ARB_multi_bind (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBuffersBase")) == NULL) || r; + r = ((glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBuffersRange")) == NULL) || r; + r = ((glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)glewGetProcAddress((const GLubyte*)"glBindImageTextures")) == NULL) || r; + r = ((glBindSamplers = (PFNGLBINDSAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glBindSamplers")) == NULL) || r; + r = ((glBindTextures = (PFNGLBINDTEXTURESPROC)glewGetProcAddress((const GLubyte*)"glBindTextures")) == NULL) || r; + r = ((glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glBindVertexBuffers")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multi_bind */ + +#ifdef GL_ARB_multi_draw_indirect + +static GLboolean _glewInit_GL_ARB_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirect")) == NULL) || r; + r = ((glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirect")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multi_draw_indirect */ + +#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_occlusion_query2 + +#endif /* GL_ARB_occlusion_query2 */ + +#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_program_interface_query + +static GLboolean _glewInit_GL_ARB_program_interface_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInterfaceiv")) == NULL) || r; + r = ((glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceIndex")) == NULL) || r; + r = ((glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocation")) == NULL) || r; + r = ((glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocationIndex")) == NULL) || r; + r = ((glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceName")) == NULL) || r; + r = ((glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceiv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_program_interface_query */ + +#ifdef GL_ARB_provoking_vertex + +static GLboolean _glewInit_GL_ARB_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertex")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_provoking_vertex */ + +#ifdef GL_ARB_query_buffer_object + +#endif /* GL_ARB_query_buffer_object */ + +#ifdef GL_ARB_robust_buffer_access_behavior + +#endif /* GL_ARB_robust_buffer_access_behavior */ + +#ifdef GL_ARB_robustness + +static GLboolean _glewInit_GL_ARB_robustness (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC)glewGetProcAddress((const GLubyte*)"glGetGraphicsResetStatusARB")) == NULL) || r; + r = ((glGetnColorTableARB = (PFNGLGETNCOLORTABLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnColorTableARB")) == NULL) || r; + r = ((glGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnCompressedTexImageARB")) == NULL) || r; + r = ((glGetnConvolutionFilterARB = (PFNGLGETNCONVOLUTIONFILTERARBPROC)glewGetProcAddress((const GLubyte*)"glGetnConvolutionFilterARB")) == NULL) || r; + r = ((glGetnHistogramARB = (PFNGLGETNHISTOGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glGetnHistogramARB")) == NULL) || r; + r = ((glGetnMapdvARB = (PFNGLGETNMAPDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapdvARB")) == NULL) || r; + r = ((glGetnMapfvARB = (PFNGLGETNMAPFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapfvARB")) == NULL) || r; + r = ((glGetnMapivARB = (PFNGLGETNMAPIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapivARB")) == NULL) || r; + r = ((glGetnMinmaxARB = (PFNGLGETNMINMAXARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMinmaxARB")) == NULL) || r; + r = ((glGetnPixelMapfvARB = (PFNGLGETNPIXELMAPFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapfvARB")) == NULL) || r; + r = ((glGetnPixelMapuivARB = (PFNGLGETNPIXELMAPUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapuivARB")) == NULL) || r; + r = ((glGetnPixelMapusvARB = (PFNGLGETNPIXELMAPUSVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapusvARB")) == NULL) || r; + r = ((glGetnPolygonStippleARB = (PFNGLGETNPOLYGONSTIPPLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPolygonStippleARB")) == NULL) || r; + r = ((glGetnSeparableFilterARB = (PFNGLGETNSEPARABLEFILTERARBPROC)glewGetProcAddress((const GLubyte*)"glGetnSeparableFilterARB")) == NULL) || r; + r = ((glGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnTexImageARB")) == NULL) || r; + r = ((glGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformdvARB")) == NULL) || r; + r = ((glGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformfvARB")) == NULL) || r; + r = ((glGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformivARB")) == NULL) || r; + r = ((glGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformuivARB")) == NULL) || r; + r = ((glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC)glewGetProcAddress((const GLubyte*)"glReadnPixelsARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_robustness */ + +#ifdef GL_ARB_robustness_application_isolation + +#endif /* GL_ARB_robustness_application_isolation */ + +#ifdef GL_ARB_robustness_share_group_isolation + +#endif /* GL_ARB_robustness_share_group_isolation */ + +#ifdef GL_ARB_sample_shading + +static GLboolean _glewInit_GL_ARB_sample_shading (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShadingARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sample_shading */ + +#ifdef GL_ARB_sampler_objects + +static GLboolean _glewInit_GL_ARB_sampler_objects (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindSampler = (PFNGLBINDSAMPLERPROC)glewGetProcAddress((const GLubyte*)"glBindSampler")) == NULL) || r; + r = ((glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteSamplers")) == NULL) || r; + r = ((glGenSamplers = (PFNGLGENSAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glGenSamplers")) == NULL) || r; + r = ((glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterIiv")) == NULL) || r; + r = ((glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterIuiv")) == NULL) || r; + r = ((glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterfv")) == NULL) || r; + r = ((glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameteriv")) == NULL) || r; + r = ((glIsSampler = (PFNGLISSAMPLERPROC)glewGetProcAddress((const GLubyte*)"glIsSampler")) == NULL) || r; + r = ((glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterIiv")) == NULL) || r; + r = ((glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterIuiv")) == NULL) || r; + r = ((glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterf")) == NULL) || r; + r = ((glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterfv")) == NULL) || r; + r = ((glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameteri")) == NULL) || r; + r = ((glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameteriv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sampler_objects */ + +#ifdef GL_ARB_seamless_cube_map + +#endif /* GL_ARB_seamless_cube_map */ + +#ifdef GL_ARB_seamless_cubemap_per_texture + +#endif /* GL_ARB_seamless_cubemap_per_texture */ + +#ifdef GL_ARB_separate_shader_objects + +static GLboolean _glewInit_GL_ARB_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glActiveShaderProgram")) == NULL) || r; + r = ((glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glBindProgramPipeline")) == NULL) || r; + r = ((glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramv")) == NULL) || r; + r = ((glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramPipelines")) == NULL) || r; + r = ((glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glGenProgramPipelines")) == NULL) || r; + r = ((glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramPipelineInfoLog")) == NULL) || r; + r = ((glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramPipelineiv")) == NULL) || r; + r = ((glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glIsProgramPipeline")) == NULL) || r; + r = ((glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1d")) == NULL) || r; + r = ((glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1dv")) == NULL) || r; + r = ((glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1f")) == NULL) || r; + r = ((glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fv")) == NULL) || r; + r = ((glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i")) == NULL) || r; + r = ((glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iv")) == NULL) || r; + r = ((glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui")) == NULL) || r; + r = ((glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiv")) == NULL) || r; + r = ((glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2d")) == NULL) || r; + r = ((glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2dv")) == NULL) || r; + r = ((glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2f")) == NULL) || r; + r = ((glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fv")) == NULL) || r; + r = ((glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i")) == NULL) || r; + r = ((glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iv")) == NULL) || r; + r = ((glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui")) == NULL) || r; + r = ((glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiv")) == NULL) || r; + r = ((glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3d")) == NULL) || r; + r = ((glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3dv")) == NULL) || r; + r = ((glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3f")) == NULL) || r; + r = ((glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fv")) == NULL) || r; + r = ((glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i")) == NULL) || r; + r = ((glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iv")) == NULL) || r; + r = ((glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui")) == NULL) || r; + r = ((glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiv")) == NULL) || r; + r = ((glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4d")) == NULL) || r; + r = ((glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4dv")) == NULL) || r; + r = ((glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4f")) == NULL) || r; + r = ((glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fv")) == NULL) || r; + r = ((glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i")) == NULL) || r; + r = ((glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iv")) == NULL) || r; + r = ((glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui")) == NULL) || r; + r = ((glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiv")) == NULL) || r; + r = ((glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2dv")) == NULL) || r; + r = ((glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fv")) == NULL) || r; + r = ((glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3dv")) == NULL) || r; + r = ((glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fv")) == NULL) || r; + r = ((glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4dv")) == NULL) || r; + r = ((glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fv")) == NULL) || r; + r = ((glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3dv")) == NULL) || r; + r = ((glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fv")) == NULL) || r; + r = ((glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2dv")) == NULL) || r; + r = ((glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fv")) == NULL) || r; + r = ((glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4dv")) == NULL) || r; + r = ((glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fv")) == NULL) || r; + r = ((glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4dv")) == NULL) || r; + r = ((glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fv")) == NULL) || r; + r = ((glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2dv")) == NULL) || r; + r = ((glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fv")) == NULL) || r; + r = ((glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3dv")) == NULL) || r; + r = ((glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fv")) == NULL) || r; + r = ((glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)glewGetProcAddress((const GLubyte*)"glUseProgramStages")) == NULL) || r; + r = ((glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramPipeline")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_separate_shader_objects */ + +#ifdef GL_ARB_shader_atomic_counters + +static GLboolean _glewInit_GL_ARB_shader_atomic_counters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAtomicCounterBufferiv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_atomic_counters */ + +#ifdef GL_ARB_shader_bit_encoding + +#endif /* GL_ARB_shader_bit_encoding */ + +#ifdef GL_ARB_shader_draw_parameters + +#endif /* GL_ARB_shader_draw_parameters */ + +#ifdef GL_ARB_shader_group_vote + +#endif /* GL_ARB_shader_group_vote */ + +#ifdef GL_ARB_shader_image_load_store + +static GLboolean _glewInit_GL_ARB_shader_image_load_store (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glBindImageTexture")) == NULL) || r; + r = ((glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrier")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_image_load_store */ + +#ifdef GL_ARB_shader_image_size + +#endif /* GL_ARB_shader_image_size */ + +#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_shader_precision + +#endif /* GL_ARB_shader_precision */ + +#ifdef GL_ARB_shader_stencil_export + +#endif /* GL_ARB_shader_stencil_export */ + +#ifdef GL_ARB_shader_storage_buffer_object + +static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glShaderStorageBlockBinding")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_storage_buffer_object */ + +#ifdef GL_ARB_shader_subroutine + +static GLboolean _glewInit_GL_ARB_shader_subroutine (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineName")) == NULL) || r; + r = ((glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineUniformName")) == NULL) || r; + r = ((glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineUniformiv")) == NULL) || r; + r = ((glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStageiv")) == NULL) || r; + r = ((glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetSubroutineIndex")) == NULL) || r; + r = ((glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetSubroutineUniformLocation")) == NULL) || r; + r = ((glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformSubroutineuiv")) == NULL) || r; + r = ((glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)glewGetProcAddress((const GLubyte*)"glUniformSubroutinesuiv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_subroutine */ + +#ifdef GL_ARB_shader_texture_lod + +#endif /* GL_ARB_shader_texture_lod */ + +#ifdef GL_ARB_shading_language_100 + +#endif /* GL_ARB_shading_language_100 */ + +#ifdef GL_ARB_shading_language_420pack + +#endif /* GL_ARB_shading_language_420pack */ + +#ifdef GL_ARB_shading_language_include + +static GLboolean _glewInit_GL_ARB_shading_language_include (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCompileShaderIncludeARB = (PFNGLCOMPILESHADERINCLUDEARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderIncludeARB")) == NULL) || r; + r = ((glDeleteNamedStringARB = (PFNGLDELETENAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteNamedStringARB")) == NULL) || r; + r = ((glGetNamedStringARB = (PFNGLGETNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetNamedStringARB")) == NULL) || r; + r = ((glGetNamedStringivARB = (PFNGLGETNAMEDSTRINGIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetNamedStringivARB")) == NULL) || r; + r = ((glIsNamedStringARB = (PFNGLISNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glIsNamedStringARB")) == NULL) || r; + r = ((glNamedStringARB = (PFNGLNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glNamedStringARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shading_language_include */ + +#ifdef GL_ARB_shading_language_packing + +#endif /* GL_ARB_shading_language_packing */ + +#ifdef GL_ARB_shadow + +#endif /* GL_ARB_shadow */ + +#ifdef GL_ARB_shadow_ambient + +#endif /* GL_ARB_shadow_ambient */ + +#ifdef GL_ARB_sparse_texture + +static GLboolean _glewInit_GL_ARB_sparse_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexPageCommitmentARB = (PFNGLTEXPAGECOMMITMENTARBPROC)glewGetProcAddress((const GLubyte*)"glTexPageCommitmentARB")) == NULL) || r; + r = ((glTexturePageCommitmentEXT = (PFNGLTEXTUREPAGECOMMITMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glTexturePageCommitmentEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sparse_texture */ + +#ifdef GL_ARB_stencil_texturing + +#endif /* GL_ARB_stencil_texturing */ + +#ifdef GL_ARB_sync + +static GLboolean _glewInit_GL_ARB_sync (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glClientWaitSync")) == NULL) || r; + r = ((glDeleteSync = (PFNGLDELETESYNCPROC)glewGetProcAddress((const GLubyte*)"glDeleteSync")) == NULL) || r; + r = ((glFenceSync = (PFNGLFENCESYNCPROC)glewGetProcAddress((const GLubyte*)"glFenceSync")) == NULL) || r; + r = ((glGetInteger64v = (PFNGLGETINTEGER64VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64v")) == NULL) || r; + r = ((glGetSynciv = (PFNGLGETSYNCIVPROC)glewGetProcAddress((const GLubyte*)"glGetSynciv")) == NULL) || r; + r = ((glIsSync = (PFNGLISSYNCPROC)glewGetProcAddress((const GLubyte*)"glIsSync")) == NULL) || r; + r = ((glWaitSync = (PFNGLWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glWaitSync")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sync */ + +#ifdef GL_ARB_tessellation_shader + +static GLboolean _glewInit_GL_ARB_tessellation_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPatchParameterfv")) == NULL) || r; + r = ((glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPatchParameteri")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_tessellation_shader */ + +#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_buffer_object_rgb32 + +#endif /* GL_ARB_texture_buffer_object_rgb32 */ + +#ifdef GL_ARB_texture_buffer_range + +static GLboolean _glewInit_GL_ARB_texture_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glTexBufferRange")) == NULL) || r; + r = ((glTextureBufferRangeEXT = (PFNGLTEXTUREBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferRangeEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_buffer_range */ + +#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_bptc + +#endif /* GL_ARB_texture_compression_bptc */ + +#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_cube_map_array + +#endif /* GL_ARB_texture_cube_map_array */ + +#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_gather + +#endif /* GL_ARB_texture_gather */ + +#ifdef GL_ARB_texture_mirror_clamp_to_edge + +#endif /* GL_ARB_texture_mirror_clamp_to_edge */ + +#ifdef GL_ARB_texture_mirrored_repeat + +#endif /* GL_ARB_texture_mirrored_repeat */ + +#ifdef GL_ARB_texture_multisample + +static GLboolean _glewInit_GL_ARB_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefv")) == NULL) || r; + r = ((glSampleMaski = (PFNGLSAMPLEMASKIPROC)glewGetProcAddress((const GLubyte*)"glSampleMaski")) == NULL) || r; + r = ((glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisample")) == NULL) || r; + r = ((glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisample")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_multisample */ + +#ifdef GL_ARB_texture_non_power_of_two + +#endif /* GL_ARB_texture_non_power_of_two */ + +#ifdef GL_ARB_texture_query_levels + +#endif /* GL_ARB_texture_query_levels */ + +#ifdef GL_ARB_texture_query_lod + +#endif /* GL_ARB_texture_query_lod */ + +#ifdef GL_ARB_texture_rectangle + +#endif /* GL_ARB_texture_rectangle */ + +#ifdef GL_ARB_texture_rg + +#endif /* GL_ARB_texture_rg */ + +#ifdef GL_ARB_texture_rgb10_a2ui + +#endif /* GL_ARB_texture_rgb10_a2ui */ + +#ifdef GL_ARB_texture_stencil8 + +#endif /* GL_ARB_texture_stencil8 */ + +#ifdef GL_ARB_texture_storage + +static GLboolean _glewInit_GL_ARB_texture_storage (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage1D")) == NULL) || r; + r = ((glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2D")) == NULL) || r; + r = ((glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3D")) == NULL) || r; + r = ((glTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage1DEXT")) == NULL) || r; + r = ((glTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DEXT")) == NULL) || r; + r = ((glTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_storage */ + +#ifdef GL_ARB_texture_storage_multisample + +static GLboolean _glewInit_GL_ARB_texture_storage_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2DMultisample")) == NULL) || r; + r = ((glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3DMultisample")) == NULL) || r; + r = ((glTextureStorage2DMultisampleEXT = (PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DMultisampleEXT")) == NULL) || r; + r = ((glTextureStorage3DMultisampleEXT = (PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DMultisampleEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_storage_multisample */ + +#ifdef GL_ARB_texture_swizzle + +#endif /* GL_ARB_texture_swizzle */ + +#ifdef GL_ARB_texture_view + +static GLboolean _glewInit_GL_ARB_texture_view (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTextureView = (PFNGLTEXTUREVIEWPROC)glewGetProcAddress((const GLubyte*)"glTextureView")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_view */ + +#ifdef GL_ARB_timer_query + +static GLboolean _glewInit_GL_ARB_timer_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64v")) == NULL) || r; + r = ((glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64v")) == NULL) || r; + r = ((glQueryCounter = (PFNGLQUERYCOUNTERPROC)glewGetProcAddress((const GLubyte*)"glQueryCounter")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_timer_query */ + +#ifdef GL_ARB_transform_feedback2 + +static GLboolean _glewInit_GL_ARB_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedback")) == NULL) || r; + r = ((glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacks")) == NULL) || r; + r = ((glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedback")) == NULL) || r; + r = ((glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacks")) == NULL) || r; + r = ((glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedback")) == NULL) || r; + r = ((glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedback")) == NULL) || r; + r = ((glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedback")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transform_feedback2 */ + +#ifdef GL_ARB_transform_feedback3 + +static GLboolean _glewInit_GL_ARB_transform_feedback3 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryIndexed")) == NULL) || r; + r = ((glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackStream")) == NULL) || r; + r = ((glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glEndQueryIndexed")) == NULL) || r; + r = ((glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryIndexediv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transform_feedback3 */ + +#ifdef GL_ARB_transform_feedback_instanced + +static GLboolean _glewInit_GL_ARB_transform_feedback_instanced (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackInstanced")) == NULL) || r; + r = ((glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackStreamInstanced")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transform_feedback_instanced */ + +#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_uniform_buffer_object + +static GLboolean _glewInit_GL_ARB_uniform_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r; + r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r; + r = ((glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockName")) == NULL) || r; + r = ((glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockiv")) == NULL) || r; + r = ((glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformName")) == NULL) || r; + r = ((glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformsiv")) == NULL) || r; + r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r; + r = ((glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBlockIndex")) == NULL) || r; + r = ((glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)glewGetProcAddress((const GLubyte*)"glGetUniformIndices")) == NULL) || r; + r = ((glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glUniformBlockBinding")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_uniform_buffer_object */ + +#ifdef GL_ARB_vertex_array_bgra + +#endif /* GL_ARB_vertex_array_bgra */ + +#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_attrib_64bit + +static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLdv")) == NULL) || r; + r = ((glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1d")) == NULL) || r; + r = ((glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dv")) == NULL) || r; + r = ((glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2d")) == NULL) || r; + r = ((glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dv")) == NULL) || r; + r = ((glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3d")) == NULL) || r; + r = ((glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dv")) == NULL) || r; + r = ((glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4d")) == NULL) || r; + r = ((glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dv")) == NULL) || r; + r = ((glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_attrib_64bit */ + +#ifdef GL_ARB_vertex_attrib_binding + +static GLboolean _glewInit_GL_ARB_vertex_attrib_binding (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindVertexBuffer")) == NULL) || r; + r = ((glVertexArrayBindVertexBufferEXT = (PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayBindVertexBufferEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribBindingEXT = (PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribBindingEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribFormatEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribIFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribIFormatEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribLFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribLFormatEXT")) == NULL) || r; + r = ((glVertexArrayVertexBindingDivisorEXT = (PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexBindingDivisorEXT")) == NULL) || r; + r = ((glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribBinding")) == NULL) || r; + r = ((glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormat")) == NULL) || r; + r = ((glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormat")) == NULL) || r; + r = ((glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLFormat")) == NULL) || r; + r = ((glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexBindingDivisor")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_attrib_binding */ + +#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_vertex_type_10f_11f_11f_rev + +#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ + +#ifdef GL_ARB_vertex_type_2_10_10_10_rev + +static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorP3ui = (PFNGLCOLORP3UIPROC)glewGetProcAddress((const GLubyte*)"glColorP3ui")) == NULL) || r; + r = ((glColorP3uiv = (PFNGLCOLORP3UIVPROC)glewGetProcAddress((const GLubyte*)"glColorP3uiv")) == NULL) || r; + r = ((glColorP4ui = (PFNGLCOLORP4UIPROC)glewGetProcAddress((const GLubyte*)"glColorP4ui")) == NULL) || r; + r = ((glColorP4uiv = (PFNGLCOLORP4UIVPROC)glewGetProcAddress((const GLubyte*)"glColorP4uiv")) == NULL) || r; + r = ((glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP1ui")) == NULL) || r; + r = ((glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP1uiv")) == NULL) || r; + r = ((glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP2ui")) == NULL) || r; + r = ((glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP2uiv")) == NULL) || r; + r = ((glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP3ui")) == NULL) || r; + r = ((glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP3uiv")) == NULL) || r; + r = ((glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP4ui")) == NULL) || r; + r = ((glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP4uiv")) == NULL) || r; + r = ((glNormalP3ui = (PFNGLNORMALP3UIPROC)glewGetProcAddress((const GLubyte*)"glNormalP3ui")) == NULL) || r; + r = ((glNormalP3uiv = (PFNGLNORMALP3UIVPROC)glewGetProcAddress((const GLubyte*)"glNormalP3uiv")) == NULL) || r; + r = ((glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorP3ui")) == NULL) || r; + r = ((glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorP3uiv")) == NULL) || r; + r = ((glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP1ui")) == NULL) || r; + r = ((glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP1uiv")) == NULL) || r; + r = ((glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP2ui")) == NULL) || r; + r = ((glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP2uiv")) == NULL) || r; + r = ((glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP3ui")) == NULL) || r; + r = ((glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP3uiv")) == NULL) || r; + r = ((glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP4ui")) == NULL) || r; + r = ((glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP4uiv")) == NULL) || r; + r = ((glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP1ui")) == NULL) || r; + r = ((glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP1uiv")) == NULL) || r; + r = ((glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP2ui")) == NULL) || r; + r = ((glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP2uiv")) == NULL) || r; + r = ((glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP3ui")) == NULL) || r; + r = ((glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP3uiv")) == NULL) || r; + r = ((glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP4ui")) == NULL) || r; + r = ((glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP4uiv")) == NULL) || r; + r = ((glVertexP2ui = (PFNGLVERTEXP2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP2ui")) == NULL) || r; + r = ((glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP2uiv")) == NULL) || r; + r = ((glVertexP3ui = (PFNGLVERTEXP3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP3ui")) == NULL) || r; + r = ((glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP3uiv")) == NULL) || r; + r = ((glVertexP4ui = (PFNGLVERTEXP4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP4ui")) == NULL) || r; + r = ((glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP4uiv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +#ifdef GL_ARB_viewport_array + +static GLboolean _glewInit_GL_ARB_viewport_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeArrayv")) == NULL) || r; + r = ((glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeIndexed")) == NULL) || r; + r = ((glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_v")) == NULL) || r; + r = ((glGetFloati_v = (PFNGLGETFLOATI_VPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_v")) == NULL) || r; + r = ((glScissorArrayv = (PFNGLSCISSORARRAYVPROC)glewGetProcAddress((const GLubyte*)"glScissorArrayv")) == NULL) || r; + r = ((glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexed")) == NULL) || r; + r = ((glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexedv")) == NULL) || r; + r = ((glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)glewGetProcAddress((const GLubyte*)"glViewportArrayv")) == NULL) || r; + r = ((glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedf")) == NULL) || r; + r = ((glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedfv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_viewport_array */ + +#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_meminfo + +#endif /* GL_ATI_meminfo */ + +#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 = ((glVertexStream1dATI = (PFNGLVERTEXSTREAM1DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1dATI")) == NULL) || r; + r = ((glVertexStream1dvATI = (PFNGLVERTEXSTREAM1DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1dvATI")) == NULL) || r; + r = ((glVertexStream1fATI = (PFNGLVERTEXSTREAM1FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1fATI")) == NULL) || r; + r = ((glVertexStream1fvATI = (PFNGLVERTEXSTREAM1FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1fvATI")) == NULL) || r; + r = ((glVertexStream1iATI = (PFNGLVERTEXSTREAM1IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1iATI")) == NULL) || r; + r = ((glVertexStream1ivATI = (PFNGLVERTEXSTREAM1IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1ivATI")) == NULL) || r; + r = ((glVertexStream1sATI = (PFNGLVERTEXSTREAM1SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1sATI")) == NULL) || r; + r = ((glVertexStream1svATI = (PFNGLVERTEXSTREAM1SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1svATI")) == 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_debug_label + +static GLboolean _glewInit_GL_EXT_debug_label (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC)glewGetProcAddress((const GLubyte*)"glGetObjectLabelEXT")) == NULL) || r; + r = ((glLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC)glewGetProcAddress((const GLubyte*)"glLabelObjectEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_debug_label */ + +#ifdef GL_EXT_debug_marker + +static GLboolean _glewInit_GL_EXT_debug_marker (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glInsertEventMarkerEXT")) == NULL) || r; + r = ((glPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glPopGroupMarkerEXT")) == NULL) || r; + r = ((glPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glPushGroupMarkerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_debug_marker */ + +#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 = ((glDisableClientStateiEXT = (PFNGLDISABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateiEXT")) == NULL) || r; + r = ((glDisableVertexArrayAttribEXT = (PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayAttribEXT")) == NULL) || r; + r = ((glDisableVertexArrayEXT = (PFNGLDISABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayEXT")) == NULL) || r; + r = ((glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateIndexedEXT")) == NULL) || r; + r = ((glEnableClientStateiEXT = (PFNGLENABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateiEXT")) == NULL) || r; + r = ((glEnableVertexArrayAttribEXT = (PFNGLENABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayAttribEXT")) == NULL) || r; + r = ((glEnableVertexArrayEXT = (PFNGLENABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayEXT")) == NULL) || r; + r = ((glFlushMappedNamedBufferRangeEXT = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedNamedBufferRangeEXT")) == 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 = ((glGetDoublei_vEXT = (PFNGLGETDOUBLEI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_vEXT")) == NULL) || r; + r = ((glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloatIndexedvEXT")) == NULL) || r; + r = ((glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_vEXT")) == 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 = ((glGetPointeri_vEXT = (PFNGLGETPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointeri_vEXT")) == 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 = ((glGetVertexArrayIntegeri_vEXT = (PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegeri_vEXT")) == NULL) || r; + r = ((glGetVertexArrayIntegervEXT = (PFNGLGETVERTEXARRAYINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegervEXT")) == NULL) || r; + r = ((glGetVertexArrayPointeri_vEXT = (PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointeri_vEXT")) == NULL) || r; + r = ((glGetVertexArrayPointervEXT = (PFNGLGETVERTEXARRAYPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointervEXT")) == NULL) || r; + r = ((glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferEXT")) == NULL) || r; + r = ((glMapNamedBufferRangeEXT = (PFNGLMAPNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferRangeEXT")) == 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 = ((glNamedCopyBufferSubDataEXT = (PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedCopyBufferSubDataEXT")) == 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; + r = ((glVertexArrayColorOffsetEXT = (PFNGLVERTEXARRAYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayColorOffsetEXT")) == NULL) || r; + r = ((glVertexArrayEdgeFlagOffsetEXT = (PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayEdgeFlagOffsetEXT")) == NULL) || r; + r = ((glVertexArrayFogCoordOffsetEXT = (PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayFogCoordOffsetEXT")) == NULL) || r; + r = ((glVertexArrayIndexOffsetEXT = (PFNGLVERTEXARRAYINDEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayIndexOffsetEXT")) == NULL) || r; + r = ((glVertexArrayMultiTexCoordOffsetEXT = (PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayMultiTexCoordOffsetEXT")) == NULL) || r; + r = ((glVertexArrayNormalOffsetEXT = (PFNGLVERTEXARRAYNORMALOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayNormalOffsetEXT")) == NULL) || r; + r = ((glVertexArraySecondaryColorOffsetEXT = (PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArraySecondaryColorOffsetEXT")) == NULL) || r; + r = ((glVertexArrayTexCoordOffsetEXT = (PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayTexCoordOffsetEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribDivisorEXT = (PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribDivisorEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribIOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribIOffsetEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribOffsetEXT")) == NULL) || r; + r = ((glVertexArrayVertexOffsetEXT = (PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexOffsetEXT")) == 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_multisample_blit_scaled + +#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ + +#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 = ((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_provoking_vertex + +static GLboolean _glewInit_GL_EXT_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProvokingVertexEXT = (PFNGLPROVOKINGVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertexEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_provoking_vertex */ + +#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_shader_objects + +static GLboolean _glewInit_GL_EXT_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveProgramEXT = (PFNGLACTIVEPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveProgramEXT")) == NULL) || r; + r = ((glCreateShaderProgramEXT = (PFNGLCREATESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramEXT")) == NULL) || r; + r = ((glUseShaderProgramEXT = (PFNGLUSESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glUseShaderProgramEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_separate_shader_objects */ + +#ifdef GL_EXT_separate_specular_color + +#endif /* GL_EXT_separate_specular_color */ + +#ifdef GL_EXT_shader_image_load_formatted + +#endif /* GL_EXT_shader_image_load_formatted */ + +#ifdef GL_EXT_shader_image_load_store + +static GLboolean _glewInit_GL_EXT_shader_image_load_store (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindImageTextureEXT = (PFNGLBINDIMAGETEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindImageTextureEXT")) == NULL) || r; + r = ((glMemoryBarrierEXT = (PFNGLMEMORYBARRIEREXTPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrierEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_shader_image_load_store */ + +#ifdef GL_EXT_shader_integer_mix + +#endif /* GL_EXT_shader_integer_mix */ + +#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 + +static GLboolean _glewInit_GL_EXT_texture_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerEXT")) == NULL) || r; + + return r; +} + +#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_sRGB_decode + +#endif /* GL_EXT_texture_sRGB_decode */ + +#ifdef GL_EXT_texture_shared_exponent + +#endif /* GL_EXT_texture_shared_exponent */ + +#ifdef GL_EXT_texture_snorm + +#endif /* GL_EXT_texture_snorm */ + +#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 = ((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_attrib_64bit + +static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribLdvEXT = (PFNGLGETVERTEXATTRIBLDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLdvEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribLOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribLOffsetEXT")) == NULL) || r; + r = ((glVertexAttribL1dEXT = (PFNGLVERTEXATTRIBL1DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dEXT")) == NULL) || r; + r = ((glVertexAttribL1dvEXT = (PFNGLVERTEXATTRIBL1DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dvEXT")) == NULL) || r; + r = ((glVertexAttribL2dEXT = (PFNGLVERTEXATTRIBL2DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dEXT")) == NULL) || r; + r = ((glVertexAttribL2dvEXT = (PFNGLVERTEXATTRIBL2DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dvEXT")) == NULL) || r; + r = ((glVertexAttribL3dEXT = (PFNGLVERTEXATTRIBL3DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dEXT")) == NULL) || r; + r = ((glVertexAttribL3dvEXT = (PFNGLVERTEXATTRIBL3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dvEXT")) == NULL) || r; + r = ((glVertexAttribL4dEXT = (PFNGLVERTEXATTRIBL4DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dEXT")) == NULL) || r; + r = ((glVertexAttribL4dvEXT = (PFNGLVERTEXATTRIBL4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dvEXT")) == NULL) || r; + r = ((glVertexAttribLPointerEXT = (PFNGLVERTEXATTRIBLPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_attrib_64bit */ + +#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_EXT_x11_sync_object + +static GLboolean _glewInit_GL_EXT_x11_sync_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glImportSyncEXT = (PFNGLIMPORTSYNCEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSyncEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_x11_sync_object */ + +#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_fragment_shader_ordering + +#endif /* GL_INTEL_fragment_shader_ordering */ + +#ifdef GL_INTEL_map_texture + +static GLboolean _glewInit_GL_INTEL_map_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMapTexture2DINTEL = (PFNGLMAPTEXTURE2DINTELPROC)glewGetProcAddress((const GLubyte*)"glMapTexture2DINTEL")) == NULL) || r; + r = ((glSyncTextureINTEL = (PFNGLSYNCTEXTUREINTELPROC)glewGetProcAddress((const GLubyte*)"glSyncTextureINTEL")) == NULL) || r; + r = ((glUnmapTexture2DINTEL = (PFNGLUNMAPTEXTURE2DINTELPROC)glewGetProcAddress((const GLubyte*)"glUnmapTexture2DINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_map_texture */ + +#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_performance_query + +static GLboolean _glewInit_GL_INTEL_performance_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginPerfQueryINTEL = (PFNGLBEGINPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glBeginPerfQueryINTEL")) == NULL) || r; + r = ((glCreatePerfQueryINTEL = (PFNGLCREATEPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glCreatePerfQueryINTEL")) == NULL) || r; + r = ((glDeletePerfQueryINTEL = (PFNGLDELETEPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glDeletePerfQueryINTEL")) == NULL) || r; + r = ((glEndPerfQueryINTEL = (PFNGLENDPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glEndPerfQueryINTEL")) == NULL) || r; + r = ((glGetFirstPerfQueryIdINTEL = (PFNGLGETFIRSTPERFQUERYIDINTELPROC)glewGetProcAddress((const GLubyte*)"glGetFirstPerfQueryIdINTEL")) == NULL) || r; + r = ((glGetNextPerfQueryIdINTEL = (PFNGLGETNEXTPERFQUERYIDINTELPROC)glewGetProcAddress((const GLubyte*)"glGetNextPerfQueryIdINTEL")) == NULL) || r; + r = ((glGetPerfCounterInfoINTEL = (PFNGLGETPERFCOUNTERINFOINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfCounterInfoINTEL")) == NULL) || r; + r = ((glGetPerfQueryDataINTEL = (PFNGLGETPERFQUERYDATAINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryDataINTEL")) == NULL) || r; + r = ((glGetPerfQueryIdByNameINTEL = (PFNGLGETPERFQUERYIDBYNAMEINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryIdByNameINTEL")) == NULL) || r; + r = ((glGetPerfQueryInfoINTEL = (PFNGLGETPERFQUERYINFOINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryInfoINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_performance_query */ + +#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_KHR_debug + +static GLboolean _glewInit_GL_KHR_debug (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallback")) == NULL) || r; + r = ((glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageControl")) == NULL) || r; + r = ((glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsert")) == NULL) || r; + r = ((glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLog")) == NULL) || r; + r = ((glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)glewGetProcAddress((const GLubyte*)"glGetObjectLabel")) == NULL) || r; + r = ((glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)glewGetProcAddress((const GLubyte*)"glGetObjectPtrLabel")) == NULL) || r; + r = ((glObjectLabel = (PFNGLOBJECTLABELPROC)glewGetProcAddress((const GLubyte*)"glObjectLabel")) == NULL) || r; + r = ((glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)glewGetProcAddress((const GLubyte*)"glObjectPtrLabel")) == NULL) || r; + r = ((glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)glewGetProcAddress((const GLubyte*)"glPopDebugGroup")) == NULL) || r; + r = ((glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)glewGetProcAddress((const GLubyte*)"glPushDebugGroup")) == NULL) || r; + + return r; +} + +#endif /* GL_KHR_debug */ + +#ifdef GL_KHR_texture_compression_astc_hdr + +#endif /* GL_KHR_texture_compression_astc_hdr */ + +#ifdef GL_KHR_texture_compression_astc_ldr + +#endif /* GL_KHR_texture_compression_astc_ldr */ + +#ifdef GL_KTX_buffer_region + +static GLboolean _glewInit_GL_KTX_buffer_region (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBufferRegionEnabled = (PFNGLBUFFERREGIONENABLEDPROC)glewGetProcAddress((const GLubyte*)"glBufferRegionEnabled")) == NULL) || r; + r = ((glDeleteBufferRegion = (PFNGLDELETEBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glDeleteBufferRegion")) == NULL) || r; + r = ((glDrawBufferRegion = (PFNGLDRAWBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glDrawBufferRegion")) == NULL) || r; + r = ((glNewBufferRegion = (PFNGLNEWBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glNewBufferRegion")) == NULL) || r; + r = ((glReadBufferRegion = (PFNGLREADBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glReadBufferRegion")) == 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_NVX_conditional_render + +static GLboolean _glewInit_GL_NVX_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginConditionalRenderNVX = (PFNGLBEGINCONDITIONALRENDERNVXPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNVX")) == NULL) || r; + r = ((glEndConditionalRenderNVX = (PFNGLENDCONDITIONALRENDERNVXPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNVX")) == NULL) || r; + + return r; +} + +#endif /* GL_NVX_conditional_render */ + +#ifdef GL_NVX_gpu_memory_info + +#endif /* GL_NVX_gpu_memory_info */ + +#ifdef GL_NV_bindless_multi_draw_indirect + +static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectBindlessNV = (PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectBindlessNV")) == NULL) || r; + r = ((glMultiDrawElementsIndirectBindlessNV = (PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectBindlessNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_bindless_multi_draw_indirect */ + +#ifdef GL_NV_bindless_texture + +static GLboolean _glewInit_GL_NV_bindless_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetImageHandleNV = (PFNGLGETIMAGEHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetImageHandleNV")) == NULL) || r; + r = ((glGetTextureHandleNV = (PFNGLGETTEXTUREHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureHandleNV")) == NULL) || r; + r = ((glGetTextureSamplerHandleNV = (PFNGLGETTEXTURESAMPLERHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSamplerHandleNV")) == NULL) || r; + r = ((glIsImageHandleResidentNV = (PFNGLISIMAGEHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsImageHandleResidentNV")) == NULL) || r; + r = ((glIsTextureHandleResidentNV = (PFNGLISTEXTUREHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsTextureHandleResidentNV")) == NULL) || r; + r = ((glMakeImageHandleNonResidentNV = (PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleNonResidentNV")) == NULL) || r; + r = ((glMakeImageHandleResidentNV = (PFNGLMAKEIMAGEHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleResidentNV")) == NULL) || r; + r = ((glMakeTextureHandleNonResidentNV = (PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleNonResidentNV")) == NULL) || r; + r = ((glMakeTextureHandleResidentNV = (PFNGLMAKETEXTUREHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleResidentNV")) == NULL) || r; + r = ((glProgramUniformHandleui64NV = (PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64NV")) == NULL) || r; + r = ((glProgramUniformHandleui64vNV = (PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64vNV")) == NULL) || r; + r = ((glUniformHandleui64NV = (PFNGLUNIFORMHANDLEUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64NV")) == NULL) || r; + r = ((glUniformHandleui64vNV = (PFNGLUNIFORMHANDLEUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64vNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_bindless_texture */ + +#ifdef GL_NV_blend_equation_advanced + +static GLboolean _glewInit_GL_NV_blend_equation_advanced (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendBarrierNV = (PFNGLBLENDBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glBlendBarrierNV")) == NULL) || r; + r = ((glBlendParameteriNV = (PFNGLBLENDPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glBlendParameteriNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_blend_equation_advanced */ + +#ifdef GL_NV_blend_equation_advanced_coherent + +#endif /* GL_NV_blend_equation_advanced_coherent */ + +#ifdef GL_NV_blend_square + +#endif /* GL_NV_blend_square */ + +#ifdef GL_NV_compute_program5 + +#endif /* GL_NV_compute_program5 */ + +#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_copy_image + +static GLboolean _glewInit_GL_NV_copy_image (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubDataNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_copy_image */ + +#ifdef GL_NV_deep_texture3D + +#endif /* GL_NV_deep_texture3D */ + +#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_draw_texture + +static GLboolean _glewInit_GL_NV_draw_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawTextureNV = (PFNGLDRAWTEXTURENVPROC)glewGetProcAddress((const GLubyte*)"glDrawTextureNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_draw_texture */ + +#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_gpu_program5 + +#endif /* GL_NV_gpu_program5 */ + +#ifdef GL_NV_gpu_program5_mem_extended + +#endif /* GL_NV_gpu_program5_mem_extended */ + +#ifdef GL_NV_gpu_program_fp64 + +#endif /* GL_NV_gpu_program_fp64 */ + +#ifdef GL_NV_gpu_shader5 + +static GLboolean _glewInit_GL_NV_gpu_shader5 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetUniformi64vNV = (PFNGLGETUNIFORMI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformi64vNV")) == NULL) || r; + r = ((glGetUniformui64vNV = (PFNGLGETUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformui64vNV")) == NULL) || r; + r = ((glProgramUniform1i64NV = (PFNGLPROGRAMUNIFORM1I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64NV")) == NULL) || r; + r = ((glProgramUniform1i64vNV = (PFNGLPROGRAMUNIFORM1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64vNV")) == NULL) || r; + r = ((glProgramUniform1ui64NV = (PFNGLPROGRAMUNIFORM1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64NV")) == NULL) || r; + r = ((glProgramUniform1ui64vNV = (PFNGLPROGRAMUNIFORM1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64vNV")) == NULL) || r; + r = ((glProgramUniform2i64NV = (PFNGLPROGRAMUNIFORM2I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64NV")) == NULL) || r; + r = ((glProgramUniform2i64vNV = (PFNGLPROGRAMUNIFORM2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64vNV")) == NULL) || r; + r = ((glProgramUniform2ui64NV = (PFNGLPROGRAMUNIFORM2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64NV")) == NULL) || r; + r = ((glProgramUniform2ui64vNV = (PFNGLPROGRAMUNIFORM2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64vNV")) == NULL) || r; + r = ((glProgramUniform3i64NV = (PFNGLPROGRAMUNIFORM3I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64NV")) == NULL) || r; + r = ((glProgramUniform3i64vNV = (PFNGLPROGRAMUNIFORM3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64vNV")) == NULL) || r; + r = ((glProgramUniform3ui64NV = (PFNGLPROGRAMUNIFORM3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64NV")) == NULL) || r; + r = ((glProgramUniform3ui64vNV = (PFNGLPROGRAMUNIFORM3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64vNV")) == NULL) || r; + r = ((glProgramUniform4i64NV = (PFNGLPROGRAMUNIFORM4I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64NV")) == NULL) || r; + r = ((glProgramUniform4i64vNV = (PFNGLPROGRAMUNIFORM4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64vNV")) == NULL) || r; + r = ((glProgramUniform4ui64NV = (PFNGLPROGRAMUNIFORM4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64NV")) == NULL) || r; + r = ((glProgramUniform4ui64vNV = (PFNGLPROGRAMUNIFORM4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64vNV")) == NULL) || r; + r = ((glUniform1i64NV = (PFNGLUNIFORM1I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64NV")) == NULL) || r; + r = ((glUniform1i64vNV = (PFNGLUNIFORM1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64vNV")) == NULL) || r; + r = ((glUniform1ui64NV = (PFNGLUNIFORM1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64NV")) == NULL) || r; + r = ((glUniform1ui64vNV = (PFNGLUNIFORM1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64vNV")) == NULL) || r; + r = ((glUniform2i64NV = (PFNGLUNIFORM2I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64NV")) == NULL) || r; + r = ((glUniform2i64vNV = (PFNGLUNIFORM2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64vNV")) == NULL) || r; + r = ((glUniform2ui64NV = (PFNGLUNIFORM2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64NV")) == NULL) || r; + r = ((glUniform2ui64vNV = (PFNGLUNIFORM2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64vNV")) == NULL) || r; + r = ((glUniform3i64NV = (PFNGLUNIFORM3I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64NV")) == NULL) || r; + r = ((glUniform3i64vNV = (PFNGLUNIFORM3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64vNV")) == NULL) || r; + r = ((glUniform3ui64NV = (PFNGLUNIFORM3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64NV")) == NULL) || r; + r = ((glUniform3ui64vNV = (PFNGLUNIFORM3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64vNV")) == NULL) || r; + r = ((glUniform4i64NV = (PFNGLUNIFORM4I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64NV")) == NULL) || r; + r = ((glUniform4i64vNV = (PFNGLUNIFORM4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64vNV")) == NULL) || r; + r = ((glUniform4ui64NV = (PFNGLUNIFORM4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64NV")) == NULL) || r; + r = ((glUniform4ui64vNV = (PFNGLUNIFORM4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64vNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_gpu_shader5 */ + +#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_coverage + +#endif /* GL_NV_multisample_coverage */ + +#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_parameter_buffer_object2 + +#endif /* GL_NV_parameter_buffer_object2 */ + +#ifdef GL_NV_path_rendering + +static GLboolean _glewInit_GL_NV_path_rendering (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyPathNV = (PFNGLCOPYPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCopyPathNV")) == NULL) || r; + r = ((glCoverFillPathInstancedNV = (PFNGLCOVERFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glCoverFillPathInstancedNV")) == NULL) || r; + r = ((glCoverFillPathNV = (PFNGLCOVERFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCoverFillPathNV")) == NULL) || r; + r = ((glCoverStrokePathInstancedNV = (PFNGLCOVERSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glCoverStrokePathInstancedNV")) == NULL) || r; + r = ((glCoverStrokePathNV = (PFNGLCOVERSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCoverStrokePathNV")) == NULL) || r; + r = ((glDeletePathsNV = (PFNGLDELETEPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glDeletePathsNV")) == NULL) || r; + r = ((glGenPathsNV = (PFNGLGENPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glGenPathsNV")) == NULL) || r; + r = ((glGetPathColorGenfvNV = (PFNGLGETPATHCOLORGENFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathColorGenfvNV")) == NULL) || r; + r = ((glGetPathColorGenivNV = (PFNGLGETPATHCOLORGENIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathColorGenivNV")) == NULL) || r; + r = ((glGetPathCommandsNV = (PFNGLGETPATHCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathCommandsNV")) == NULL) || r; + r = ((glGetPathCoordsNV = (PFNGLGETPATHCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathCoordsNV")) == NULL) || r; + r = ((glGetPathDashArrayNV = (PFNGLGETPATHDASHARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathDashArrayNV")) == NULL) || r; + r = ((glGetPathLengthNV = (PFNGLGETPATHLENGTHNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathLengthNV")) == NULL) || r; + r = ((glGetPathMetricRangeNV = (PFNGLGETPATHMETRICRANGENVPROC)glewGetProcAddress((const GLubyte*)"glGetPathMetricRangeNV")) == NULL) || r; + r = ((glGetPathMetricsNV = (PFNGLGETPATHMETRICSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathMetricsNV")) == NULL) || r; + r = ((glGetPathParameterfvNV = (PFNGLGETPATHPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathParameterfvNV")) == NULL) || r; + r = ((glGetPathParameterivNV = (PFNGLGETPATHPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathParameterivNV")) == NULL) || r; + r = ((glGetPathSpacingNV = (PFNGLGETPATHSPACINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathSpacingNV")) == NULL) || r; + r = ((glGetPathTexGenfvNV = (PFNGLGETPATHTEXGENFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathTexGenfvNV")) == NULL) || r; + r = ((glGetPathTexGenivNV = (PFNGLGETPATHTEXGENIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathTexGenivNV")) == NULL) || r; + r = ((glInterpolatePathsNV = (PFNGLINTERPOLATEPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glInterpolatePathsNV")) == NULL) || r; + r = ((glIsPathNV = (PFNGLISPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPathNV")) == NULL) || r; + r = ((glIsPointInFillPathNV = (PFNGLISPOINTINFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPointInFillPathNV")) == NULL) || r; + r = ((glIsPointInStrokePathNV = (PFNGLISPOINTINSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPointInStrokePathNV")) == NULL) || r; + r = ((glPathColorGenNV = (PFNGLPATHCOLORGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathColorGenNV")) == NULL) || r; + r = ((glPathCommandsNV = (PFNGLPATHCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathCommandsNV")) == NULL) || r; + r = ((glPathCoordsNV = (PFNGLPATHCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathCoordsNV")) == NULL) || r; + r = ((glPathCoverDepthFuncNV = (PFNGLPATHCOVERDEPTHFUNCNVPROC)glewGetProcAddress((const GLubyte*)"glPathCoverDepthFuncNV")) == NULL) || r; + r = ((glPathDashArrayNV = (PFNGLPATHDASHARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glPathDashArrayNV")) == NULL) || r; + r = ((glPathFogGenNV = (PFNGLPATHFOGGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathFogGenNV")) == NULL) || r; + r = ((glPathGlyphRangeNV = (PFNGLPATHGLYPHRANGENVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphRangeNV")) == NULL) || r; + r = ((glPathGlyphsNV = (PFNGLPATHGLYPHSNVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphsNV")) == NULL) || r; + r = ((glPathParameterfNV = (PFNGLPATHPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterfNV")) == NULL) || r; + r = ((glPathParameterfvNV = (PFNGLPATHPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterfvNV")) == NULL) || r; + r = ((glPathParameteriNV = (PFNGLPATHPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPathParameteriNV")) == NULL) || r; + r = ((glPathParameterivNV = (PFNGLPATHPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterivNV")) == NULL) || r; + r = ((glPathStencilDepthOffsetNV = (PFNGLPATHSTENCILDEPTHOFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glPathStencilDepthOffsetNV")) == NULL) || r; + r = ((glPathStencilFuncNV = (PFNGLPATHSTENCILFUNCNVPROC)glewGetProcAddress((const GLubyte*)"glPathStencilFuncNV")) == NULL) || r; + r = ((glPathStringNV = (PFNGLPATHSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glPathStringNV")) == NULL) || r; + r = ((glPathSubCommandsNV = (PFNGLPATHSUBCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathSubCommandsNV")) == NULL) || r; + r = ((glPathSubCoordsNV = (PFNGLPATHSUBCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathSubCoordsNV")) == NULL) || r; + r = ((glPathTexGenNV = (PFNGLPATHTEXGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathTexGenNV")) == NULL) || r; + r = ((glPointAlongPathNV = (PFNGLPOINTALONGPATHNVPROC)glewGetProcAddress((const GLubyte*)"glPointAlongPathNV")) == NULL) || r; + r = ((glStencilFillPathInstancedNV = (PFNGLSTENCILFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilFillPathInstancedNV")) == NULL) || r; + r = ((glStencilFillPathNV = (PFNGLSTENCILFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilFillPathNV")) == NULL) || r; + r = ((glStencilStrokePathInstancedNV = (PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilStrokePathInstancedNV")) == NULL) || r; + r = ((glStencilStrokePathNV = (PFNGLSTENCILSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilStrokePathNV")) == NULL) || r; + r = ((glTransformPathNV = (PFNGLTRANSFORMPATHNVPROC)glewGetProcAddress((const GLubyte*)"glTransformPathNV")) == NULL) || r; + r = ((glWeightPathsNV = (PFNGLWEIGHTPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glWeightPathsNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_path_rendering */ + +#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; + + 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_shader_atomic_counters + +#endif /* GL_NV_shader_atomic_counters */ + +#ifdef GL_NV_shader_atomic_float + +#endif /* GL_NV_shader_atomic_float */ + +#ifdef GL_NV_shader_buffer_load + +static GLboolean _glewInit_GL_NV_shader_buffer_load (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetBufferParameterui64vNV = (PFNGLGETBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterui64vNV")) == NULL) || r; + r = ((glGetIntegerui64vNV = (PFNGLGETINTEGERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64vNV")) == NULL) || r; + r = ((glGetNamedBufferParameterui64vNV = (PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterui64vNV")) == NULL) || r; + r = ((glIsBufferResidentNV = (PFNGLISBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsBufferResidentNV")) == NULL) || r; + r = ((glIsNamedBufferResidentNV = (PFNGLISNAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsNamedBufferResidentNV")) == NULL) || r; + r = ((glMakeBufferNonResidentNV = (PFNGLMAKEBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferNonResidentNV")) == NULL) || r; + r = ((glMakeBufferResidentNV = (PFNGLMAKEBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferResidentNV")) == NULL) || r; + r = ((glMakeNamedBufferNonResidentNV = (PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferNonResidentNV")) == NULL) || r; + r = ((glMakeNamedBufferResidentNV = (PFNGLMAKENAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferResidentNV")) == NULL) || r; + r = ((glProgramUniformui64NV = (PFNGLPROGRAMUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64NV")) == NULL) || r; + r = ((glProgramUniformui64vNV = (PFNGLPROGRAMUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64vNV")) == NULL) || r; + r = ((glUniformui64NV = (PFNGLUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64NV")) == NULL) || r; + r = ((glUniformui64vNV = (PFNGLUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64vNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_shader_buffer_load */ + +#ifdef GL_NV_shader_storage_buffer_object + +#endif /* GL_NV_shader_storage_buffer_object */ + +#ifdef GL_NV_shader_thread_group + +#endif /* GL_NV_shader_thread_group */ + +#ifdef GL_NV_shader_thread_shuffle + +#endif /* GL_NV_shader_thread_shuffle */ + +#ifdef GL_NV_tessellation_program5 + +#endif /* GL_NV_tessellation_program5 */ + +#ifdef GL_NV_texgen_emboss + +#endif /* GL_NV_texgen_emboss */ + +#ifdef GL_NV_texgen_reflection + +#endif /* GL_NV_texgen_reflection */ + +#ifdef GL_NV_texture_barrier + +static GLboolean _glewInit_GL_NV_texture_barrier (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTextureBarrierNV = (PFNGLTEXTUREBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glTextureBarrierNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_texture_barrier */ + +#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_multisample + +static GLboolean _glewInit_GL_NV_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage2DMultisampleCoverageNV = (PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisampleCoverageNV")) == NULL) || r; + r = ((glTexImage3DMultisampleCoverageNV = (PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisampleCoverageNV")) == NULL) || r; + r = ((glTextureImage2DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DMultisampleCoverageNV")) == NULL) || r; + r = ((glTextureImage2DMultisampleNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DMultisampleNV")) == NULL) || r; + r = ((glTextureImage3DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DMultisampleCoverageNV")) == NULL) || r; + r = ((glTextureImage3DMultisampleNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DMultisampleNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_texture_multisample */ + +#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_transform_feedback2 + +static GLboolean _glewInit_GL_NV_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindTransformFeedbackNV = (PFNGLBINDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedbackNV")) == NULL) || r; + r = ((glDeleteTransformFeedbacksNV = (PFNGLDELETETRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacksNV")) == NULL) || r; + r = ((glDrawTransformFeedbackNV = (PFNGLDRAWTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackNV")) == NULL) || r; + r = ((glGenTransformFeedbacksNV = (PFNGLGENTRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacksNV")) == NULL) || r; + r = ((glIsTransformFeedbackNV = (PFNGLISTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedbackNV")) == NULL) || r; + r = ((glPauseTransformFeedbackNV = (PFNGLPAUSETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedbackNV")) == NULL) || r; + r = ((glResumeTransformFeedbackNV = (PFNGLRESUMETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedbackNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_transform_feedback2 */ + +#ifdef GL_NV_vdpau_interop + +static GLboolean _glewInit_GL_NV_vdpau_interop (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVDPAUFiniNV = (PFNGLVDPAUFININVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUFiniNV")) == NULL) || r; + r = ((glVDPAUGetSurfaceivNV = (PFNGLVDPAUGETSURFACEIVNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUGetSurfaceivNV")) == NULL) || r; + r = ((glVDPAUInitNV = (PFNGLVDPAUINITNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUInitNV")) == NULL) || r; + r = ((glVDPAUIsSurfaceNV = (PFNGLVDPAUISSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUIsSurfaceNV")) == NULL) || r; + r = ((glVDPAUMapSurfacesNV = (PFNGLVDPAUMAPSURFACESNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUMapSurfacesNV")) == NULL) || r; + r = ((glVDPAURegisterOutputSurfaceNV = (PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAURegisterOutputSurfaceNV")) == NULL) || r; + r = ((glVDPAURegisterVideoSurfaceNV = (PFNGLVDPAUREGISTERVIDEOSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAURegisterVideoSurfaceNV")) == NULL) || r; + r = ((glVDPAUSurfaceAccessNV = (PFNGLVDPAUSURFACEACCESSNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUSurfaceAccessNV")) == NULL) || r; + r = ((glVDPAUUnmapSurfacesNV = (PFNGLVDPAUUNMAPSURFACESNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUUnmapSurfacesNV")) == NULL) || r; + r = ((glVDPAUUnregisterSurfaceNV = (PFNGLVDPAUUNREGISTERSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUUnregisterSurfaceNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vdpau_interop */ + +#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_attrib_integer_64bit + +static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribLi64vNV = (PFNGLGETVERTEXATTRIBLI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLi64vNV")) == NULL) || r; + r = ((glGetVertexAttribLui64vNV = (PFNGLGETVERTEXATTRIBLUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLui64vNV")) == NULL) || r; + r = ((glVertexAttribL1i64NV = (PFNGLVERTEXATTRIBL1I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1i64NV")) == NULL) || r; + r = ((glVertexAttribL1i64vNV = (PFNGLVERTEXATTRIBL1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1i64vNV")) == NULL) || r; + r = ((glVertexAttribL1ui64NV = (PFNGLVERTEXATTRIBL1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64NV")) == NULL) || r; + r = ((glVertexAttribL1ui64vNV = (PFNGLVERTEXATTRIBL1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64vNV")) == NULL) || r; + r = ((glVertexAttribL2i64NV = (PFNGLVERTEXATTRIBL2I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2i64NV")) == NULL) || r; + r = ((glVertexAttribL2i64vNV = (PFNGLVERTEXATTRIBL2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2i64vNV")) == NULL) || r; + r = ((glVertexAttribL2ui64NV = (PFNGLVERTEXATTRIBL2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2ui64NV")) == NULL) || r; + r = ((glVertexAttribL2ui64vNV = (PFNGLVERTEXATTRIBL2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2ui64vNV")) == NULL) || r; + r = ((glVertexAttribL3i64NV = (PFNGLVERTEXATTRIBL3I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3i64NV")) == NULL) || r; + r = ((glVertexAttribL3i64vNV = (PFNGLVERTEXATTRIBL3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3i64vNV")) == NULL) || r; + r = ((glVertexAttribL3ui64NV = (PFNGLVERTEXATTRIBL3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3ui64NV")) == NULL) || r; + r = ((glVertexAttribL3ui64vNV = (PFNGLVERTEXATTRIBL3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3ui64vNV")) == NULL) || r; + r = ((glVertexAttribL4i64NV = (PFNGLVERTEXATTRIBL4I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4i64NV")) == NULL) || r; + r = ((glVertexAttribL4i64vNV = (PFNGLVERTEXATTRIBL4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4i64vNV")) == NULL) || r; + r = ((glVertexAttribL4ui64NV = (PFNGLVERTEXATTRIBL4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4ui64NV")) == NULL) || r; + r = ((glVertexAttribL4ui64vNV = (PFNGLVERTEXATTRIBL4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4ui64vNV")) == NULL) || r; + r = ((glVertexAttribLFormatNV = (PFNGLVERTEXATTRIBLFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLFormatNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +#ifdef GL_NV_vertex_buffer_unified_memory + +static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBufferAddressRangeNV = (PFNGLBUFFERADDRESSRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBufferAddressRangeNV")) == NULL) || r; + r = ((glColorFormatNV = (PFNGLCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glColorFormatNV")) == NULL) || r; + r = ((glEdgeFlagFormatNV = (PFNGLEDGEFLAGFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagFormatNV")) == NULL) || r; + r = ((glFogCoordFormatNV = (PFNGLFOGCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordFormatNV")) == NULL) || r; + r = ((glGetIntegerui64i_vNV = (PFNGLGETINTEGERUI64I_VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64i_vNV")) == NULL) || r; + r = ((glIndexFormatNV = (PFNGLINDEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glIndexFormatNV")) == NULL) || r; + r = ((glNormalFormatNV = (PFNGLNORMALFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glNormalFormatNV")) == NULL) || r; + r = ((glSecondaryColorFormatNV = (PFNGLSECONDARYCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorFormatNV")) == NULL) || r; + r = ((glTexCoordFormatNV = (PFNGLTEXCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordFormatNV")) == NULL) || r; + r = ((glVertexAttribFormatNV = (PFNGLVERTEXATTRIBFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormatNV")) == NULL) || r; + r = ((glVertexAttribIFormatNV = (PFNGLVERTEXATTRIBIFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormatNV")) == NULL) || r; + r = ((glVertexFormatNV = (PFNGLVERTEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexFormatNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_buffer_unified_memory */ + +#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_NV_video_capture + +static GLboolean _glewInit_GL_NV_video_capture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginVideoCaptureNV = (PFNGLBEGINVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glBeginVideoCaptureNV")) == NULL) || r; + r = ((glBindVideoCaptureStreamBufferNV = (PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glBindVideoCaptureStreamBufferNV")) == NULL) || r; + r = ((glBindVideoCaptureStreamTextureNV = (PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC)glewGetProcAddress((const GLubyte*)"glBindVideoCaptureStreamTextureNV")) == NULL) || r; + r = ((glEndVideoCaptureNV = (PFNGLENDVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glEndVideoCaptureNV")) == NULL) || r; + r = ((glGetVideoCaptureStreamdvNV = (PFNGLGETVIDEOCAPTURESTREAMDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamdvNV")) == NULL) || r; + r = ((glGetVideoCaptureStreamfvNV = (PFNGLGETVIDEOCAPTURESTREAMFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamfvNV")) == NULL) || r; + r = ((glGetVideoCaptureStreamivNV = (PFNGLGETVIDEOCAPTURESTREAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamivNV")) == NULL) || r; + r = ((glGetVideoCaptureivNV = (PFNGLGETVIDEOCAPTUREIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureivNV")) == NULL) || r; + r = ((glVideoCaptureNV = (PFNGLVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureNV")) == NULL) || r; + r = ((glVideoCaptureStreamParameterdvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterdvNV")) == NULL) || r; + r = ((glVideoCaptureStreamParameterfvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterfvNV")) == NULL) || r; + r = ((glVideoCaptureStreamParameterivNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_video_capture */ + +#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_REGAL_ES1_0_compatibility + +static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAlphaFuncx = (PFNGLALPHAFUNCXPROC)glewGetProcAddress((const GLubyte*)"glAlphaFuncx")) == NULL) || r; + r = ((glClearColorx = (PFNGLCLEARCOLORXPROC)glewGetProcAddress((const GLubyte*)"glClearColorx")) == NULL) || r; + r = ((glClearDepthx = (PFNGLCLEARDEPTHXPROC)glewGetProcAddress((const GLubyte*)"glClearDepthx")) == NULL) || r; + r = ((glColor4x = (PFNGLCOLOR4XPROC)glewGetProcAddress((const GLubyte*)"glColor4x")) == NULL) || r; + r = ((glDepthRangex = (PFNGLDEPTHRANGEXPROC)glewGetProcAddress((const GLubyte*)"glDepthRangex")) == NULL) || r; + r = ((glFogx = (PFNGLFOGXPROC)glewGetProcAddress((const GLubyte*)"glFogx")) == NULL) || r; + r = ((glFogxv = (PFNGLFOGXVPROC)glewGetProcAddress((const GLubyte*)"glFogxv")) == NULL) || r; + r = ((glFrustumf = (PFNGLFRUSTUMFPROC)glewGetProcAddress((const GLubyte*)"glFrustumf")) == NULL) || r; + r = ((glFrustumx = (PFNGLFRUSTUMXPROC)glewGetProcAddress((const GLubyte*)"glFrustumx")) == NULL) || r; + r = ((glLightModelx = (PFNGLLIGHTMODELXPROC)glewGetProcAddress((const GLubyte*)"glLightModelx")) == NULL) || r; + r = ((glLightModelxv = (PFNGLLIGHTMODELXVPROC)glewGetProcAddress((const GLubyte*)"glLightModelxv")) == NULL) || r; + r = ((glLightx = (PFNGLLIGHTXPROC)glewGetProcAddress((const GLubyte*)"glLightx")) == NULL) || r; + r = ((glLightxv = (PFNGLLIGHTXVPROC)glewGetProcAddress((const GLubyte*)"glLightxv")) == NULL) || r; + r = ((glLineWidthx = (PFNGLLINEWIDTHXPROC)glewGetProcAddress((const GLubyte*)"glLineWidthx")) == NULL) || r; + r = ((glLoadMatrixx = (PFNGLLOADMATRIXXPROC)glewGetProcAddress((const GLubyte*)"glLoadMatrixx")) == NULL) || r; + r = ((glMaterialx = (PFNGLMATERIALXPROC)glewGetProcAddress((const GLubyte*)"glMaterialx")) == NULL) || r; + r = ((glMaterialxv = (PFNGLMATERIALXVPROC)glewGetProcAddress((const GLubyte*)"glMaterialxv")) == NULL) || r; + r = ((glMultMatrixx = (PFNGLMULTMATRIXXPROC)glewGetProcAddress((const GLubyte*)"glMultMatrixx")) == NULL) || r; + r = ((glMultiTexCoord4x = (PFNGLMULTITEXCOORD4XPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4x")) == NULL) || r; + r = ((glNormal3x = (PFNGLNORMAL3XPROC)glewGetProcAddress((const GLubyte*)"glNormal3x")) == NULL) || r; + r = ((glOrthof = (PFNGLORTHOFPROC)glewGetProcAddress((const GLubyte*)"glOrthof")) == NULL) || r; + r = ((glOrthox = (PFNGLORTHOXPROC)glewGetProcAddress((const GLubyte*)"glOrthox")) == NULL) || r; + r = ((glPointSizex = (PFNGLPOINTSIZEXPROC)glewGetProcAddress((const GLubyte*)"glPointSizex")) == NULL) || r; + r = ((glPolygonOffsetx = (PFNGLPOLYGONOFFSETXPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetx")) == NULL) || r; + r = ((glRotatex = (PFNGLROTATEXPROC)glewGetProcAddress((const GLubyte*)"glRotatex")) == NULL) || r; + r = ((glSampleCoveragex = (PFNGLSAMPLECOVERAGEXPROC)glewGetProcAddress((const GLubyte*)"glSampleCoveragex")) == NULL) || r; + r = ((glScalex = (PFNGLSCALEXPROC)glewGetProcAddress((const GLubyte*)"glScalex")) == NULL) || r; + r = ((glTexEnvx = (PFNGLTEXENVXPROC)glewGetProcAddress((const GLubyte*)"glTexEnvx")) == NULL) || r; + r = ((glTexEnvxv = (PFNGLTEXENVXVPROC)glewGetProcAddress((const GLubyte*)"glTexEnvxv")) == NULL) || r; + r = ((glTexParameterx = (PFNGLTEXPARAMETERXPROC)glewGetProcAddress((const GLubyte*)"glTexParameterx")) == NULL) || r; + r = ((glTranslatex = (PFNGLTRANSLATEXPROC)glewGetProcAddress((const GLubyte*)"glTranslatex")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_ES1_0_compatibility */ + +#ifdef GL_REGAL_ES1_1_compatibility + +static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClipPlanef = (PFNGLCLIPPLANEFPROC)glewGetProcAddress((const GLubyte*)"glClipPlanef")) == NULL) || r; + r = ((glClipPlanex = (PFNGLCLIPPLANEXPROC)glewGetProcAddress((const GLubyte*)"glClipPlanex")) == NULL) || r; + r = ((glGetClipPlanef = (PFNGLGETCLIPPLANEFPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanef")) == NULL) || r; + r = ((glGetClipPlanex = (PFNGLGETCLIPPLANEXPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanex")) == NULL) || r; + r = ((glGetFixedv = (PFNGLGETFIXEDVPROC)glewGetProcAddress((const GLubyte*)"glGetFixedv")) == NULL) || r; + r = ((glGetLightxv = (PFNGLGETLIGHTXVPROC)glewGetProcAddress((const GLubyte*)"glGetLightxv")) == NULL) || r; + r = ((glGetMaterialxv = (PFNGLGETMATERIALXVPROC)glewGetProcAddress((const GLubyte*)"glGetMaterialxv")) == NULL) || r; + r = ((glGetTexEnvxv = (PFNGLGETTEXENVXVPROC)glewGetProcAddress((const GLubyte*)"glGetTexEnvxv")) == NULL) || r; + r = ((glGetTexParameterxv = (PFNGLGETTEXPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterxv")) == NULL) || r; + r = ((glPointParameterx = (PFNGLPOINTPARAMETERXPROC)glewGetProcAddress((const GLubyte*)"glPointParameterx")) == NULL) || r; + r = ((glPointParameterxv = (PFNGLPOINTPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterxv")) == NULL) || r; + r = ((glPointSizePointerOES = (PFNGLPOINTSIZEPOINTEROESPROC)glewGetProcAddress((const GLubyte*)"glPointSizePointerOES")) == NULL) || r; + r = ((glTexParameterxv = (PFNGLTEXPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterxv")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_ES1_1_compatibility */ + +#ifdef GL_REGAL_enable + +#endif /* GL_REGAL_enable */ + +#ifdef GL_REGAL_error_string + +static GLboolean _glewInit_GL_REGAL_error_string (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glErrorStringREGAL = (PFNGLERRORSTRINGREGALPROC)glewGetProcAddress((const GLubyte*)"glErrorStringREGAL")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_error_string */ + +#ifdef GL_REGAL_extension_query + +static GLboolean _glewInit_GL_REGAL_extension_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetExtensionREGAL = (PFNGLGETEXTENSIONREGALPROC)glewGetProcAddress((const GLubyte*)"glGetExtensionREGAL")) == NULL) || r; + r = ((glIsSupportedREGAL = (PFNGLISSUPPORTEDREGALPROC)glewGetProcAddress((const GLubyte*)"glIsSupportedREGAL")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_extension_query */ + +#ifdef GL_REGAL_log + +static GLboolean _glewInit_GL_REGAL_log (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glLogMessageCallbackREGAL = (PFNGLLOGMESSAGECALLBACKREGALPROC)glewGetProcAddress((const GLubyte*)"glLogMessageCallbackREGAL")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_log */ + +#ifdef GL_REGAL_proc_address + +static GLboolean _glewInit_GL_REGAL_proc_address (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetProcAddressREGAL = (PFNGLGETPROCADDRESSREGALPROC)glewGetProcAddress((const GLubyte*)"glGetProcAddressREGAL")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_proc_address */ + +#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 */ + +/* ------------------------------------------------------------------------- */ + +GLboolean GLEWAPIENTRY glewGetExtension (const char* name) +{ + const GLubyte* start; + const GLubyte* end; + start = (const GLubyte*)glGetString(GL_EXTENSIONS); + if (start == 0) + return GL_FALSE; + end = start + _glewStrLen(start); + return _glewSearchExtension(name, start, end); +} + +/* ------------------------------------------------------------------------- */ + +#ifndef GLEW_MX +static +#endif +GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) +{ + const GLubyte* s; + GLuint dot; + GLint major, minor; + const GLubyte* extStart; + const GLubyte* extEnd; + /* query opengl version */ + s = glGetString(GL_VERSION); + dot = _glewStrCLen(s, '.'); + if (dot == 0) + return GLEW_ERROR_NO_GL_VERSION; + + major = s[dot-1]-'0'; + minor = s[dot+1]-'0'; + + if (minor < 0 || minor > 9) + minor = 0; + if (major<0 || major>9) + return GLEW_ERROR_NO_GL_VERSION; + + + if (major == 1 && minor == 0) + { + return GLEW_ERROR_GL_VERSION_10_ONLY; + } + else + { + GLEW_VERSION_4_4 = ( major > 4 ) || ( major == 4 && minor >= 4 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_4_3 = GLEW_VERSION_4_4 == GL_TRUE || ( major == 4 && minor >= 3 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_4_2 = GLEW_VERSION_4_3 == GL_TRUE || ( major == 4 && minor >= 2 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_4_1 = GLEW_VERSION_4_2 == GL_TRUE || ( major == 4 && minor >= 1 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_4_0 = GLEW_VERSION_4_1 == GL_TRUE || ( major == 4 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_3_3 = GLEW_VERSION_4_0 == GL_TRUE || ( major == 3 && minor >= 3 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_3_2 = GLEW_VERSION_3_3 == GL_TRUE || ( major == 3 && minor >= 2 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_3_1 = GLEW_VERSION_3_2 == GL_TRUE || ( major == 3 && minor >= 1 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_3_0 = GLEW_VERSION_3_1 == GL_TRUE || ( major == 3 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_2_1 = GLEW_VERSION_3_0 == GL_TRUE || ( major == 2 && minor >= 1 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_2_0 = GLEW_VERSION_2_1 == GL_TRUE || ( major == 2 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_1_5 = GLEW_VERSION_2_0 == GL_TRUE || ( major == 1 && minor >= 5 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_1_4 = GLEW_VERSION_1_5 == GL_TRUE || ( major == 1 && minor >= 4 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_1_3 = GLEW_VERSION_1_4 == GL_TRUE || ( major == 1 && minor >= 3 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_1_2_1 = GLEW_VERSION_1_3 == GL_TRUE ? GL_TRUE : GL_FALSE; + GLEW_VERSION_1_2 = GLEW_VERSION_1_2_1 == GL_TRUE || ( major == 1 && minor >= 2 ) ? GL_TRUE : GL_FALSE; + GLEW_VERSION_1_1 = GLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE; + } + + /* query opengl extensions string */ + extStart = glGetString(GL_EXTENSIONS); + if (extStart == 0) + extStart = (const GLubyte*)""; + extEnd = extStart + _glewStrLen(extStart); + + /* initialize extensions */ +#ifdef GL_VERSION_1_2 + if (glewExperimental || GLEW_VERSION_1_2) GLEW_VERSION_1_2 = !_glewInit_GL_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_2 */ +#ifdef GL_VERSION_1_2_1 +#endif /* GL_VERSION_1_2_1 */ +#ifdef GL_VERSION_1_3 + if (glewExperimental || GLEW_VERSION_1_3) 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) 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) 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) 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) 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) GLEW_VERSION_3_0 = !_glewInit_GL_VERSION_3_0(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_3_0 */ +#ifdef GL_VERSION_3_1 + if (glewExperimental || GLEW_VERSION_3_1) GLEW_VERSION_3_1 = !_glewInit_GL_VERSION_3_1(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_3_1 */ +#ifdef GL_VERSION_3_2 + if (glewExperimental || GLEW_VERSION_3_2) GLEW_VERSION_3_2 = !_glewInit_GL_VERSION_3_2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_3_2 */ +#ifdef GL_VERSION_3_3 + if (glewExperimental || GLEW_VERSION_3_3) GLEW_VERSION_3_3 = !_glewInit_GL_VERSION_3_3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_3_3 */ +#ifdef GL_VERSION_4_0 + if (glewExperimental || GLEW_VERSION_4_0) GLEW_VERSION_4_0 = !_glewInit_GL_VERSION_4_0(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_4_0 */ +#ifdef GL_VERSION_4_1 +#endif /* GL_VERSION_4_1 */ +#ifdef GL_VERSION_4_2 +#endif /* GL_VERSION_4_2 */ +#ifdef GL_VERSION_4_3 +#endif /* GL_VERSION_4_3 */ +#ifdef GL_VERSION_4_4 +#endif /* GL_VERSION_4_4 */ +#ifdef GL_3DFX_multisample + GLEW_3DFX_multisample = _glewSearchExtension("GL_3DFX_multisample", extStart, extEnd); +#endif /* GL_3DFX_multisample */ +#ifdef GL_3DFX_tbuffer + GLEW_3DFX_tbuffer = _glewSearchExtension("GL_3DFX_tbuffer", extStart, extEnd); + if (glewExperimental || GLEW_3DFX_tbuffer) GLEW_3DFX_tbuffer = !_glewInit_GL_3DFX_tbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_3DFX_tbuffer */ +#ifdef GL_3DFX_texture_compression_FXT1 + GLEW_3DFX_texture_compression_FXT1 = _glewSearchExtension("GL_3DFX_texture_compression_FXT1", extStart, extEnd); +#endif /* GL_3DFX_texture_compression_FXT1 */ +#ifdef GL_AMD_blend_minmax_factor + GLEW_AMD_blend_minmax_factor = _glewSearchExtension("GL_AMD_blend_minmax_factor", extStart, extEnd); +#endif /* GL_AMD_blend_minmax_factor */ +#ifdef GL_AMD_conservative_depth + GLEW_AMD_conservative_depth = _glewSearchExtension("GL_AMD_conservative_depth", extStart, extEnd); +#endif /* GL_AMD_conservative_depth */ +#ifdef GL_AMD_debug_output + GLEW_AMD_debug_output = _glewSearchExtension("GL_AMD_debug_output", extStart, extEnd); + if (glewExperimental || GLEW_AMD_debug_output) GLEW_AMD_debug_output = !_glewInit_GL_AMD_debug_output(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_debug_output */ +#ifdef GL_AMD_depth_clamp_separate + GLEW_AMD_depth_clamp_separate = _glewSearchExtension("GL_AMD_depth_clamp_separate", extStart, extEnd); +#endif /* GL_AMD_depth_clamp_separate */ +#ifdef GL_AMD_draw_buffers_blend + GLEW_AMD_draw_buffers_blend = _glewSearchExtension("GL_AMD_draw_buffers_blend", extStart, extEnd); + if (glewExperimental || GLEW_AMD_draw_buffers_blend) GLEW_AMD_draw_buffers_blend = !_glewInit_GL_AMD_draw_buffers_blend(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_draw_buffers_blend */ +#ifdef GL_AMD_gcn_shader + GLEW_AMD_gcn_shader = _glewSearchExtension("GL_AMD_gcn_shader", extStart, extEnd); +#endif /* GL_AMD_gcn_shader */ +#ifdef GL_AMD_gpu_shader_int64 + GLEW_AMD_gpu_shader_int64 = _glewSearchExtension("GL_AMD_gpu_shader_int64", extStart, extEnd); +#endif /* GL_AMD_gpu_shader_int64 */ +#ifdef GL_AMD_interleaved_elements + GLEW_AMD_interleaved_elements = _glewSearchExtension("GL_AMD_interleaved_elements", extStart, extEnd); + if (glewExperimental || GLEW_AMD_interleaved_elements) GLEW_AMD_interleaved_elements = !_glewInit_GL_AMD_interleaved_elements(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_interleaved_elements */ +#ifdef GL_AMD_multi_draw_indirect + GLEW_AMD_multi_draw_indirect = _glewSearchExtension("GL_AMD_multi_draw_indirect", extStart, extEnd); + if (glewExperimental || GLEW_AMD_multi_draw_indirect) GLEW_AMD_multi_draw_indirect = !_glewInit_GL_AMD_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_multi_draw_indirect */ +#ifdef GL_AMD_name_gen_delete + GLEW_AMD_name_gen_delete = _glewSearchExtension("GL_AMD_name_gen_delete", extStart, extEnd); + if (glewExperimental || GLEW_AMD_name_gen_delete) GLEW_AMD_name_gen_delete = !_glewInit_GL_AMD_name_gen_delete(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_name_gen_delete */ +#ifdef GL_AMD_occlusion_query_event + GLEW_AMD_occlusion_query_event = _glewSearchExtension("GL_AMD_occlusion_query_event", extStart, extEnd); + if (glewExperimental || GLEW_AMD_occlusion_query_event) GLEW_AMD_occlusion_query_event = !_glewInit_GL_AMD_occlusion_query_event(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_occlusion_query_event */ +#ifdef GL_AMD_performance_monitor + GLEW_AMD_performance_monitor = _glewSearchExtension("GL_AMD_performance_monitor", extStart, extEnd); + if (glewExperimental || GLEW_AMD_performance_monitor) GLEW_AMD_performance_monitor = !_glewInit_GL_AMD_performance_monitor(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_performance_monitor */ +#ifdef GL_AMD_pinned_memory + GLEW_AMD_pinned_memory = _glewSearchExtension("GL_AMD_pinned_memory", extStart, extEnd); +#endif /* GL_AMD_pinned_memory */ +#ifdef GL_AMD_query_buffer_object + GLEW_AMD_query_buffer_object = _glewSearchExtension("GL_AMD_query_buffer_object", extStart, extEnd); +#endif /* GL_AMD_query_buffer_object */ +#ifdef GL_AMD_sample_positions + GLEW_AMD_sample_positions = _glewSearchExtension("GL_AMD_sample_positions", extStart, extEnd); + if (glewExperimental || GLEW_AMD_sample_positions) GLEW_AMD_sample_positions = !_glewInit_GL_AMD_sample_positions(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_sample_positions */ +#ifdef GL_AMD_seamless_cubemap_per_texture + GLEW_AMD_seamless_cubemap_per_texture = _glewSearchExtension("GL_AMD_seamless_cubemap_per_texture", extStart, extEnd); +#endif /* GL_AMD_seamless_cubemap_per_texture */ +#ifdef GL_AMD_shader_atomic_counter_ops + GLEW_AMD_shader_atomic_counter_ops = _glewSearchExtension("GL_AMD_shader_atomic_counter_ops", extStart, extEnd); +#endif /* GL_AMD_shader_atomic_counter_ops */ +#ifdef GL_AMD_shader_stencil_export + GLEW_AMD_shader_stencil_export = _glewSearchExtension("GL_AMD_shader_stencil_export", extStart, extEnd); +#endif /* GL_AMD_shader_stencil_export */ +#ifdef GL_AMD_shader_stencil_value_export + GLEW_AMD_shader_stencil_value_export = _glewSearchExtension("GL_AMD_shader_stencil_value_export", extStart, extEnd); +#endif /* GL_AMD_shader_stencil_value_export */ +#ifdef GL_AMD_shader_trinary_minmax + GLEW_AMD_shader_trinary_minmax = _glewSearchExtension("GL_AMD_shader_trinary_minmax", extStart, extEnd); +#endif /* GL_AMD_shader_trinary_minmax */ +#ifdef GL_AMD_sparse_texture + GLEW_AMD_sparse_texture = _glewSearchExtension("GL_AMD_sparse_texture", extStart, extEnd); + if (glewExperimental || GLEW_AMD_sparse_texture) GLEW_AMD_sparse_texture = !_glewInit_GL_AMD_sparse_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_sparse_texture */ +#ifdef GL_AMD_stencil_operation_extended + GLEW_AMD_stencil_operation_extended = _glewSearchExtension("GL_AMD_stencil_operation_extended", extStart, extEnd); + if (glewExperimental || GLEW_AMD_stencil_operation_extended) GLEW_AMD_stencil_operation_extended = !_glewInit_GL_AMD_stencil_operation_extended(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_stencil_operation_extended */ +#ifdef GL_AMD_texture_texture4 + GLEW_AMD_texture_texture4 = _glewSearchExtension("GL_AMD_texture_texture4", extStart, extEnd); +#endif /* GL_AMD_texture_texture4 */ +#ifdef GL_AMD_transform_feedback3_lines_triangles + GLEW_AMD_transform_feedback3_lines_triangles = _glewSearchExtension("GL_AMD_transform_feedback3_lines_triangles", extStart, extEnd); +#endif /* GL_AMD_transform_feedback3_lines_triangles */ +#ifdef GL_AMD_transform_feedback4 + GLEW_AMD_transform_feedback4 = _glewSearchExtension("GL_AMD_transform_feedback4", extStart, extEnd); +#endif /* GL_AMD_transform_feedback4 */ +#ifdef GL_AMD_vertex_shader_layer + GLEW_AMD_vertex_shader_layer = _glewSearchExtension("GL_AMD_vertex_shader_layer", extStart, extEnd); +#endif /* GL_AMD_vertex_shader_layer */ +#ifdef GL_AMD_vertex_shader_tessellator + GLEW_AMD_vertex_shader_tessellator = _glewSearchExtension("GL_AMD_vertex_shader_tessellator", extStart, extEnd); + if (glewExperimental || GLEW_AMD_vertex_shader_tessellator) GLEW_AMD_vertex_shader_tessellator = !_glewInit_GL_AMD_vertex_shader_tessellator(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_AMD_vertex_shader_tessellator */ +#ifdef GL_AMD_vertex_shader_viewport_index + GLEW_AMD_vertex_shader_viewport_index = _glewSearchExtension("GL_AMD_vertex_shader_viewport_index", extStart, extEnd); +#endif /* GL_AMD_vertex_shader_viewport_index */ +#ifdef GL_ANGLE_depth_texture + GLEW_ANGLE_depth_texture = _glewSearchExtension("GL_ANGLE_depth_texture", extStart, extEnd); +#endif /* GL_ANGLE_depth_texture */ +#ifdef GL_ANGLE_framebuffer_blit + GLEW_ANGLE_framebuffer_blit = _glewSearchExtension("GL_ANGLE_framebuffer_blit", extStart, extEnd); + if (glewExperimental || GLEW_ANGLE_framebuffer_blit) GLEW_ANGLE_framebuffer_blit = !_glewInit_GL_ANGLE_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ANGLE_framebuffer_blit */ +#ifdef GL_ANGLE_framebuffer_multisample + GLEW_ANGLE_framebuffer_multisample = _glewSearchExtension("GL_ANGLE_framebuffer_multisample", extStart, extEnd); + if (glewExperimental || GLEW_ANGLE_framebuffer_multisample) GLEW_ANGLE_framebuffer_multisample = !_glewInit_GL_ANGLE_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ANGLE_framebuffer_multisample */ +#ifdef GL_ANGLE_instanced_arrays + GLEW_ANGLE_instanced_arrays = _glewSearchExtension("GL_ANGLE_instanced_arrays", extStart, extEnd); + if (glewExperimental || GLEW_ANGLE_instanced_arrays) GLEW_ANGLE_instanced_arrays = !_glewInit_GL_ANGLE_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ANGLE_instanced_arrays */ +#ifdef GL_ANGLE_pack_reverse_row_order + GLEW_ANGLE_pack_reverse_row_order = _glewSearchExtension("GL_ANGLE_pack_reverse_row_order", extStart, extEnd); +#endif /* GL_ANGLE_pack_reverse_row_order */ +#ifdef GL_ANGLE_program_binary + GLEW_ANGLE_program_binary = _glewSearchExtension("GL_ANGLE_program_binary", extStart, extEnd); +#endif /* GL_ANGLE_program_binary */ +#ifdef GL_ANGLE_texture_compression_dxt1 + GLEW_ANGLE_texture_compression_dxt1 = _glewSearchExtension("GL_ANGLE_texture_compression_dxt1", extStart, extEnd); +#endif /* GL_ANGLE_texture_compression_dxt1 */ +#ifdef GL_ANGLE_texture_compression_dxt3 + GLEW_ANGLE_texture_compression_dxt3 = _glewSearchExtension("GL_ANGLE_texture_compression_dxt3", extStart, extEnd); +#endif /* GL_ANGLE_texture_compression_dxt3 */ +#ifdef GL_ANGLE_texture_compression_dxt5 + GLEW_ANGLE_texture_compression_dxt5 = _glewSearchExtension("GL_ANGLE_texture_compression_dxt5", extStart, extEnd); +#endif /* GL_ANGLE_texture_compression_dxt5 */ +#ifdef GL_ANGLE_texture_usage + GLEW_ANGLE_texture_usage = _glewSearchExtension("GL_ANGLE_texture_usage", extStart, extEnd); +#endif /* GL_ANGLE_texture_usage */ +#ifdef GL_ANGLE_timer_query + GLEW_ANGLE_timer_query = _glewSearchExtension("GL_ANGLE_timer_query", extStart, extEnd); + if (glewExperimental || GLEW_ANGLE_timer_query) GLEW_ANGLE_timer_query = !_glewInit_GL_ANGLE_timer_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ANGLE_timer_query */ +#ifdef GL_ANGLE_translated_shader_source + GLEW_ANGLE_translated_shader_source = _glewSearchExtension("GL_ANGLE_translated_shader_source", extStart, extEnd); + if (glewExperimental || GLEW_ANGLE_translated_shader_source) GLEW_ANGLE_translated_shader_source = !_glewInit_GL_ANGLE_translated_shader_source(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ANGLE_translated_shader_source */ +#ifdef GL_APPLE_aux_depth_stencil + GLEW_APPLE_aux_depth_stencil = _glewSearchExtension("GL_APPLE_aux_depth_stencil", extStart, extEnd); +#endif /* GL_APPLE_aux_depth_stencil */ +#ifdef GL_APPLE_client_storage + GLEW_APPLE_client_storage = _glewSearchExtension("GL_APPLE_client_storage", extStart, extEnd); +#endif /* GL_APPLE_client_storage */ +#ifdef GL_APPLE_element_array + GLEW_APPLE_element_array = _glewSearchExtension("GL_APPLE_element_array", extStart, extEnd); + if (glewExperimental || GLEW_APPLE_element_array) GLEW_APPLE_element_array = !_glewInit_GL_APPLE_element_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_element_array */ +#ifdef GL_APPLE_fence + GLEW_APPLE_fence = _glewSearchExtension("GL_APPLE_fence", extStart, extEnd); + if (glewExperimental || GLEW_APPLE_fence) GLEW_APPLE_fence = !_glewInit_GL_APPLE_fence(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_fence */ +#ifdef GL_APPLE_float_pixels + GLEW_APPLE_float_pixels = _glewSearchExtension("GL_APPLE_float_pixels", extStart, extEnd); +#endif /* GL_APPLE_float_pixels */ +#ifdef GL_APPLE_flush_buffer_range + GLEW_APPLE_flush_buffer_range = _glewSearchExtension("GL_APPLE_flush_buffer_range", extStart, extEnd); + if (glewExperimental || GLEW_APPLE_flush_buffer_range) 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_object_purgeable + GLEW_APPLE_object_purgeable = _glewSearchExtension("GL_APPLE_object_purgeable", extStart, extEnd); + if (glewExperimental || GLEW_APPLE_object_purgeable) GLEW_APPLE_object_purgeable = !_glewInit_GL_APPLE_object_purgeable(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_object_purgeable */ +#ifdef GL_APPLE_pixel_buffer + GLEW_APPLE_pixel_buffer = _glewSearchExtension("GL_APPLE_pixel_buffer", extStart, extEnd); +#endif /* GL_APPLE_pixel_buffer */ +#ifdef GL_APPLE_rgb_422 + GLEW_APPLE_rgb_422 = _glewSearchExtension("GL_APPLE_rgb_422", extStart, extEnd); +#endif /* GL_APPLE_rgb_422 */ +#ifdef GL_APPLE_row_bytes + GLEW_APPLE_row_bytes = _glewSearchExtension("GL_APPLE_row_bytes", extStart, extEnd); +#endif /* GL_APPLE_row_bytes */ +#ifdef GL_APPLE_specular_vector + GLEW_APPLE_specular_vector = _glewSearchExtension("GL_APPLE_specular_vector", extStart, extEnd); +#endif /* GL_APPLE_specular_vector */ +#ifdef GL_APPLE_texture_range + GLEW_APPLE_texture_range = _glewSearchExtension("GL_APPLE_texture_range", extStart, extEnd); + if (glewExperimental || GLEW_APPLE_texture_range) GLEW_APPLE_texture_range = !_glewInit_GL_APPLE_texture_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_texture_range */ +#ifdef GL_APPLE_transform_hint + GLEW_APPLE_transform_hint = _glewSearchExtension("GL_APPLE_transform_hint", extStart, extEnd); +#endif /* GL_APPLE_transform_hint */ +#ifdef GL_APPLE_vertex_array_object + GLEW_APPLE_vertex_array_object = _glewSearchExtension("GL_APPLE_vertex_array_object", extStart, extEnd); + if (glewExperimental || GLEW_APPLE_vertex_array_object) 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 + GLEW_APPLE_vertex_array_range = _glewSearchExtension("GL_APPLE_vertex_array_range", extStart, extEnd); + if (glewExperimental || GLEW_APPLE_vertex_array_range) 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_vertex_program_evaluators + GLEW_APPLE_vertex_program_evaluators = _glewSearchExtension("GL_APPLE_vertex_program_evaluators", extStart, extEnd); + if (glewExperimental || GLEW_APPLE_vertex_program_evaluators) GLEW_APPLE_vertex_program_evaluators = !_glewInit_GL_APPLE_vertex_program_evaluators(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_vertex_program_evaluators */ +#ifdef GL_APPLE_ycbcr_422 + GLEW_APPLE_ycbcr_422 = _glewSearchExtension("GL_APPLE_ycbcr_422", extStart, extEnd); +#endif /* GL_APPLE_ycbcr_422 */ +#ifdef GL_ARB_ES2_compatibility + GLEW_ARB_ES2_compatibility = _glewSearchExtension("GL_ARB_ES2_compatibility", extStart, extEnd); + if (glewExperimental || GLEW_ARB_ES2_compatibility) GLEW_ARB_ES2_compatibility = !_glewInit_GL_ARB_ES2_compatibility(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_ES2_compatibility */ +#ifdef GL_ARB_ES3_compatibility + GLEW_ARB_ES3_compatibility = _glewSearchExtension("GL_ARB_ES3_compatibility", extStart, extEnd); +#endif /* GL_ARB_ES3_compatibility */ +#ifdef GL_ARB_arrays_of_arrays + GLEW_ARB_arrays_of_arrays = _glewSearchExtension("GL_ARB_arrays_of_arrays", extStart, extEnd); +#endif /* GL_ARB_arrays_of_arrays */ +#ifdef GL_ARB_base_instance + GLEW_ARB_base_instance = _glewSearchExtension("GL_ARB_base_instance", extStart, extEnd); + if (glewExperimental || GLEW_ARB_base_instance) GLEW_ARB_base_instance = !_glewInit_GL_ARB_base_instance(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_base_instance */ +#ifdef GL_ARB_bindless_texture + GLEW_ARB_bindless_texture = _glewSearchExtension("GL_ARB_bindless_texture", extStart, extEnd); + if (glewExperimental || GLEW_ARB_bindless_texture) GLEW_ARB_bindless_texture = !_glewInit_GL_ARB_bindless_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_bindless_texture */ +#ifdef GL_ARB_blend_func_extended + GLEW_ARB_blend_func_extended = _glewSearchExtension("GL_ARB_blend_func_extended", extStart, extEnd); + if (glewExperimental || GLEW_ARB_blend_func_extended) GLEW_ARB_blend_func_extended = !_glewInit_GL_ARB_blend_func_extended(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_blend_func_extended */ +#ifdef GL_ARB_buffer_storage + GLEW_ARB_buffer_storage = _glewSearchExtension("GL_ARB_buffer_storage", extStart, extEnd); + if (glewExperimental || GLEW_ARB_buffer_storage) GLEW_ARB_buffer_storage = !_glewInit_GL_ARB_buffer_storage(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_buffer_storage */ +#ifdef GL_ARB_cl_event + GLEW_ARB_cl_event = _glewSearchExtension("GL_ARB_cl_event", extStart, extEnd); + if (glewExperimental || GLEW_ARB_cl_event) GLEW_ARB_cl_event = !_glewInit_GL_ARB_cl_event(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_cl_event */ +#ifdef GL_ARB_clear_buffer_object + GLEW_ARB_clear_buffer_object = _glewSearchExtension("GL_ARB_clear_buffer_object", extStart, extEnd); + if (glewExperimental || GLEW_ARB_clear_buffer_object) GLEW_ARB_clear_buffer_object = !_glewInit_GL_ARB_clear_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_clear_buffer_object */ +#ifdef GL_ARB_clear_texture + GLEW_ARB_clear_texture = _glewSearchExtension("GL_ARB_clear_texture", extStart, extEnd); + if (glewExperimental || GLEW_ARB_clear_texture) GLEW_ARB_clear_texture = !_glewInit_GL_ARB_clear_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_clear_texture */ +#ifdef GL_ARB_color_buffer_float + GLEW_ARB_color_buffer_float = _glewSearchExtension("GL_ARB_color_buffer_float", extStart, extEnd); + if (glewExperimental || GLEW_ARB_color_buffer_float) 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_compatibility + GLEW_ARB_compatibility = _glewSearchExtension("GL_ARB_compatibility", extStart, extEnd); +#endif /* GL_ARB_compatibility */ +#ifdef GL_ARB_compressed_texture_pixel_storage + GLEW_ARB_compressed_texture_pixel_storage = _glewSearchExtension("GL_ARB_compressed_texture_pixel_storage", extStart, extEnd); +#endif /* GL_ARB_compressed_texture_pixel_storage */ +#ifdef GL_ARB_compute_shader + GLEW_ARB_compute_shader = _glewSearchExtension("GL_ARB_compute_shader", extStart, extEnd); + if (glewExperimental || GLEW_ARB_compute_shader) GLEW_ARB_compute_shader = !_glewInit_GL_ARB_compute_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_compute_shader */ +#ifdef GL_ARB_compute_variable_group_size + GLEW_ARB_compute_variable_group_size = _glewSearchExtension("GL_ARB_compute_variable_group_size", extStart, extEnd); + if (glewExperimental || GLEW_ARB_compute_variable_group_size) GLEW_ARB_compute_variable_group_size = !_glewInit_GL_ARB_compute_variable_group_size(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_compute_variable_group_size */ +#ifdef GL_ARB_conservative_depth + GLEW_ARB_conservative_depth = _glewSearchExtension("GL_ARB_conservative_depth", extStart, extEnd); +#endif /* GL_ARB_conservative_depth */ +#ifdef GL_ARB_copy_buffer + GLEW_ARB_copy_buffer = _glewSearchExtension("GL_ARB_copy_buffer", extStart, extEnd); + if (glewExperimental || GLEW_ARB_copy_buffer) GLEW_ARB_copy_buffer = !_glewInit_GL_ARB_copy_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_copy_buffer */ +#ifdef GL_ARB_copy_image + GLEW_ARB_copy_image = _glewSearchExtension("GL_ARB_copy_image", extStart, extEnd); + if (glewExperimental || GLEW_ARB_copy_image) GLEW_ARB_copy_image = !_glewInit_GL_ARB_copy_image(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_copy_image */ +#ifdef GL_ARB_debug_output + GLEW_ARB_debug_output = _glewSearchExtension("GL_ARB_debug_output", extStart, extEnd); + if (glewExperimental || GLEW_ARB_debug_output) GLEW_ARB_debug_output = !_glewInit_GL_ARB_debug_output(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_debug_output */ +#ifdef GL_ARB_depth_buffer_float + GLEW_ARB_depth_buffer_float = _glewSearchExtension("GL_ARB_depth_buffer_float", extStart, extEnd); +#endif /* GL_ARB_depth_buffer_float */ +#ifdef GL_ARB_depth_clamp + GLEW_ARB_depth_clamp = _glewSearchExtension("GL_ARB_depth_clamp", extStart, extEnd); +#endif /* GL_ARB_depth_clamp */ +#ifdef GL_ARB_depth_texture + GLEW_ARB_depth_texture = _glewSearchExtension("GL_ARB_depth_texture", extStart, extEnd); +#endif /* GL_ARB_depth_texture */ +#ifdef GL_ARB_draw_buffers + GLEW_ARB_draw_buffers = _glewSearchExtension("GL_ARB_draw_buffers", extStart, extEnd); + if (glewExperimental || GLEW_ARB_draw_buffers) GLEW_ARB_draw_buffers = !_glewInit_GL_ARB_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_buffers */ +#ifdef GL_ARB_draw_buffers_blend + GLEW_ARB_draw_buffers_blend = _glewSearchExtension("GL_ARB_draw_buffers_blend", extStart, extEnd); + if (glewExperimental || GLEW_ARB_draw_buffers_blend) GLEW_ARB_draw_buffers_blend = !_glewInit_GL_ARB_draw_buffers_blend(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_buffers_blend */ +#ifdef GL_ARB_draw_elements_base_vertex + GLEW_ARB_draw_elements_base_vertex = _glewSearchExtension("GL_ARB_draw_elements_base_vertex", extStart, extEnd); + if (glewExperimental || GLEW_ARB_draw_elements_base_vertex) GLEW_ARB_draw_elements_base_vertex = !_glewInit_GL_ARB_draw_elements_base_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_elements_base_vertex */ +#ifdef GL_ARB_draw_indirect + GLEW_ARB_draw_indirect = _glewSearchExtension("GL_ARB_draw_indirect", extStart, extEnd); + if (glewExperimental || GLEW_ARB_draw_indirect) GLEW_ARB_draw_indirect = !_glewInit_GL_ARB_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_indirect */ +#ifdef GL_ARB_draw_instanced + GLEW_ARB_draw_instanced = _glewSearchExtension("GL_ARB_draw_instanced", extStart, extEnd); +#endif /* GL_ARB_draw_instanced */ +#ifdef GL_ARB_enhanced_layouts + GLEW_ARB_enhanced_layouts = _glewSearchExtension("GL_ARB_enhanced_layouts", extStart, extEnd); +#endif /* GL_ARB_enhanced_layouts */ +#ifdef GL_ARB_explicit_attrib_location + GLEW_ARB_explicit_attrib_location = _glewSearchExtension("GL_ARB_explicit_attrib_location", extStart, extEnd); +#endif /* GL_ARB_explicit_attrib_location */ +#ifdef GL_ARB_explicit_uniform_location + GLEW_ARB_explicit_uniform_location = _glewSearchExtension("GL_ARB_explicit_uniform_location", extStart, extEnd); +#endif /* GL_ARB_explicit_uniform_location */ +#ifdef GL_ARB_fragment_coord_conventions + GLEW_ARB_fragment_coord_conventions = _glewSearchExtension("GL_ARB_fragment_coord_conventions", extStart, extEnd); +#endif /* GL_ARB_fragment_coord_conventions */ +#ifdef GL_ARB_fragment_layer_viewport + GLEW_ARB_fragment_layer_viewport = _glewSearchExtension("GL_ARB_fragment_layer_viewport", extStart, extEnd); +#endif /* GL_ARB_fragment_layer_viewport */ +#ifdef GL_ARB_fragment_program + GLEW_ARB_fragment_program = _glewSearchExtension("GL_ARB_fragment_program", extStart, extEnd); +#endif /* GL_ARB_fragment_program */ +#ifdef GL_ARB_fragment_program_shadow + GLEW_ARB_fragment_program_shadow = _glewSearchExtension("GL_ARB_fragment_program_shadow", extStart, extEnd); +#endif /* GL_ARB_fragment_program_shadow */ +#ifdef GL_ARB_fragment_shader + GLEW_ARB_fragment_shader = _glewSearchExtension("GL_ARB_fragment_shader", extStart, extEnd); +#endif /* GL_ARB_fragment_shader */ +#ifdef GL_ARB_framebuffer_no_attachments + GLEW_ARB_framebuffer_no_attachments = _glewSearchExtension("GL_ARB_framebuffer_no_attachments", extStart, extEnd); + if (glewExperimental || GLEW_ARB_framebuffer_no_attachments) GLEW_ARB_framebuffer_no_attachments = !_glewInit_GL_ARB_framebuffer_no_attachments(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_framebuffer_no_attachments */ +#ifdef GL_ARB_framebuffer_object + GLEW_ARB_framebuffer_object = _glewSearchExtension("GL_ARB_framebuffer_object", extStart, extEnd); + if (glewExperimental || GLEW_ARB_framebuffer_object) GLEW_ARB_framebuffer_object = !_glewInit_GL_ARB_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_framebuffer_object */ +#ifdef GL_ARB_framebuffer_sRGB + GLEW_ARB_framebuffer_sRGB = _glewSearchExtension("GL_ARB_framebuffer_sRGB", extStart, extEnd); +#endif /* GL_ARB_framebuffer_sRGB */ +#ifdef GL_ARB_geometry_shader4 + GLEW_ARB_geometry_shader4 = _glewSearchExtension("GL_ARB_geometry_shader4", extStart, extEnd); + if (glewExperimental || GLEW_ARB_geometry_shader4) GLEW_ARB_geometry_shader4 = !_glewInit_GL_ARB_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_geometry_shader4 */ +#ifdef GL_ARB_get_program_binary + GLEW_ARB_get_program_binary = _glewSearchExtension("GL_ARB_get_program_binary", extStart, extEnd); + if (glewExperimental || GLEW_ARB_get_program_binary) GLEW_ARB_get_program_binary = !_glewInit_GL_ARB_get_program_binary(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_get_program_binary */ +#ifdef GL_ARB_gpu_shader5 + GLEW_ARB_gpu_shader5 = _glewSearchExtension("GL_ARB_gpu_shader5", extStart, extEnd); +#endif /* GL_ARB_gpu_shader5 */ +#ifdef GL_ARB_gpu_shader_fp64 + GLEW_ARB_gpu_shader_fp64 = _glewSearchExtension("GL_ARB_gpu_shader_fp64", extStart, extEnd); + if (glewExperimental || GLEW_ARB_gpu_shader_fp64) GLEW_ARB_gpu_shader_fp64 = !_glewInit_GL_ARB_gpu_shader_fp64(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_gpu_shader_fp64 */ +#ifdef GL_ARB_half_float_pixel + GLEW_ARB_half_float_pixel = _glewSearchExtension("GL_ARB_half_float_pixel", extStart, extEnd); +#endif /* GL_ARB_half_float_pixel */ +#ifdef GL_ARB_half_float_vertex + GLEW_ARB_half_float_vertex = _glewSearchExtension("GL_ARB_half_float_vertex", extStart, extEnd); +#endif /* GL_ARB_half_float_vertex */ +#ifdef GL_ARB_imaging + GLEW_ARB_imaging = _glewSearchExtension("GL_ARB_imaging", extStart, extEnd); + if (glewExperimental || GLEW_ARB_imaging) GLEW_ARB_imaging = !_glewInit_GL_ARB_imaging(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_imaging */ +#ifdef GL_ARB_indirect_parameters + GLEW_ARB_indirect_parameters = _glewSearchExtension("GL_ARB_indirect_parameters", extStart, extEnd); + if (glewExperimental || GLEW_ARB_indirect_parameters) GLEW_ARB_indirect_parameters = !_glewInit_GL_ARB_indirect_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_indirect_parameters */ +#ifdef GL_ARB_instanced_arrays + GLEW_ARB_instanced_arrays = _glewSearchExtension("GL_ARB_instanced_arrays", extStart, extEnd); + if (glewExperimental || GLEW_ARB_instanced_arrays) GLEW_ARB_instanced_arrays = !_glewInit_GL_ARB_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_instanced_arrays */ +#ifdef GL_ARB_internalformat_query + GLEW_ARB_internalformat_query = _glewSearchExtension("GL_ARB_internalformat_query", extStart, extEnd); + if (glewExperimental || GLEW_ARB_internalformat_query) GLEW_ARB_internalformat_query = !_glewInit_GL_ARB_internalformat_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_internalformat_query */ +#ifdef GL_ARB_internalformat_query2 + GLEW_ARB_internalformat_query2 = _glewSearchExtension("GL_ARB_internalformat_query2", extStart, extEnd); + if (glewExperimental || GLEW_ARB_internalformat_query2) GLEW_ARB_internalformat_query2 = !_glewInit_GL_ARB_internalformat_query2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_internalformat_query2 */ +#ifdef GL_ARB_invalidate_subdata + GLEW_ARB_invalidate_subdata = _glewSearchExtension("GL_ARB_invalidate_subdata", extStart, extEnd); + if (glewExperimental || GLEW_ARB_invalidate_subdata) GLEW_ARB_invalidate_subdata = !_glewInit_GL_ARB_invalidate_subdata(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_invalidate_subdata */ +#ifdef GL_ARB_map_buffer_alignment + GLEW_ARB_map_buffer_alignment = _glewSearchExtension("GL_ARB_map_buffer_alignment", extStart, extEnd); +#endif /* GL_ARB_map_buffer_alignment */ +#ifdef GL_ARB_map_buffer_range + GLEW_ARB_map_buffer_range = _glewSearchExtension("GL_ARB_map_buffer_range", extStart, extEnd); + if (glewExperimental || GLEW_ARB_map_buffer_range) 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 + GLEW_ARB_matrix_palette = _glewSearchExtension("GL_ARB_matrix_palette", extStart, extEnd); + if (glewExperimental || GLEW_ARB_matrix_palette) GLEW_ARB_matrix_palette = !_glewInit_GL_ARB_matrix_palette(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_matrix_palette */ +#ifdef GL_ARB_multi_bind + GLEW_ARB_multi_bind = _glewSearchExtension("GL_ARB_multi_bind", extStart, extEnd); + if (glewExperimental || GLEW_ARB_multi_bind) GLEW_ARB_multi_bind = !_glewInit_GL_ARB_multi_bind(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multi_bind */ +#ifdef GL_ARB_multi_draw_indirect + GLEW_ARB_multi_draw_indirect = _glewSearchExtension("GL_ARB_multi_draw_indirect", extStart, extEnd); + if (glewExperimental || GLEW_ARB_multi_draw_indirect) GLEW_ARB_multi_draw_indirect = !_glewInit_GL_ARB_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multi_draw_indirect */ +#ifdef GL_ARB_multisample + GLEW_ARB_multisample = _glewSearchExtension("GL_ARB_multisample", extStart, extEnd); + if (glewExperimental || GLEW_ARB_multisample) GLEW_ARB_multisample = !_glewInit_GL_ARB_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multisample */ +#ifdef GL_ARB_multitexture + GLEW_ARB_multitexture = _glewSearchExtension("GL_ARB_multitexture", extStart, extEnd); + if (glewExperimental || GLEW_ARB_multitexture) GLEW_ARB_multitexture = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multitexture */ +#ifdef GL_ARB_occlusion_query + GLEW_ARB_occlusion_query = _glewSearchExtension("GL_ARB_occlusion_query", extStart, extEnd); + if (glewExperimental || GLEW_ARB_occlusion_query) GLEW_ARB_occlusion_query = !_glewInit_GL_ARB_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_occlusion_query */ +#ifdef GL_ARB_occlusion_query2 + GLEW_ARB_occlusion_query2 = _glewSearchExtension("GL_ARB_occlusion_query2", extStart, extEnd); +#endif /* GL_ARB_occlusion_query2 */ +#ifdef GL_ARB_pixel_buffer_object + GLEW_ARB_pixel_buffer_object = _glewSearchExtension("GL_ARB_pixel_buffer_object", extStart, extEnd); +#endif /* GL_ARB_pixel_buffer_object */ +#ifdef GL_ARB_point_parameters + GLEW_ARB_point_parameters = _glewSearchExtension("GL_ARB_point_parameters", extStart, extEnd); + if (glewExperimental || GLEW_ARB_point_parameters) GLEW_ARB_point_parameters = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_point_parameters */ +#ifdef GL_ARB_point_sprite + GLEW_ARB_point_sprite = _glewSearchExtension("GL_ARB_point_sprite", extStart, extEnd); +#endif /* GL_ARB_point_sprite */ +#ifdef GL_ARB_program_interface_query + GLEW_ARB_program_interface_query = _glewSearchExtension("GL_ARB_program_interface_query", extStart, extEnd); + if (glewExperimental || GLEW_ARB_program_interface_query) GLEW_ARB_program_interface_query = !_glewInit_GL_ARB_program_interface_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_program_interface_query */ +#ifdef GL_ARB_provoking_vertex + GLEW_ARB_provoking_vertex = _glewSearchExtension("GL_ARB_provoking_vertex", extStart, extEnd); + if (glewExperimental || GLEW_ARB_provoking_vertex) GLEW_ARB_provoking_vertex = !_glewInit_GL_ARB_provoking_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_provoking_vertex */ +#ifdef GL_ARB_query_buffer_object + GLEW_ARB_query_buffer_object = _glewSearchExtension("GL_ARB_query_buffer_object", extStart, extEnd); +#endif /* GL_ARB_query_buffer_object */ +#ifdef GL_ARB_robust_buffer_access_behavior + GLEW_ARB_robust_buffer_access_behavior = _glewSearchExtension("GL_ARB_robust_buffer_access_behavior", extStart, extEnd); +#endif /* GL_ARB_robust_buffer_access_behavior */ +#ifdef GL_ARB_robustness + GLEW_ARB_robustness = _glewSearchExtension("GL_ARB_robustness", extStart, extEnd); + if (glewExperimental || GLEW_ARB_robustness) GLEW_ARB_robustness = !_glewInit_GL_ARB_robustness(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_robustness */ +#ifdef GL_ARB_robustness_application_isolation + GLEW_ARB_robustness_application_isolation = _glewSearchExtension("GL_ARB_robustness_application_isolation", extStart, extEnd); +#endif /* GL_ARB_robustness_application_isolation */ +#ifdef GL_ARB_robustness_share_group_isolation + GLEW_ARB_robustness_share_group_isolation = _glewSearchExtension("GL_ARB_robustness_share_group_isolation", extStart, extEnd); +#endif /* GL_ARB_robustness_share_group_isolation */ +#ifdef GL_ARB_sample_shading + GLEW_ARB_sample_shading = _glewSearchExtension("GL_ARB_sample_shading", extStart, extEnd); + if (glewExperimental || GLEW_ARB_sample_shading) GLEW_ARB_sample_shading = !_glewInit_GL_ARB_sample_shading(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_sample_shading */ +#ifdef GL_ARB_sampler_objects + GLEW_ARB_sampler_objects = _glewSearchExtension("GL_ARB_sampler_objects", extStart, extEnd); + if (glewExperimental || GLEW_ARB_sampler_objects) GLEW_ARB_sampler_objects = !_glewInit_GL_ARB_sampler_objects(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_sampler_objects */ +#ifdef GL_ARB_seamless_cube_map + GLEW_ARB_seamless_cube_map = _glewSearchExtension("GL_ARB_seamless_cube_map", extStart, extEnd); +#endif /* GL_ARB_seamless_cube_map */ +#ifdef GL_ARB_seamless_cubemap_per_texture + GLEW_ARB_seamless_cubemap_per_texture = _glewSearchExtension("GL_ARB_seamless_cubemap_per_texture", extStart, extEnd); +#endif /* GL_ARB_seamless_cubemap_per_texture */ +#ifdef GL_ARB_separate_shader_objects + GLEW_ARB_separate_shader_objects = _glewSearchExtension("GL_ARB_separate_shader_objects", extStart, extEnd); + if (glewExperimental || GLEW_ARB_separate_shader_objects) GLEW_ARB_separate_shader_objects = !_glewInit_GL_ARB_separate_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_separate_shader_objects */ +#ifdef GL_ARB_shader_atomic_counters + GLEW_ARB_shader_atomic_counters = _glewSearchExtension("GL_ARB_shader_atomic_counters", extStart, extEnd); + if (glewExperimental || GLEW_ARB_shader_atomic_counters) GLEW_ARB_shader_atomic_counters = !_glewInit_GL_ARB_shader_atomic_counters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shader_atomic_counters */ +#ifdef GL_ARB_shader_bit_encoding + GLEW_ARB_shader_bit_encoding = _glewSearchExtension("GL_ARB_shader_bit_encoding", extStart, extEnd); +#endif /* GL_ARB_shader_bit_encoding */ +#ifdef GL_ARB_shader_draw_parameters + GLEW_ARB_shader_draw_parameters = _glewSearchExtension("GL_ARB_shader_draw_parameters", extStart, extEnd); +#endif /* GL_ARB_shader_draw_parameters */ +#ifdef GL_ARB_shader_group_vote + GLEW_ARB_shader_group_vote = _glewSearchExtension("GL_ARB_shader_group_vote", extStart, extEnd); +#endif /* GL_ARB_shader_group_vote */ +#ifdef GL_ARB_shader_image_load_store + GLEW_ARB_shader_image_load_store = _glewSearchExtension("GL_ARB_shader_image_load_store", extStart, extEnd); + if (glewExperimental || GLEW_ARB_shader_image_load_store) GLEW_ARB_shader_image_load_store = !_glewInit_GL_ARB_shader_image_load_store(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shader_image_load_store */ +#ifdef GL_ARB_shader_image_size + GLEW_ARB_shader_image_size = _glewSearchExtension("GL_ARB_shader_image_size", extStart, extEnd); +#endif /* GL_ARB_shader_image_size */ +#ifdef GL_ARB_shader_objects + GLEW_ARB_shader_objects = _glewSearchExtension("GL_ARB_shader_objects", extStart, extEnd); + if (glewExperimental || GLEW_ARB_shader_objects) GLEW_ARB_shader_objects = !_glewInit_GL_ARB_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shader_objects */ +#ifdef GL_ARB_shader_precision + GLEW_ARB_shader_precision = _glewSearchExtension("GL_ARB_shader_precision", extStart, extEnd); +#endif /* GL_ARB_shader_precision */ +#ifdef GL_ARB_shader_stencil_export + GLEW_ARB_shader_stencil_export = _glewSearchExtension("GL_ARB_shader_stencil_export", extStart, extEnd); +#endif /* GL_ARB_shader_stencil_export */ +#ifdef GL_ARB_shader_storage_buffer_object + GLEW_ARB_shader_storage_buffer_object = _glewSearchExtension("GL_ARB_shader_storage_buffer_object", extStart, extEnd); + if (glewExperimental || GLEW_ARB_shader_storage_buffer_object) GLEW_ARB_shader_storage_buffer_object = !_glewInit_GL_ARB_shader_storage_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shader_storage_buffer_object */ +#ifdef GL_ARB_shader_subroutine + GLEW_ARB_shader_subroutine = _glewSearchExtension("GL_ARB_shader_subroutine", extStart, extEnd); + if (glewExperimental || GLEW_ARB_shader_subroutine) GLEW_ARB_shader_subroutine = !_glewInit_GL_ARB_shader_subroutine(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shader_subroutine */ +#ifdef GL_ARB_shader_texture_lod + GLEW_ARB_shader_texture_lod = _glewSearchExtension("GL_ARB_shader_texture_lod", extStart, extEnd); +#endif /* GL_ARB_shader_texture_lod */ +#ifdef GL_ARB_shading_language_100 + GLEW_ARB_shading_language_100 = _glewSearchExtension("GL_ARB_shading_language_100", extStart, extEnd); +#endif /* GL_ARB_shading_language_100 */ +#ifdef GL_ARB_shading_language_420pack + GLEW_ARB_shading_language_420pack = _glewSearchExtension("GL_ARB_shading_language_420pack", extStart, extEnd); +#endif /* GL_ARB_shading_language_420pack */ +#ifdef GL_ARB_shading_language_include + GLEW_ARB_shading_language_include = _glewSearchExtension("GL_ARB_shading_language_include", extStart, extEnd); + if (glewExperimental || GLEW_ARB_shading_language_include) GLEW_ARB_shading_language_include = !_glewInit_GL_ARB_shading_language_include(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shading_language_include */ +#ifdef GL_ARB_shading_language_packing + GLEW_ARB_shading_language_packing = _glewSearchExtension("GL_ARB_shading_language_packing", extStart, extEnd); +#endif /* GL_ARB_shading_language_packing */ +#ifdef GL_ARB_shadow + GLEW_ARB_shadow = _glewSearchExtension("GL_ARB_shadow", extStart, extEnd); +#endif /* GL_ARB_shadow */ +#ifdef GL_ARB_shadow_ambient + GLEW_ARB_shadow_ambient = _glewSearchExtension("GL_ARB_shadow_ambient", extStart, extEnd); +#endif /* GL_ARB_shadow_ambient */ +#ifdef GL_ARB_sparse_texture + GLEW_ARB_sparse_texture = _glewSearchExtension("GL_ARB_sparse_texture", extStart, extEnd); + if (glewExperimental || GLEW_ARB_sparse_texture) GLEW_ARB_sparse_texture = !_glewInit_GL_ARB_sparse_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_sparse_texture */ +#ifdef GL_ARB_stencil_texturing + GLEW_ARB_stencil_texturing = _glewSearchExtension("GL_ARB_stencil_texturing", extStart, extEnd); +#endif /* GL_ARB_stencil_texturing */ +#ifdef GL_ARB_sync + GLEW_ARB_sync = _glewSearchExtension("GL_ARB_sync", extStart, extEnd); + if (glewExperimental || GLEW_ARB_sync) GLEW_ARB_sync = !_glewInit_GL_ARB_sync(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_sync */ +#ifdef GL_ARB_tessellation_shader + GLEW_ARB_tessellation_shader = _glewSearchExtension("GL_ARB_tessellation_shader", extStart, extEnd); + if (glewExperimental || GLEW_ARB_tessellation_shader) GLEW_ARB_tessellation_shader = !_glewInit_GL_ARB_tessellation_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_tessellation_shader */ +#ifdef GL_ARB_texture_border_clamp + GLEW_ARB_texture_border_clamp = _glewSearchExtension("GL_ARB_texture_border_clamp", extStart, extEnd); +#endif /* GL_ARB_texture_border_clamp */ +#ifdef GL_ARB_texture_buffer_object + GLEW_ARB_texture_buffer_object = _glewSearchExtension("GL_ARB_texture_buffer_object", extStart, extEnd); + if (glewExperimental || GLEW_ARB_texture_buffer_object) 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_buffer_object_rgb32 + GLEW_ARB_texture_buffer_object_rgb32 = _glewSearchExtension("GL_ARB_texture_buffer_object_rgb32", extStart, extEnd); +#endif /* GL_ARB_texture_buffer_object_rgb32 */ +#ifdef GL_ARB_texture_buffer_range + GLEW_ARB_texture_buffer_range = _glewSearchExtension("GL_ARB_texture_buffer_range", extStart, extEnd); + if (glewExperimental || GLEW_ARB_texture_buffer_range) GLEW_ARB_texture_buffer_range = !_glewInit_GL_ARB_texture_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_buffer_range */ +#ifdef GL_ARB_texture_compression + GLEW_ARB_texture_compression = _glewSearchExtension("GL_ARB_texture_compression", extStart, extEnd); + if (glewExperimental || GLEW_ARB_texture_compression) GLEW_ARB_texture_compression = !_glewInit_GL_ARB_texture_compression(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_compression */ +#ifdef GL_ARB_texture_compression_bptc + GLEW_ARB_texture_compression_bptc = _glewSearchExtension("GL_ARB_texture_compression_bptc", extStart, extEnd); +#endif /* GL_ARB_texture_compression_bptc */ +#ifdef GL_ARB_texture_compression_rgtc + GLEW_ARB_texture_compression_rgtc = _glewSearchExtension("GL_ARB_texture_compression_rgtc", extStart, extEnd); +#endif /* GL_ARB_texture_compression_rgtc */ +#ifdef GL_ARB_texture_cube_map + GLEW_ARB_texture_cube_map = _glewSearchExtension("GL_ARB_texture_cube_map", extStart, extEnd); +#endif /* GL_ARB_texture_cube_map */ +#ifdef GL_ARB_texture_cube_map_array + GLEW_ARB_texture_cube_map_array = _glewSearchExtension("GL_ARB_texture_cube_map_array", extStart, extEnd); +#endif /* GL_ARB_texture_cube_map_array */ +#ifdef GL_ARB_texture_env_add + GLEW_ARB_texture_env_add = _glewSearchExtension("GL_ARB_texture_env_add", extStart, extEnd); +#endif /* GL_ARB_texture_env_add */ +#ifdef GL_ARB_texture_env_combine + GLEW_ARB_texture_env_combine = _glewSearchExtension("GL_ARB_texture_env_combine", extStart, extEnd); +#endif /* GL_ARB_texture_env_combine */ +#ifdef GL_ARB_texture_env_crossbar + GLEW_ARB_texture_env_crossbar = _glewSearchExtension("GL_ARB_texture_env_crossbar", extStart, extEnd); +#endif /* GL_ARB_texture_env_crossbar */ +#ifdef GL_ARB_texture_env_dot3 + GLEW_ARB_texture_env_dot3 = _glewSearchExtension("GL_ARB_texture_env_dot3", extStart, extEnd); +#endif /* GL_ARB_texture_env_dot3 */ +#ifdef GL_ARB_texture_float + GLEW_ARB_texture_float = _glewSearchExtension("GL_ARB_texture_float", extStart, extEnd); +#endif /* GL_ARB_texture_float */ +#ifdef GL_ARB_texture_gather + GLEW_ARB_texture_gather = _glewSearchExtension("GL_ARB_texture_gather", extStart, extEnd); +#endif /* GL_ARB_texture_gather */ +#ifdef GL_ARB_texture_mirror_clamp_to_edge + GLEW_ARB_texture_mirror_clamp_to_edge = _glewSearchExtension("GL_ARB_texture_mirror_clamp_to_edge", extStart, extEnd); +#endif /* GL_ARB_texture_mirror_clamp_to_edge */ +#ifdef GL_ARB_texture_mirrored_repeat + GLEW_ARB_texture_mirrored_repeat = _glewSearchExtension("GL_ARB_texture_mirrored_repeat", extStart, extEnd); +#endif /* GL_ARB_texture_mirrored_repeat */ +#ifdef GL_ARB_texture_multisample + GLEW_ARB_texture_multisample = _glewSearchExtension("GL_ARB_texture_multisample", extStart, extEnd); + if (glewExperimental || GLEW_ARB_texture_multisample) GLEW_ARB_texture_multisample = !_glewInit_GL_ARB_texture_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_multisample */ +#ifdef GL_ARB_texture_non_power_of_two + GLEW_ARB_texture_non_power_of_two = _glewSearchExtension("GL_ARB_texture_non_power_of_two", extStart, extEnd); +#endif /* GL_ARB_texture_non_power_of_two */ +#ifdef GL_ARB_texture_query_levels + GLEW_ARB_texture_query_levels = _glewSearchExtension("GL_ARB_texture_query_levels", extStart, extEnd); +#endif /* GL_ARB_texture_query_levels */ +#ifdef GL_ARB_texture_query_lod + GLEW_ARB_texture_query_lod = _glewSearchExtension("GL_ARB_texture_query_lod", extStart, extEnd); +#endif /* GL_ARB_texture_query_lod */ +#ifdef GL_ARB_texture_rectangle + GLEW_ARB_texture_rectangle = _glewSearchExtension("GL_ARB_texture_rectangle", extStart, extEnd); +#endif /* GL_ARB_texture_rectangle */ +#ifdef GL_ARB_texture_rg + GLEW_ARB_texture_rg = _glewSearchExtension("GL_ARB_texture_rg", extStart, extEnd); +#endif /* GL_ARB_texture_rg */ +#ifdef GL_ARB_texture_rgb10_a2ui + GLEW_ARB_texture_rgb10_a2ui = _glewSearchExtension("GL_ARB_texture_rgb10_a2ui", extStart, extEnd); +#endif /* GL_ARB_texture_rgb10_a2ui */ +#ifdef GL_ARB_texture_stencil8 + GLEW_ARB_texture_stencil8 = _glewSearchExtension("GL_ARB_texture_stencil8", extStart, extEnd); +#endif /* GL_ARB_texture_stencil8 */ +#ifdef GL_ARB_texture_storage + GLEW_ARB_texture_storage = _glewSearchExtension("GL_ARB_texture_storage", extStart, extEnd); + if (glewExperimental || GLEW_ARB_texture_storage) GLEW_ARB_texture_storage = !_glewInit_GL_ARB_texture_storage(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_storage */ +#ifdef GL_ARB_texture_storage_multisample + GLEW_ARB_texture_storage_multisample = _glewSearchExtension("GL_ARB_texture_storage_multisample", extStart, extEnd); + if (glewExperimental || GLEW_ARB_texture_storage_multisample) GLEW_ARB_texture_storage_multisample = !_glewInit_GL_ARB_texture_storage_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_storage_multisample */ +#ifdef GL_ARB_texture_swizzle + GLEW_ARB_texture_swizzle = _glewSearchExtension("GL_ARB_texture_swizzle", extStart, extEnd); +#endif /* GL_ARB_texture_swizzle */ +#ifdef GL_ARB_texture_view + GLEW_ARB_texture_view = _glewSearchExtension("GL_ARB_texture_view", extStart, extEnd); + if (glewExperimental || GLEW_ARB_texture_view) GLEW_ARB_texture_view = !_glewInit_GL_ARB_texture_view(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_view */ +#ifdef GL_ARB_timer_query + GLEW_ARB_timer_query = _glewSearchExtension("GL_ARB_timer_query", extStart, extEnd); + if (glewExperimental || GLEW_ARB_timer_query) GLEW_ARB_timer_query = !_glewInit_GL_ARB_timer_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_timer_query */ +#ifdef GL_ARB_transform_feedback2 + GLEW_ARB_transform_feedback2 = _glewSearchExtension("GL_ARB_transform_feedback2", extStart, extEnd); + if (glewExperimental || GLEW_ARB_transform_feedback2) GLEW_ARB_transform_feedback2 = !_glewInit_GL_ARB_transform_feedback2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_transform_feedback2 */ +#ifdef GL_ARB_transform_feedback3 + GLEW_ARB_transform_feedback3 = _glewSearchExtension("GL_ARB_transform_feedback3", extStart, extEnd); + if (glewExperimental || GLEW_ARB_transform_feedback3) GLEW_ARB_transform_feedback3 = !_glewInit_GL_ARB_transform_feedback3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_transform_feedback3 */ +#ifdef GL_ARB_transform_feedback_instanced + GLEW_ARB_transform_feedback_instanced = _glewSearchExtension("GL_ARB_transform_feedback_instanced", extStart, extEnd); + if (glewExperimental || GLEW_ARB_transform_feedback_instanced) GLEW_ARB_transform_feedback_instanced = !_glewInit_GL_ARB_transform_feedback_instanced(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_transform_feedback_instanced */ +#ifdef GL_ARB_transpose_matrix + GLEW_ARB_transpose_matrix = _glewSearchExtension("GL_ARB_transpose_matrix", extStart, extEnd); + if (glewExperimental || GLEW_ARB_transpose_matrix) GLEW_ARB_transpose_matrix = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_transpose_matrix */ +#ifdef GL_ARB_uniform_buffer_object + GLEW_ARB_uniform_buffer_object = _glewSearchExtension("GL_ARB_uniform_buffer_object", extStart, extEnd); + if (glewExperimental || GLEW_ARB_uniform_buffer_object) GLEW_ARB_uniform_buffer_object = !_glewInit_GL_ARB_uniform_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_uniform_buffer_object */ +#ifdef GL_ARB_vertex_array_bgra + GLEW_ARB_vertex_array_bgra = _glewSearchExtension("GL_ARB_vertex_array_bgra", extStart, extEnd); +#endif /* GL_ARB_vertex_array_bgra */ +#ifdef GL_ARB_vertex_array_object + GLEW_ARB_vertex_array_object = _glewSearchExtension("GL_ARB_vertex_array_object", extStart, extEnd); + if (glewExperimental || GLEW_ARB_vertex_array_object) 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_attrib_64bit + GLEW_ARB_vertex_attrib_64bit = _glewSearchExtension("GL_ARB_vertex_attrib_64bit", extStart, extEnd); + if (glewExperimental || GLEW_ARB_vertex_attrib_64bit) GLEW_ARB_vertex_attrib_64bit = !_glewInit_GL_ARB_vertex_attrib_64bit(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_attrib_64bit */ +#ifdef GL_ARB_vertex_attrib_binding + GLEW_ARB_vertex_attrib_binding = _glewSearchExtension("GL_ARB_vertex_attrib_binding", extStart, extEnd); + if (glewExperimental || GLEW_ARB_vertex_attrib_binding) GLEW_ARB_vertex_attrib_binding = !_glewInit_GL_ARB_vertex_attrib_binding(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_attrib_binding */ +#ifdef GL_ARB_vertex_blend + GLEW_ARB_vertex_blend = _glewSearchExtension("GL_ARB_vertex_blend", extStart, extEnd); + if (glewExperimental || GLEW_ARB_vertex_blend) 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 + GLEW_ARB_vertex_buffer_object = _glewSearchExtension("GL_ARB_vertex_buffer_object", extStart, extEnd); + if (glewExperimental || GLEW_ARB_vertex_buffer_object) 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 + GLEW_ARB_vertex_program = _glewSearchExtension("GL_ARB_vertex_program", extStart, extEnd); + if (glewExperimental || GLEW_ARB_vertex_program) GLEW_ARB_vertex_program = !_glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_program */ +#ifdef GL_ARB_vertex_shader + GLEW_ARB_vertex_shader = _glewSearchExtension("GL_ARB_vertex_shader", extStart, extEnd); + if (glewExperimental || GLEW_ARB_vertex_shader) { GLEW_ARB_vertex_shader = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); _glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); } +#endif /* GL_ARB_vertex_shader */ +#ifdef GL_ARB_vertex_type_10f_11f_11f_rev + GLEW_ARB_vertex_type_10f_11f_11f_rev = _glewSearchExtension("GL_ARB_vertex_type_10f_11f_11f_rev", extStart, extEnd); +#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ +#ifdef GL_ARB_vertex_type_2_10_10_10_rev + GLEW_ARB_vertex_type_2_10_10_10_rev = _glewSearchExtension("GL_ARB_vertex_type_2_10_10_10_rev", extStart, extEnd); + if (glewExperimental || GLEW_ARB_vertex_type_2_10_10_10_rev) GLEW_ARB_vertex_type_2_10_10_10_rev = !_glewInit_GL_ARB_vertex_type_2_10_10_10_rev(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ +#ifdef GL_ARB_viewport_array + GLEW_ARB_viewport_array = _glewSearchExtension("GL_ARB_viewport_array", extStart, extEnd); + if (glewExperimental || GLEW_ARB_viewport_array) GLEW_ARB_viewport_array = !_glewInit_GL_ARB_viewport_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_viewport_array */ +#ifdef GL_ARB_window_pos + GLEW_ARB_window_pos = _glewSearchExtension("GL_ARB_window_pos", extStart, extEnd); + if (glewExperimental || GLEW_ARB_window_pos) GLEW_ARB_window_pos = !_glewInit_GL_ARB_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_window_pos */ +#ifdef GL_ATIX_point_sprites + GLEW_ATIX_point_sprites = _glewSearchExtension("GL_ATIX_point_sprites", extStart, extEnd); +#endif /* GL_ATIX_point_sprites */ +#ifdef GL_ATIX_texture_env_combine3 + GLEW_ATIX_texture_env_combine3 = _glewSearchExtension("GL_ATIX_texture_env_combine3", extStart, extEnd); +#endif /* GL_ATIX_texture_env_combine3 */ +#ifdef GL_ATIX_texture_env_route + GLEW_ATIX_texture_env_route = _glewSearchExtension("GL_ATIX_texture_env_route", extStart, extEnd); +#endif /* GL_ATIX_texture_env_route */ +#ifdef GL_ATIX_vertex_shader_output_point_size + GLEW_ATIX_vertex_shader_output_point_size = _glewSearchExtension("GL_ATIX_vertex_shader_output_point_size", extStart, extEnd); +#endif /* GL_ATIX_vertex_shader_output_point_size */ +#ifdef GL_ATI_draw_buffers + GLEW_ATI_draw_buffers = _glewSearchExtension("GL_ATI_draw_buffers", extStart, extEnd); + if (glewExperimental || GLEW_ATI_draw_buffers) GLEW_ATI_draw_buffers = !_glewInit_GL_ATI_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_draw_buffers */ +#ifdef GL_ATI_element_array + GLEW_ATI_element_array = _glewSearchExtension("GL_ATI_element_array", extStart, extEnd); + if (glewExperimental || GLEW_ATI_element_array) GLEW_ATI_element_array = !_glewInit_GL_ATI_element_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_element_array */ +#ifdef GL_ATI_envmap_bumpmap + GLEW_ATI_envmap_bumpmap = _glewSearchExtension("GL_ATI_envmap_bumpmap", extStart, extEnd); + if (glewExperimental || GLEW_ATI_envmap_bumpmap) GLEW_ATI_envmap_bumpmap = !_glewInit_GL_ATI_envmap_bumpmap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_envmap_bumpmap */ +#ifdef GL_ATI_fragment_shader + GLEW_ATI_fragment_shader = _glewSearchExtension("GL_ATI_fragment_shader", extStart, extEnd); + if (glewExperimental || GLEW_ATI_fragment_shader) 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 + GLEW_ATI_map_object_buffer = _glewSearchExtension("GL_ATI_map_object_buffer", extStart, extEnd); + if (glewExperimental || GLEW_ATI_map_object_buffer) 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_meminfo + GLEW_ATI_meminfo = _glewSearchExtension("GL_ATI_meminfo", extStart, extEnd); +#endif /* GL_ATI_meminfo */ +#ifdef GL_ATI_pn_triangles + GLEW_ATI_pn_triangles = _glewSearchExtension("GL_ATI_pn_triangles", extStart, extEnd); + if (glewExperimental || GLEW_ATI_pn_triangles) GLEW_ATI_pn_triangles = !_glewInit_GL_ATI_pn_triangles(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_pn_triangles */ +#ifdef GL_ATI_separate_stencil + GLEW_ATI_separate_stencil = _glewSearchExtension("GL_ATI_separate_stencil", extStart, extEnd); + if (glewExperimental || GLEW_ATI_separate_stencil) 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 + GLEW_ATI_shader_texture_lod = _glewSearchExtension("GL_ATI_shader_texture_lod", extStart, extEnd); +#endif /* GL_ATI_shader_texture_lod */ +#ifdef GL_ATI_text_fragment_shader + GLEW_ATI_text_fragment_shader = _glewSearchExtension("GL_ATI_text_fragment_shader", extStart, extEnd); +#endif /* GL_ATI_text_fragment_shader */ +#ifdef GL_ATI_texture_compression_3dc + GLEW_ATI_texture_compression_3dc = _glewSearchExtension("GL_ATI_texture_compression_3dc", extStart, extEnd); +#endif /* GL_ATI_texture_compression_3dc */ +#ifdef GL_ATI_texture_env_combine3 + GLEW_ATI_texture_env_combine3 = _glewSearchExtension("GL_ATI_texture_env_combine3", extStart, extEnd); +#endif /* GL_ATI_texture_env_combine3 */ +#ifdef GL_ATI_texture_float + GLEW_ATI_texture_float = _glewSearchExtension("GL_ATI_texture_float", extStart, extEnd); +#endif /* GL_ATI_texture_float */ +#ifdef GL_ATI_texture_mirror_once + GLEW_ATI_texture_mirror_once = _glewSearchExtension("GL_ATI_texture_mirror_once", extStart, extEnd); +#endif /* GL_ATI_texture_mirror_once */ +#ifdef GL_ATI_vertex_array_object + GLEW_ATI_vertex_array_object = _glewSearchExtension("GL_ATI_vertex_array_object", extStart, extEnd); + if (glewExperimental || GLEW_ATI_vertex_array_object) 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 + GLEW_ATI_vertex_attrib_array_object = _glewSearchExtension("GL_ATI_vertex_attrib_array_object", extStart, extEnd); + if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) 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 + GLEW_ATI_vertex_streams = _glewSearchExtension("GL_ATI_vertex_streams", extStart, extEnd); + if (glewExperimental || GLEW_ATI_vertex_streams) GLEW_ATI_vertex_streams = !_glewInit_GL_ATI_vertex_streams(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_streams */ +#ifdef GL_EXT_422_pixels + GLEW_EXT_422_pixels = _glewSearchExtension("GL_EXT_422_pixels", extStart, extEnd); +#endif /* GL_EXT_422_pixels */ +#ifdef GL_EXT_Cg_shader + GLEW_EXT_Cg_shader = _glewSearchExtension("GL_EXT_Cg_shader", extStart, extEnd); +#endif /* GL_EXT_Cg_shader */ +#ifdef GL_EXT_abgr + GLEW_EXT_abgr = _glewSearchExtension("GL_EXT_abgr", extStart, extEnd); +#endif /* GL_EXT_abgr */ +#ifdef GL_EXT_bgra + GLEW_EXT_bgra = _glewSearchExtension("GL_EXT_bgra", extStart, extEnd); +#endif /* GL_EXT_bgra */ +#ifdef GL_EXT_bindable_uniform + GLEW_EXT_bindable_uniform = _glewSearchExtension("GL_EXT_bindable_uniform", extStart, extEnd); + if (glewExperimental || GLEW_EXT_bindable_uniform) GLEW_EXT_bindable_uniform = !_glewInit_GL_EXT_bindable_uniform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_bindable_uniform */ +#ifdef GL_EXT_blend_color + GLEW_EXT_blend_color = _glewSearchExtension("GL_EXT_blend_color", extStart, extEnd); + if (glewExperimental || GLEW_EXT_blend_color) 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 + GLEW_EXT_blend_equation_separate = _glewSearchExtension("GL_EXT_blend_equation_separate", extStart, extEnd); + if (glewExperimental || GLEW_EXT_blend_equation_separate) 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 + GLEW_EXT_blend_func_separate = _glewSearchExtension("GL_EXT_blend_func_separate", extStart, extEnd); + if (glewExperimental || GLEW_EXT_blend_func_separate) 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 + GLEW_EXT_blend_logic_op = _glewSearchExtension("GL_EXT_blend_logic_op", extStart, extEnd); +#endif /* GL_EXT_blend_logic_op */ +#ifdef GL_EXT_blend_minmax + GLEW_EXT_blend_minmax = _glewSearchExtension("GL_EXT_blend_minmax", extStart, extEnd); + if (glewExperimental || GLEW_EXT_blend_minmax) GLEW_EXT_blend_minmax = !_glewInit_GL_EXT_blend_minmax(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_minmax */ +#ifdef GL_EXT_blend_subtract + GLEW_EXT_blend_subtract = _glewSearchExtension("GL_EXT_blend_subtract", extStart, extEnd); +#endif /* GL_EXT_blend_subtract */ +#ifdef GL_EXT_clip_volume_hint + GLEW_EXT_clip_volume_hint = _glewSearchExtension("GL_EXT_clip_volume_hint", extStart, extEnd); +#endif /* GL_EXT_clip_volume_hint */ +#ifdef GL_EXT_cmyka + GLEW_EXT_cmyka = _glewSearchExtension("GL_EXT_cmyka", extStart, extEnd); +#endif /* GL_EXT_cmyka */ +#ifdef GL_EXT_color_subtable + GLEW_EXT_color_subtable = _glewSearchExtension("GL_EXT_color_subtable", extStart, extEnd); + if (glewExperimental || GLEW_EXT_color_subtable) 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 + GLEW_EXT_compiled_vertex_array = _glewSearchExtension("GL_EXT_compiled_vertex_array", extStart, extEnd); + if (glewExperimental || GLEW_EXT_compiled_vertex_array) 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 + GLEW_EXT_convolution = _glewSearchExtension("GL_EXT_convolution", extStart, extEnd); + if (glewExperimental || GLEW_EXT_convolution) GLEW_EXT_convolution = !_glewInit_GL_EXT_convolution(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_convolution */ +#ifdef GL_EXT_coordinate_frame + GLEW_EXT_coordinate_frame = _glewSearchExtension("GL_EXT_coordinate_frame", extStart, extEnd); + if (glewExperimental || GLEW_EXT_coordinate_frame) GLEW_EXT_coordinate_frame = !_glewInit_GL_EXT_coordinate_frame(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_coordinate_frame */ +#ifdef GL_EXT_copy_texture + GLEW_EXT_copy_texture = _glewSearchExtension("GL_EXT_copy_texture", extStart, extEnd); + if (glewExperimental || GLEW_EXT_copy_texture) GLEW_EXT_copy_texture = !_glewInit_GL_EXT_copy_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_copy_texture */ +#ifdef GL_EXT_cull_vertex + GLEW_EXT_cull_vertex = _glewSearchExtension("GL_EXT_cull_vertex", extStart, extEnd); + if (glewExperimental || GLEW_EXT_cull_vertex) GLEW_EXT_cull_vertex = !_glewInit_GL_EXT_cull_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_cull_vertex */ +#ifdef GL_EXT_debug_label + GLEW_EXT_debug_label = _glewSearchExtension("GL_EXT_debug_label", extStart, extEnd); + if (glewExperimental || GLEW_EXT_debug_label) GLEW_EXT_debug_label = !_glewInit_GL_EXT_debug_label(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_debug_label */ +#ifdef GL_EXT_debug_marker + GLEW_EXT_debug_marker = _glewSearchExtension("GL_EXT_debug_marker", extStart, extEnd); + if (glewExperimental || GLEW_EXT_debug_marker) GLEW_EXT_debug_marker = !_glewInit_GL_EXT_debug_marker(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_debug_marker */ +#ifdef GL_EXT_depth_bounds_test + GLEW_EXT_depth_bounds_test = _glewSearchExtension("GL_EXT_depth_bounds_test", extStart, extEnd); + if (glewExperimental || GLEW_EXT_depth_bounds_test) 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 + GLEW_EXT_direct_state_access = _glewSearchExtension("GL_EXT_direct_state_access", extStart, extEnd); + if (glewExperimental || GLEW_EXT_direct_state_access) 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 + GLEW_EXT_draw_buffers2 = _glewSearchExtension("GL_EXT_draw_buffers2", extStart, extEnd); + if (glewExperimental || GLEW_EXT_draw_buffers2) GLEW_EXT_draw_buffers2 = !_glewInit_GL_EXT_draw_buffers2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_draw_buffers2 */ +#ifdef GL_EXT_draw_instanced + GLEW_EXT_draw_instanced = _glewSearchExtension("GL_EXT_draw_instanced", extStart, extEnd); + if (glewExperimental || GLEW_EXT_draw_instanced) 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 + GLEW_EXT_draw_range_elements = _glewSearchExtension("GL_EXT_draw_range_elements", extStart, extEnd); + if (glewExperimental || GLEW_EXT_draw_range_elements) 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 + GLEW_EXT_fog_coord = _glewSearchExtension("GL_EXT_fog_coord", extStart, extEnd); + if (glewExperimental || GLEW_EXT_fog_coord) GLEW_EXT_fog_coord = !_glewInit_GL_EXT_fog_coord(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_fog_coord */ +#ifdef GL_EXT_fragment_lighting + GLEW_EXT_fragment_lighting = _glewSearchExtension("GL_EXT_fragment_lighting", extStart, extEnd); + if (glewExperimental || GLEW_EXT_fragment_lighting) GLEW_EXT_fragment_lighting = !_glewInit_GL_EXT_fragment_lighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_fragment_lighting */ +#ifdef GL_EXT_framebuffer_blit + GLEW_EXT_framebuffer_blit = _glewSearchExtension("GL_EXT_framebuffer_blit", extStart, extEnd); + if (glewExperimental || GLEW_EXT_framebuffer_blit) GLEW_EXT_framebuffer_blit = !_glewInit_GL_EXT_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_blit */ +#ifdef GL_EXT_framebuffer_multisample + GLEW_EXT_framebuffer_multisample = _glewSearchExtension("GL_EXT_framebuffer_multisample", extStart, extEnd); + if (glewExperimental || GLEW_EXT_framebuffer_multisample) GLEW_EXT_framebuffer_multisample = !_glewInit_GL_EXT_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_multisample */ +#ifdef GL_EXT_framebuffer_multisample_blit_scaled + GLEW_EXT_framebuffer_multisample_blit_scaled = _glewSearchExtension("GL_EXT_framebuffer_multisample_blit_scaled", extStart, extEnd); +#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ +#ifdef GL_EXT_framebuffer_object + GLEW_EXT_framebuffer_object = _glewSearchExtension("GL_EXT_framebuffer_object", extStart, extEnd); + if (glewExperimental || GLEW_EXT_framebuffer_object) GLEW_EXT_framebuffer_object = !_glewInit_GL_EXT_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_object */ +#ifdef GL_EXT_framebuffer_sRGB + GLEW_EXT_framebuffer_sRGB = _glewSearchExtension("GL_EXT_framebuffer_sRGB", extStart, extEnd); +#endif /* GL_EXT_framebuffer_sRGB */ +#ifdef GL_EXT_geometry_shader4 + GLEW_EXT_geometry_shader4 = _glewSearchExtension("GL_EXT_geometry_shader4", extStart, extEnd); + if (glewExperimental || GLEW_EXT_geometry_shader4) 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 + GLEW_EXT_gpu_program_parameters = _glewSearchExtension("GL_EXT_gpu_program_parameters", extStart, extEnd); + if (glewExperimental || GLEW_EXT_gpu_program_parameters) 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 + GLEW_EXT_gpu_shader4 = _glewSearchExtension("GL_EXT_gpu_shader4", extStart, extEnd); + if (glewExperimental || GLEW_EXT_gpu_shader4) GLEW_EXT_gpu_shader4 = !_glewInit_GL_EXT_gpu_shader4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_gpu_shader4 */ +#ifdef GL_EXT_histogram + GLEW_EXT_histogram = _glewSearchExtension("GL_EXT_histogram", extStart, extEnd); + if (glewExperimental || GLEW_EXT_histogram) GLEW_EXT_histogram = !_glewInit_GL_EXT_histogram(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_histogram */ +#ifdef GL_EXT_index_array_formats + GLEW_EXT_index_array_formats = _glewSearchExtension("GL_EXT_index_array_formats", extStart, extEnd); +#endif /* GL_EXT_index_array_formats */ +#ifdef GL_EXT_index_func + GLEW_EXT_index_func = _glewSearchExtension("GL_EXT_index_func", extStart, extEnd); + if (glewExperimental || GLEW_EXT_index_func) GLEW_EXT_index_func = !_glewInit_GL_EXT_index_func(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_index_func */ +#ifdef GL_EXT_index_material + GLEW_EXT_index_material = _glewSearchExtension("GL_EXT_index_material", extStart, extEnd); + if (glewExperimental || GLEW_EXT_index_material) GLEW_EXT_index_material = !_glewInit_GL_EXT_index_material(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_index_material */ +#ifdef GL_EXT_index_texture + GLEW_EXT_index_texture = _glewSearchExtension("GL_EXT_index_texture", extStart, extEnd); +#endif /* GL_EXT_index_texture */ +#ifdef GL_EXT_light_texture + GLEW_EXT_light_texture = _glewSearchExtension("GL_EXT_light_texture", extStart, extEnd); + if (glewExperimental || GLEW_EXT_light_texture) GLEW_EXT_light_texture = !_glewInit_GL_EXT_light_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_light_texture */ +#ifdef GL_EXT_misc_attribute + GLEW_EXT_misc_attribute = _glewSearchExtension("GL_EXT_misc_attribute", extStart, extEnd); +#endif /* GL_EXT_misc_attribute */ +#ifdef GL_EXT_multi_draw_arrays + GLEW_EXT_multi_draw_arrays = _glewSearchExtension("GL_EXT_multi_draw_arrays", extStart, extEnd); + if (glewExperimental || GLEW_EXT_multi_draw_arrays) 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 + GLEW_EXT_multisample = _glewSearchExtension("GL_EXT_multisample", extStart, extEnd); + if (glewExperimental || GLEW_EXT_multisample) GLEW_EXT_multisample = !_glewInit_GL_EXT_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_multisample */ +#ifdef GL_EXT_packed_depth_stencil + GLEW_EXT_packed_depth_stencil = _glewSearchExtension("GL_EXT_packed_depth_stencil", extStart, extEnd); +#endif /* GL_EXT_packed_depth_stencil */ +#ifdef GL_EXT_packed_float + GLEW_EXT_packed_float = _glewSearchExtension("GL_EXT_packed_float", extStart, extEnd); +#endif /* GL_EXT_packed_float */ +#ifdef GL_EXT_packed_pixels + GLEW_EXT_packed_pixels = _glewSearchExtension("GL_EXT_packed_pixels", extStart, extEnd); +#endif /* GL_EXT_packed_pixels */ +#ifdef GL_EXT_paletted_texture + GLEW_EXT_paletted_texture = _glewSearchExtension("GL_EXT_paletted_texture", extStart, extEnd); + if (glewExperimental || GLEW_EXT_paletted_texture) 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 + GLEW_EXT_pixel_buffer_object = _glewSearchExtension("GL_EXT_pixel_buffer_object", extStart, extEnd); +#endif /* GL_EXT_pixel_buffer_object */ +#ifdef GL_EXT_pixel_transform + GLEW_EXT_pixel_transform = _glewSearchExtension("GL_EXT_pixel_transform", extStart, extEnd); + if (glewExperimental || GLEW_EXT_pixel_transform) 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 + GLEW_EXT_pixel_transform_color_table = _glewSearchExtension("GL_EXT_pixel_transform_color_table", extStart, extEnd); +#endif /* GL_EXT_pixel_transform_color_table */ +#ifdef GL_EXT_point_parameters + GLEW_EXT_point_parameters = _glewSearchExtension("GL_EXT_point_parameters", extStart, extEnd); + if (glewExperimental || GLEW_EXT_point_parameters) GLEW_EXT_point_parameters = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_point_parameters */ +#ifdef GL_EXT_polygon_offset + GLEW_EXT_polygon_offset = _glewSearchExtension("GL_EXT_polygon_offset", extStart, extEnd); + if (glewExperimental || GLEW_EXT_polygon_offset) GLEW_EXT_polygon_offset = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_polygon_offset */ +#ifdef GL_EXT_provoking_vertex + GLEW_EXT_provoking_vertex = _glewSearchExtension("GL_EXT_provoking_vertex", extStart, extEnd); + if (glewExperimental || GLEW_EXT_provoking_vertex) GLEW_EXT_provoking_vertex = !_glewInit_GL_EXT_provoking_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_provoking_vertex */ +#ifdef GL_EXT_rescale_normal + GLEW_EXT_rescale_normal = _glewSearchExtension("GL_EXT_rescale_normal", extStart, extEnd); +#endif /* GL_EXT_rescale_normal */ +#ifdef GL_EXT_scene_marker + GLEW_EXT_scene_marker = _glewSearchExtension("GL_EXT_scene_marker", extStart, extEnd); + if (glewExperimental || GLEW_EXT_scene_marker) GLEW_EXT_scene_marker = !_glewInit_GL_EXT_scene_marker(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_scene_marker */ +#ifdef GL_EXT_secondary_color + GLEW_EXT_secondary_color = _glewSearchExtension("GL_EXT_secondary_color", extStart, extEnd); + if (glewExperimental || GLEW_EXT_secondary_color) GLEW_EXT_secondary_color = !_glewInit_GL_EXT_secondary_color(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_secondary_color */ +#ifdef GL_EXT_separate_shader_objects + GLEW_EXT_separate_shader_objects = _glewSearchExtension("GL_EXT_separate_shader_objects", extStart, extEnd); + if (glewExperimental || GLEW_EXT_separate_shader_objects) GLEW_EXT_separate_shader_objects = !_glewInit_GL_EXT_separate_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_separate_shader_objects */ +#ifdef GL_EXT_separate_specular_color + GLEW_EXT_separate_specular_color = _glewSearchExtension("GL_EXT_separate_specular_color", extStart, extEnd); +#endif /* GL_EXT_separate_specular_color */ +#ifdef GL_EXT_shader_image_load_formatted + GLEW_EXT_shader_image_load_formatted = _glewSearchExtension("GL_EXT_shader_image_load_formatted", extStart, extEnd); +#endif /* GL_EXT_shader_image_load_formatted */ +#ifdef GL_EXT_shader_image_load_store + GLEW_EXT_shader_image_load_store = _glewSearchExtension("GL_EXT_shader_image_load_store", extStart, extEnd); + if (glewExperimental || GLEW_EXT_shader_image_load_store) GLEW_EXT_shader_image_load_store = !_glewInit_GL_EXT_shader_image_load_store(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_shader_image_load_store */ +#ifdef GL_EXT_shader_integer_mix + GLEW_EXT_shader_integer_mix = _glewSearchExtension("GL_EXT_shader_integer_mix", extStart, extEnd); +#endif /* GL_EXT_shader_integer_mix */ +#ifdef GL_EXT_shadow_funcs + GLEW_EXT_shadow_funcs = _glewSearchExtension("GL_EXT_shadow_funcs", extStart, extEnd); +#endif /* GL_EXT_shadow_funcs */ +#ifdef GL_EXT_shared_texture_palette + GLEW_EXT_shared_texture_palette = _glewSearchExtension("GL_EXT_shared_texture_palette", extStart, extEnd); +#endif /* GL_EXT_shared_texture_palette */ +#ifdef GL_EXT_stencil_clear_tag + GLEW_EXT_stencil_clear_tag = _glewSearchExtension("GL_EXT_stencil_clear_tag", extStart, extEnd); +#endif /* GL_EXT_stencil_clear_tag */ +#ifdef GL_EXT_stencil_two_side + GLEW_EXT_stencil_two_side = _glewSearchExtension("GL_EXT_stencil_two_side", extStart, extEnd); + if (glewExperimental || GLEW_EXT_stencil_two_side) 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 + GLEW_EXT_stencil_wrap = _glewSearchExtension("GL_EXT_stencil_wrap", extStart, extEnd); +#endif /* GL_EXT_stencil_wrap */ +#ifdef GL_EXT_subtexture + GLEW_EXT_subtexture = _glewSearchExtension("GL_EXT_subtexture", extStart, extEnd); + if (glewExperimental || GLEW_EXT_subtexture) GLEW_EXT_subtexture = !_glewInit_GL_EXT_subtexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_subtexture */ +#ifdef GL_EXT_texture + GLEW_EXT_texture = _glewSearchExtension("GL_EXT_texture", extStart, extEnd); +#endif /* GL_EXT_texture */ +#ifdef GL_EXT_texture3D + GLEW_EXT_texture3D = _glewSearchExtension("GL_EXT_texture3D", extStart, extEnd); + if (glewExperimental || GLEW_EXT_texture3D) GLEW_EXT_texture3D = !_glewInit_GL_EXT_texture3D(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture3D */ +#ifdef GL_EXT_texture_array + GLEW_EXT_texture_array = _glewSearchExtension("GL_EXT_texture_array", extStart, extEnd); + if (glewExperimental || GLEW_EXT_texture_array) GLEW_EXT_texture_array = !_glewInit_GL_EXT_texture_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_array */ +#ifdef GL_EXT_texture_buffer_object + GLEW_EXT_texture_buffer_object = _glewSearchExtension("GL_EXT_texture_buffer_object", extStart, extEnd); + if (glewExperimental || GLEW_EXT_texture_buffer_object) 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 + GLEW_EXT_texture_compression_dxt1 = _glewSearchExtension("GL_EXT_texture_compression_dxt1", extStart, extEnd); +#endif /* GL_EXT_texture_compression_dxt1 */ +#ifdef GL_EXT_texture_compression_latc + GLEW_EXT_texture_compression_latc = _glewSearchExtension("GL_EXT_texture_compression_latc", extStart, extEnd); +#endif /* GL_EXT_texture_compression_latc */ +#ifdef GL_EXT_texture_compression_rgtc + GLEW_EXT_texture_compression_rgtc = _glewSearchExtension("GL_EXT_texture_compression_rgtc", extStart, extEnd); +#endif /* GL_EXT_texture_compression_rgtc */ +#ifdef GL_EXT_texture_compression_s3tc + GLEW_EXT_texture_compression_s3tc = _glewSearchExtension("GL_EXT_texture_compression_s3tc", extStart, extEnd); +#endif /* GL_EXT_texture_compression_s3tc */ +#ifdef GL_EXT_texture_cube_map + GLEW_EXT_texture_cube_map = _glewSearchExtension("GL_EXT_texture_cube_map", extStart, extEnd); +#endif /* GL_EXT_texture_cube_map */ +#ifdef GL_EXT_texture_edge_clamp + GLEW_EXT_texture_edge_clamp = _glewSearchExtension("GL_EXT_texture_edge_clamp", extStart, extEnd); +#endif /* GL_EXT_texture_edge_clamp */ +#ifdef GL_EXT_texture_env + GLEW_EXT_texture_env = _glewSearchExtension("GL_EXT_texture_env", extStart, extEnd); +#endif /* GL_EXT_texture_env */ +#ifdef GL_EXT_texture_env_add + GLEW_EXT_texture_env_add = _glewSearchExtension("GL_EXT_texture_env_add", extStart, extEnd); +#endif /* GL_EXT_texture_env_add */ +#ifdef GL_EXT_texture_env_combine + GLEW_EXT_texture_env_combine = _glewSearchExtension("GL_EXT_texture_env_combine", extStart, extEnd); +#endif /* GL_EXT_texture_env_combine */ +#ifdef GL_EXT_texture_env_dot3 + GLEW_EXT_texture_env_dot3 = _glewSearchExtension("GL_EXT_texture_env_dot3", extStart, extEnd); +#endif /* GL_EXT_texture_env_dot3 */ +#ifdef GL_EXT_texture_filter_anisotropic + GLEW_EXT_texture_filter_anisotropic = _glewSearchExtension("GL_EXT_texture_filter_anisotropic", extStart, extEnd); +#endif /* GL_EXT_texture_filter_anisotropic */ +#ifdef GL_EXT_texture_integer + GLEW_EXT_texture_integer = _glewSearchExtension("GL_EXT_texture_integer", extStart, extEnd); + if (glewExperimental || GLEW_EXT_texture_integer) 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 + GLEW_EXT_texture_lod_bias = _glewSearchExtension("GL_EXT_texture_lod_bias", extStart, extEnd); +#endif /* GL_EXT_texture_lod_bias */ +#ifdef GL_EXT_texture_mirror_clamp + GLEW_EXT_texture_mirror_clamp = _glewSearchExtension("GL_EXT_texture_mirror_clamp", extStart, extEnd); +#endif /* GL_EXT_texture_mirror_clamp */ +#ifdef GL_EXT_texture_object + GLEW_EXT_texture_object = _glewSearchExtension("GL_EXT_texture_object", extStart, extEnd); + if (glewExperimental || GLEW_EXT_texture_object) 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 + GLEW_EXT_texture_perturb_normal = _glewSearchExtension("GL_EXT_texture_perturb_normal", extStart, extEnd); + if (glewExperimental || GLEW_EXT_texture_perturb_normal) 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 + GLEW_EXT_texture_rectangle = _glewSearchExtension("GL_EXT_texture_rectangle", extStart, extEnd); +#endif /* GL_EXT_texture_rectangle */ +#ifdef GL_EXT_texture_sRGB + GLEW_EXT_texture_sRGB = _glewSearchExtension("GL_EXT_texture_sRGB", extStart, extEnd); +#endif /* GL_EXT_texture_sRGB */ +#ifdef GL_EXT_texture_sRGB_decode + GLEW_EXT_texture_sRGB_decode = _glewSearchExtension("GL_EXT_texture_sRGB_decode", extStart, extEnd); +#endif /* GL_EXT_texture_sRGB_decode */ +#ifdef GL_EXT_texture_shared_exponent + GLEW_EXT_texture_shared_exponent = _glewSearchExtension("GL_EXT_texture_shared_exponent", extStart, extEnd); +#endif /* GL_EXT_texture_shared_exponent */ +#ifdef GL_EXT_texture_snorm + GLEW_EXT_texture_snorm = _glewSearchExtension("GL_EXT_texture_snorm", extStart, extEnd); +#endif /* GL_EXT_texture_snorm */ +#ifdef GL_EXT_texture_swizzle + GLEW_EXT_texture_swizzle = _glewSearchExtension("GL_EXT_texture_swizzle", extStart, extEnd); +#endif /* GL_EXT_texture_swizzle */ +#ifdef GL_EXT_timer_query + GLEW_EXT_timer_query = _glewSearchExtension("GL_EXT_timer_query", extStart, extEnd); + if (glewExperimental || GLEW_EXT_timer_query) GLEW_EXT_timer_query = !_glewInit_GL_EXT_timer_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_timer_query */ +#ifdef GL_EXT_transform_feedback + GLEW_EXT_transform_feedback = _glewSearchExtension("GL_EXT_transform_feedback", extStart, extEnd); + if (glewExperimental || GLEW_EXT_transform_feedback) GLEW_EXT_transform_feedback = !_glewInit_GL_EXT_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_transform_feedback */ +#ifdef GL_EXT_vertex_array + GLEW_EXT_vertex_array = _glewSearchExtension("GL_EXT_vertex_array", extStart, extEnd); + if (glewExperimental || GLEW_EXT_vertex_array) 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 + GLEW_EXT_vertex_array_bgra = _glewSearchExtension("GL_EXT_vertex_array_bgra", extStart, extEnd); +#endif /* GL_EXT_vertex_array_bgra */ +#ifdef GL_EXT_vertex_attrib_64bit + GLEW_EXT_vertex_attrib_64bit = _glewSearchExtension("GL_EXT_vertex_attrib_64bit", extStart, extEnd); + if (glewExperimental || GLEW_EXT_vertex_attrib_64bit) GLEW_EXT_vertex_attrib_64bit = !_glewInit_GL_EXT_vertex_attrib_64bit(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_attrib_64bit */ +#ifdef GL_EXT_vertex_shader + GLEW_EXT_vertex_shader = _glewSearchExtension("GL_EXT_vertex_shader", extStart, extEnd); + if (glewExperimental || GLEW_EXT_vertex_shader) GLEW_EXT_vertex_shader = !_glewInit_GL_EXT_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_shader */ +#ifdef GL_EXT_vertex_weighting + GLEW_EXT_vertex_weighting = _glewSearchExtension("GL_EXT_vertex_weighting", extStart, extEnd); + if (glewExperimental || GLEW_EXT_vertex_weighting) GLEW_EXT_vertex_weighting = !_glewInit_GL_EXT_vertex_weighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_weighting */ +#ifdef GL_EXT_x11_sync_object + GLEW_EXT_x11_sync_object = _glewSearchExtension("GL_EXT_x11_sync_object", extStart, extEnd); + if (glewExperimental || GLEW_EXT_x11_sync_object) GLEW_EXT_x11_sync_object = !_glewInit_GL_EXT_x11_sync_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_x11_sync_object */ +#ifdef GL_GREMEDY_frame_terminator + GLEW_GREMEDY_frame_terminator = _glewSearchExtension("GL_GREMEDY_frame_terminator", extStart, extEnd); + if (glewExperimental || GLEW_GREMEDY_frame_terminator) GLEW_GREMEDY_frame_terminator = !_glewInit_GL_GREMEDY_frame_terminator(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_GREMEDY_frame_terminator */ +#ifdef GL_GREMEDY_string_marker + GLEW_GREMEDY_string_marker = _glewSearchExtension("GL_GREMEDY_string_marker", extStart, extEnd); + if (glewExperimental || GLEW_GREMEDY_string_marker) 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 + GLEW_HP_convolution_border_modes = _glewSearchExtension("GL_HP_convolution_border_modes", extStart, extEnd); +#endif /* GL_HP_convolution_border_modes */ +#ifdef GL_HP_image_transform + GLEW_HP_image_transform = _glewSearchExtension("GL_HP_image_transform", extStart, extEnd); + if (glewExperimental || GLEW_HP_image_transform) GLEW_HP_image_transform = !_glewInit_GL_HP_image_transform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_HP_image_transform */ +#ifdef GL_HP_occlusion_test + GLEW_HP_occlusion_test = _glewSearchExtension("GL_HP_occlusion_test", extStart, extEnd); +#endif /* GL_HP_occlusion_test */ +#ifdef GL_HP_texture_lighting + GLEW_HP_texture_lighting = _glewSearchExtension("GL_HP_texture_lighting", extStart, extEnd); +#endif /* GL_HP_texture_lighting */ +#ifdef GL_IBM_cull_vertex + GLEW_IBM_cull_vertex = _glewSearchExtension("GL_IBM_cull_vertex", extStart, extEnd); +#endif /* GL_IBM_cull_vertex */ +#ifdef GL_IBM_multimode_draw_arrays + GLEW_IBM_multimode_draw_arrays = _glewSearchExtension("GL_IBM_multimode_draw_arrays", extStart, extEnd); + if (glewExperimental || GLEW_IBM_multimode_draw_arrays) 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 + GLEW_IBM_rasterpos_clip = _glewSearchExtension("GL_IBM_rasterpos_clip", extStart, extEnd); +#endif /* GL_IBM_rasterpos_clip */ +#ifdef GL_IBM_static_data + GLEW_IBM_static_data = _glewSearchExtension("GL_IBM_static_data", extStart, extEnd); +#endif /* GL_IBM_static_data */ +#ifdef GL_IBM_texture_mirrored_repeat + GLEW_IBM_texture_mirrored_repeat = _glewSearchExtension("GL_IBM_texture_mirrored_repeat", extStart, extEnd); +#endif /* GL_IBM_texture_mirrored_repeat */ +#ifdef GL_IBM_vertex_array_lists + GLEW_IBM_vertex_array_lists = _glewSearchExtension("GL_IBM_vertex_array_lists", extStart, extEnd); + if (glewExperimental || GLEW_IBM_vertex_array_lists) 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 + GLEW_INGR_color_clamp = _glewSearchExtension("GL_INGR_color_clamp", extStart, extEnd); +#endif /* GL_INGR_color_clamp */ +#ifdef GL_INGR_interlace_read + GLEW_INGR_interlace_read = _glewSearchExtension("GL_INGR_interlace_read", extStart, extEnd); +#endif /* GL_INGR_interlace_read */ +#ifdef GL_INTEL_fragment_shader_ordering + GLEW_INTEL_fragment_shader_ordering = _glewSearchExtension("GL_INTEL_fragment_shader_ordering", extStart, extEnd); +#endif /* GL_INTEL_fragment_shader_ordering */ +#ifdef GL_INTEL_map_texture + GLEW_INTEL_map_texture = _glewSearchExtension("GL_INTEL_map_texture", extStart, extEnd); + if (glewExperimental || GLEW_INTEL_map_texture) GLEW_INTEL_map_texture = !_glewInit_GL_INTEL_map_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_map_texture */ +#ifdef GL_INTEL_parallel_arrays + GLEW_INTEL_parallel_arrays = _glewSearchExtension("GL_INTEL_parallel_arrays", extStart, extEnd); + if (glewExperimental || GLEW_INTEL_parallel_arrays) GLEW_INTEL_parallel_arrays = !_glewInit_GL_INTEL_parallel_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_parallel_arrays */ +#ifdef GL_INTEL_performance_query + GLEW_INTEL_performance_query = _glewSearchExtension("GL_INTEL_performance_query", extStart, extEnd); + if (glewExperimental || GLEW_INTEL_performance_query) GLEW_INTEL_performance_query = !_glewInit_GL_INTEL_performance_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_performance_query */ +#ifdef GL_INTEL_texture_scissor + GLEW_INTEL_texture_scissor = _glewSearchExtension("GL_INTEL_texture_scissor", extStart, extEnd); + if (glewExperimental || GLEW_INTEL_texture_scissor) GLEW_INTEL_texture_scissor = !_glewInit_GL_INTEL_texture_scissor(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_texture_scissor */ +#ifdef GL_KHR_debug + GLEW_KHR_debug = _glewSearchExtension("GL_KHR_debug", extStart, extEnd); + if (glewExperimental || GLEW_KHR_debug) GLEW_KHR_debug = !_glewInit_GL_KHR_debug(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_KHR_debug */ +#ifdef GL_KHR_texture_compression_astc_hdr + GLEW_KHR_texture_compression_astc_hdr = _glewSearchExtension("GL_KHR_texture_compression_astc_hdr", extStart, extEnd); +#endif /* GL_KHR_texture_compression_astc_hdr */ +#ifdef GL_KHR_texture_compression_astc_ldr + GLEW_KHR_texture_compression_astc_ldr = _glewSearchExtension("GL_KHR_texture_compression_astc_ldr", extStart, extEnd); +#endif /* GL_KHR_texture_compression_astc_ldr */ +#ifdef GL_KTX_buffer_region + GLEW_KTX_buffer_region = _glewSearchExtension("GL_KTX_buffer_region", extStart, extEnd); + if (glewExperimental || GLEW_KTX_buffer_region) GLEW_KTX_buffer_region = !_glewInit_GL_KTX_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_KTX_buffer_region */ +#ifdef GL_MESAX_texture_stack + GLEW_MESAX_texture_stack = _glewSearchExtension("GL_MESAX_texture_stack", extStart, extEnd); +#endif /* GL_MESAX_texture_stack */ +#ifdef GL_MESA_pack_invert + GLEW_MESA_pack_invert = _glewSearchExtension("GL_MESA_pack_invert", extStart, extEnd); +#endif /* GL_MESA_pack_invert */ +#ifdef GL_MESA_resize_buffers + GLEW_MESA_resize_buffers = _glewSearchExtension("GL_MESA_resize_buffers", extStart, extEnd); + if (glewExperimental || GLEW_MESA_resize_buffers) GLEW_MESA_resize_buffers = !_glewInit_GL_MESA_resize_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_MESA_resize_buffers */ +#ifdef GL_MESA_window_pos + GLEW_MESA_window_pos = _glewSearchExtension("GL_MESA_window_pos", extStart, extEnd); + if (glewExperimental || GLEW_MESA_window_pos) GLEW_MESA_window_pos = !_glewInit_GL_MESA_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_MESA_window_pos */ +#ifdef GL_MESA_ycbcr_texture + GLEW_MESA_ycbcr_texture = _glewSearchExtension("GL_MESA_ycbcr_texture", extStart, extEnd); +#endif /* GL_MESA_ycbcr_texture */ +#ifdef GL_NVX_conditional_render + GLEW_NVX_conditional_render = _glewSearchExtension("GL_NVX_conditional_render", extStart, extEnd); + if (glewExperimental || GLEW_NVX_conditional_render) GLEW_NVX_conditional_render = !_glewInit_GL_NVX_conditional_render(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NVX_conditional_render */ +#ifdef GL_NVX_gpu_memory_info + GLEW_NVX_gpu_memory_info = _glewSearchExtension("GL_NVX_gpu_memory_info", extStart, extEnd); +#endif /* GL_NVX_gpu_memory_info */ +#ifdef GL_NV_bindless_multi_draw_indirect + GLEW_NV_bindless_multi_draw_indirect = _glewSearchExtension("GL_NV_bindless_multi_draw_indirect", extStart, extEnd); + if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect) GLEW_NV_bindless_multi_draw_indirect = !_glewInit_GL_NV_bindless_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_bindless_multi_draw_indirect */ +#ifdef GL_NV_bindless_texture + GLEW_NV_bindless_texture = _glewSearchExtension("GL_NV_bindless_texture", extStart, extEnd); + if (glewExperimental || GLEW_NV_bindless_texture) GLEW_NV_bindless_texture = !_glewInit_GL_NV_bindless_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_bindless_texture */ +#ifdef GL_NV_blend_equation_advanced + GLEW_NV_blend_equation_advanced = _glewSearchExtension("GL_NV_blend_equation_advanced", extStart, extEnd); + if (glewExperimental || GLEW_NV_blend_equation_advanced) GLEW_NV_blend_equation_advanced = !_glewInit_GL_NV_blend_equation_advanced(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_blend_equation_advanced */ +#ifdef GL_NV_blend_equation_advanced_coherent + GLEW_NV_blend_equation_advanced_coherent = _glewSearchExtension("GL_NV_blend_equation_advanced_coherent", extStart, extEnd); +#endif /* GL_NV_blend_equation_advanced_coherent */ +#ifdef GL_NV_blend_square + GLEW_NV_blend_square = _glewSearchExtension("GL_NV_blend_square", extStart, extEnd); +#endif /* GL_NV_blend_square */ +#ifdef GL_NV_compute_program5 + GLEW_NV_compute_program5 = _glewSearchExtension("GL_NV_compute_program5", extStart, extEnd); +#endif /* GL_NV_compute_program5 */ +#ifdef GL_NV_conditional_render + GLEW_NV_conditional_render = _glewSearchExtension("GL_NV_conditional_render", extStart, extEnd); + if (glewExperimental || GLEW_NV_conditional_render) 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 + GLEW_NV_copy_depth_to_color = _glewSearchExtension("GL_NV_copy_depth_to_color", extStart, extEnd); +#endif /* GL_NV_copy_depth_to_color */ +#ifdef GL_NV_copy_image + GLEW_NV_copy_image = _glewSearchExtension("GL_NV_copy_image", extStart, extEnd); + if (glewExperimental || GLEW_NV_copy_image) GLEW_NV_copy_image = !_glewInit_GL_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_copy_image */ +#ifdef GL_NV_deep_texture3D + GLEW_NV_deep_texture3D = _glewSearchExtension("GL_NV_deep_texture3D", extStart, extEnd); +#endif /* GL_NV_deep_texture3D */ +#ifdef GL_NV_depth_buffer_float + GLEW_NV_depth_buffer_float = _glewSearchExtension("GL_NV_depth_buffer_float", extStart, extEnd); + if (glewExperimental || GLEW_NV_depth_buffer_float) 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 + GLEW_NV_depth_clamp = _glewSearchExtension("GL_NV_depth_clamp", extStart, extEnd); +#endif /* GL_NV_depth_clamp */ +#ifdef GL_NV_depth_range_unclamped + GLEW_NV_depth_range_unclamped = _glewSearchExtension("GL_NV_depth_range_unclamped", extStart, extEnd); +#endif /* GL_NV_depth_range_unclamped */ +#ifdef GL_NV_draw_texture + GLEW_NV_draw_texture = _glewSearchExtension("GL_NV_draw_texture", extStart, extEnd); + if (glewExperimental || GLEW_NV_draw_texture) GLEW_NV_draw_texture = !_glewInit_GL_NV_draw_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_draw_texture */ +#ifdef GL_NV_evaluators + GLEW_NV_evaluators = _glewSearchExtension("GL_NV_evaluators", extStart, extEnd); + if (glewExperimental || GLEW_NV_evaluators) GLEW_NV_evaluators = !_glewInit_GL_NV_evaluators(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_evaluators */ +#ifdef GL_NV_explicit_multisample + GLEW_NV_explicit_multisample = _glewSearchExtension("GL_NV_explicit_multisample", extStart, extEnd); + if (glewExperimental || GLEW_NV_explicit_multisample) GLEW_NV_explicit_multisample = !_glewInit_GL_NV_explicit_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_explicit_multisample */ +#ifdef GL_NV_fence + GLEW_NV_fence = _glewSearchExtension("GL_NV_fence", extStart, extEnd); + if (glewExperimental || GLEW_NV_fence) GLEW_NV_fence = !_glewInit_GL_NV_fence(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_fence */ +#ifdef GL_NV_float_buffer + GLEW_NV_float_buffer = _glewSearchExtension("GL_NV_float_buffer", extStart, extEnd); +#endif /* GL_NV_float_buffer */ +#ifdef GL_NV_fog_distance + GLEW_NV_fog_distance = _glewSearchExtension("GL_NV_fog_distance", extStart, extEnd); +#endif /* GL_NV_fog_distance */ +#ifdef GL_NV_fragment_program + GLEW_NV_fragment_program = _glewSearchExtension("GL_NV_fragment_program", extStart, extEnd); + if (glewExperimental || GLEW_NV_fragment_program) GLEW_NV_fragment_program = !_glewInit_GL_NV_fragment_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_fragment_program */ +#ifdef GL_NV_fragment_program2 + GLEW_NV_fragment_program2 = _glewSearchExtension("GL_NV_fragment_program2", extStart, extEnd); +#endif /* GL_NV_fragment_program2 */ +#ifdef GL_NV_fragment_program4 + GLEW_NV_fragment_program4 = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd); +#endif /* GL_NV_fragment_program4 */ +#ifdef GL_NV_fragment_program_option + GLEW_NV_fragment_program_option = _glewSearchExtension("GL_NV_fragment_program_option", extStart, extEnd); +#endif /* GL_NV_fragment_program_option */ +#ifdef GL_NV_framebuffer_multisample_coverage + GLEW_NV_framebuffer_multisample_coverage = _glewSearchExtension("GL_NV_framebuffer_multisample_coverage", extStart, extEnd); + if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) 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 + GLEW_NV_geometry_program4 = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd); + if (glewExperimental || GLEW_NV_geometry_program4) GLEW_NV_geometry_program4 = !_glewInit_GL_NV_geometry_program4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_geometry_program4 */ +#ifdef GL_NV_geometry_shader4 + GLEW_NV_geometry_shader4 = _glewSearchExtension("GL_NV_geometry_shader4", extStart, extEnd); +#endif /* GL_NV_geometry_shader4 */ +#ifdef GL_NV_gpu_program4 + GLEW_NV_gpu_program4 = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd); + if (glewExperimental || GLEW_NV_gpu_program4) GLEW_NV_gpu_program4 = !_glewInit_GL_NV_gpu_program4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_gpu_program4 */ +#ifdef GL_NV_gpu_program5 + GLEW_NV_gpu_program5 = _glewSearchExtension("GL_NV_gpu_program5", extStart, extEnd); +#endif /* GL_NV_gpu_program5 */ +#ifdef GL_NV_gpu_program5_mem_extended + GLEW_NV_gpu_program5_mem_extended = _glewSearchExtension("GL_NV_gpu_program5_mem_extended", extStart, extEnd); +#endif /* GL_NV_gpu_program5_mem_extended */ +#ifdef GL_NV_gpu_program_fp64 + GLEW_NV_gpu_program_fp64 = _glewSearchExtension("GL_NV_gpu_program_fp64", extStart, extEnd); +#endif /* GL_NV_gpu_program_fp64 */ +#ifdef GL_NV_gpu_shader5 + GLEW_NV_gpu_shader5 = _glewSearchExtension("GL_NV_gpu_shader5", extStart, extEnd); + if (glewExperimental || GLEW_NV_gpu_shader5) GLEW_NV_gpu_shader5 = !_glewInit_GL_NV_gpu_shader5(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_gpu_shader5 */ +#ifdef GL_NV_half_float + GLEW_NV_half_float = _glewSearchExtension("GL_NV_half_float", extStart, extEnd); + if (glewExperimental || GLEW_NV_half_float) 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 + GLEW_NV_light_max_exponent = _glewSearchExtension("GL_NV_light_max_exponent", extStart, extEnd); +#endif /* GL_NV_light_max_exponent */ +#ifdef GL_NV_multisample_coverage + GLEW_NV_multisample_coverage = _glewSearchExtension("GL_NV_multisample_coverage", extStart, extEnd); +#endif /* GL_NV_multisample_coverage */ +#ifdef GL_NV_multisample_filter_hint + GLEW_NV_multisample_filter_hint = _glewSearchExtension("GL_NV_multisample_filter_hint", extStart, extEnd); +#endif /* GL_NV_multisample_filter_hint */ +#ifdef GL_NV_occlusion_query + GLEW_NV_occlusion_query = _glewSearchExtension("GL_NV_occlusion_query", extStart, extEnd); + if (glewExperimental || GLEW_NV_occlusion_query) 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 + GLEW_NV_packed_depth_stencil = _glewSearchExtension("GL_NV_packed_depth_stencil", extStart, extEnd); +#endif /* GL_NV_packed_depth_stencil */ +#ifdef GL_NV_parameter_buffer_object + GLEW_NV_parameter_buffer_object = _glewSearchExtension("GL_NV_parameter_buffer_object", extStart, extEnd); + if (glewExperimental || GLEW_NV_parameter_buffer_object) 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_parameter_buffer_object2 + GLEW_NV_parameter_buffer_object2 = _glewSearchExtension("GL_NV_parameter_buffer_object2", extStart, extEnd); +#endif /* GL_NV_parameter_buffer_object2 */ +#ifdef GL_NV_path_rendering + GLEW_NV_path_rendering = _glewSearchExtension("GL_NV_path_rendering", extStart, extEnd); + if (glewExperimental || GLEW_NV_path_rendering) GLEW_NV_path_rendering = !_glewInit_GL_NV_path_rendering(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_path_rendering */ +#ifdef GL_NV_pixel_data_range + GLEW_NV_pixel_data_range = _glewSearchExtension("GL_NV_pixel_data_range", extStart, extEnd); + if (glewExperimental || GLEW_NV_pixel_data_range) 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 + GLEW_NV_point_sprite = _glewSearchExtension("GL_NV_point_sprite", extStart, extEnd); + if (glewExperimental || GLEW_NV_point_sprite) GLEW_NV_point_sprite = !_glewInit_GL_NV_point_sprite(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_point_sprite */ +#ifdef GL_NV_present_video + GLEW_NV_present_video = _glewSearchExtension("GL_NV_present_video", extStart, extEnd); + if (glewExperimental || GLEW_NV_present_video) GLEW_NV_present_video = !_glewInit_GL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_present_video */ +#ifdef GL_NV_primitive_restart + GLEW_NV_primitive_restart = _glewSearchExtension("GL_NV_primitive_restart", extStart, extEnd); + if (glewExperimental || GLEW_NV_primitive_restart) GLEW_NV_primitive_restart = !_glewInit_GL_NV_primitive_restart(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_primitive_restart */ +#ifdef GL_NV_register_combiners + GLEW_NV_register_combiners = _glewSearchExtension("GL_NV_register_combiners", extStart, extEnd); + if (glewExperimental || GLEW_NV_register_combiners) GLEW_NV_register_combiners = !_glewInit_GL_NV_register_combiners(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_register_combiners */ +#ifdef GL_NV_register_combiners2 + GLEW_NV_register_combiners2 = _glewSearchExtension("GL_NV_register_combiners2", extStart, extEnd); + if (glewExperimental || GLEW_NV_register_combiners2) GLEW_NV_register_combiners2 = !_glewInit_GL_NV_register_combiners2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_register_combiners2 */ +#ifdef GL_NV_shader_atomic_counters + GLEW_NV_shader_atomic_counters = _glewSearchExtension("GL_NV_shader_atomic_counters", extStart, extEnd); +#endif /* GL_NV_shader_atomic_counters */ +#ifdef GL_NV_shader_atomic_float + GLEW_NV_shader_atomic_float = _glewSearchExtension("GL_NV_shader_atomic_float", extStart, extEnd); +#endif /* GL_NV_shader_atomic_float */ +#ifdef GL_NV_shader_buffer_load + GLEW_NV_shader_buffer_load = _glewSearchExtension("GL_NV_shader_buffer_load", extStart, extEnd); + if (glewExperimental || GLEW_NV_shader_buffer_load) GLEW_NV_shader_buffer_load = !_glewInit_GL_NV_shader_buffer_load(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_shader_buffer_load */ +#ifdef GL_NV_shader_storage_buffer_object + GLEW_NV_shader_storage_buffer_object = _glewSearchExtension("GL_NV_shader_storage_buffer_object", extStart, extEnd); +#endif /* GL_NV_shader_storage_buffer_object */ +#ifdef GL_NV_shader_thread_group + GLEW_NV_shader_thread_group = _glewSearchExtension("GL_NV_shader_thread_group", extStart, extEnd); +#endif /* GL_NV_shader_thread_group */ +#ifdef GL_NV_shader_thread_shuffle + GLEW_NV_shader_thread_shuffle = _glewSearchExtension("GL_NV_shader_thread_shuffle", extStart, extEnd); +#endif /* GL_NV_shader_thread_shuffle */ +#ifdef GL_NV_tessellation_program5 + GLEW_NV_tessellation_program5 = _glewSearchExtension("GL_NV_gpu_program5", extStart, extEnd); +#endif /* GL_NV_tessellation_program5 */ +#ifdef GL_NV_texgen_emboss + GLEW_NV_texgen_emboss = _glewSearchExtension("GL_NV_texgen_emboss", extStart, extEnd); +#endif /* GL_NV_texgen_emboss */ +#ifdef GL_NV_texgen_reflection + GLEW_NV_texgen_reflection = _glewSearchExtension("GL_NV_texgen_reflection", extStart, extEnd); +#endif /* GL_NV_texgen_reflection */ +#ifdef GL_NV_texture_barrier + GLEW_NV_texture_barrier = _glewSearchExtension("GL_NV_texture_barrier", extStart, extEnd); + if (glewExperimental || GLEW_NV_texture_barrier) GLEW_NV_texture_barrier = !_glewInit_GL_NV_texture_barrier(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_texture_barrier */ +#ifdef GL_NV_texture_compression_vtc + GLEW_NV_texture_compression_vtc = _glewSearchExtension("GL_NV_texture_compression_vtc", extStart, extEnd); +#endif /* GL_NV_texture_compression_vtc */ +#ifdef GL_NV_texture_env_combine4 + GLEW_NV_texture_env_combine4 = _glewSearchExtension("GL_NV_texture_env_combine4", extStart, extEnd); +#endif /* GL_NV_texture_env_combine4 */ +#ifdef GL_NV_texture_expand_normal + GLEW_NV_texture_expand_normal = _glewSearchExtension("GL_NV_texture_expand_normal", extStart, extEnd); +#endif /* GL_NV_texture_expand_normal */ +#ifdef GL_NV_texture_multisample + GLEW_NV_texture_multisample = _glewSearchExtension("GL_NV_texture_multisample", extStart, extEnd); + if (glewExperimental || GLEW_NV_texture_multisample) GLEW_NV_texture_multisample = !_glewInit_GL_NV_texture_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_texture_multisample */ +#ifdef GL_NV_texture_rectangle + GLEW_NV_texture_rectangle = _glewSearchExtension("GL_NV_texture_rectangle", extStart, extEnd); +#endif /* GL_NV_texture_rectangle */ +#ifdef GL_NV_texture_shader + GLEW_NV_texture_shader = _glewSearchExtension("GL_NV_texture_shader", extStart, extEnd); +#endif /* GL_NV_texture_shader */ +#ifdef GL_NV_texture_shader2 + GLEW_NV_texture_shader2 = _glewSearchExtension("GL_NV_texture_shader2", extStart, extEnd); +#endif /* GL_NV_texture_shader2 */ +#ifdef GL_NV_texture_shader3 + GLEW_NV_texture_shader3 = _glewSearchExtension("GL_NV_texture_shader3", extStart, extEnd); +#endif /* GL_NV_texture_shader3 */ +#ifdef GL_NV_transform_feedback + GLEW_NV_transform_feedback = _glewSearchExtension("GL_NV_transform_feedback", extStart, extEnd); + if (glewExperimental || GLEW_NV_transform_feedback) GLEW_NV_transform_feedback = !_glewInit_GL_NV_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_transform_feedback */ +#ifdef GL_NV_transform_feedback2 + GLEW_NV_transform_feedback2 = _glewSearchExtension("GL_NV_transform_feedback2", extStart, extEnd); + if (glewExperimental || GLEW_NV_transform_feedback2) GLEW_NV_transform_feedback2 = !_glewInit_GL_NV_transform_feedback2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_transform_feedback2 */ +#ifdef GL_NV_vdpau_interop + GLEW_NV_vdpau_interop = _glewSearchExtension("GL_NV_vdpau_interop", extStart, extEnd); + if (glewExperimental || GLEW_NV_vdpau_interop) GLEW_NV_vdpau_interop = !_glewInit_GL_NV_vdpau_interop(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vdpau_interop */ +#ifdef GL_NV_vertex_array_range + GLEW_NV_vertex_array_range = _glewSearchExtension("GL_NV_vertex_array_range", extStart, extEnd); + if (glewExperimental || GLEW_NV_vertex_array_range) 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 + GLEW_NV_vertex_array_range2 = _glewSearchExtension("GL_NV_vertex_array_range2", extStart, extEnd); +#endif /* GL_NV_vertex_array_range2 */ +#ifdef GL_NV_vertex_attrib_integer_64bit + GLEW_NV_vertex_attrib_integer_64bit = _glewSearchExtension("GL_NV_vertex_attrib_integer_64bit", extStart, extEnd); + if (glewExperimental || GLEW_NV_vertex_attrib_integer_64bit) GLEW_NV_vertex_attrib_integer_64bit = !_glewInit_GL_NV_vertex_attrib_integer_64bit(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vertex_attrib_integer_64bit */ +#ifdef GL_NV_vertex_buffer_unified_memory + GLEW_NV_vertex_buffer_unified_memory = _glewSearchExtension("GL_NV_vertex_buffer_unified_memory", extStart, extEnd); + if (glewExperimental || GLEW_NV_vertex_buffer_unified_memory) GLEW_NV_vertex_buffer_unified_memory = !_glewInit_GL_NV_vertex_buffer_unified_memory(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vertex_buffer_unified_memory */ +#ifdef GL_NV_vertex_program + GLEW_NV_vertex_program = _glewSearchExtension("GL_NV_vertex_program", extStart, extEnd); + if (glewExperimental || GLEW_NV_vertex_program) 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 + GLEW_NV_vertex_program1_1 = _glewSearchExtension("GL_NV_vertex_program1_1", extStart, extEnd); +#endif /* GL_NV_vertex_program1_1 */ +#ifdef GL_NV_vertex_program2 + GLEW_NV_vertex_program2 = _glewSearchExtension("GL_NV_vertex_program2", extStart, extEnd); +#endif /* GL_NV_vertex_program2 */ +#ifdef GL_NV_vertex_program2_option + GLEW_NV_vertex_program2_option = _glewSearchExtension("GL_NV_vertex_program2_option", extStart, extEnd); +#endif /* GL_NV_vertex_program2_option */ +#ifdef GL_NV_vertex_program3 + GLEW_NV_vertex_program3 = _glewSearchExtension("GL_NV_vertex_program3", extStart, extEnd); +#endif /* GL_NV_vertex_program3 */ +#ifdef GL_NV_vertex_program4 + GLEW_NV_vertex_program4 = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd); +#endif /* GL_NV_vertex_program4 */ +#ifdef GL_NV_video_capture + GLEW_NV_video_capture = _glewSearchExtension("GL_NV_video_capture", extStart, extEnd); + if (glewExperimental || GLEW_NV_video_capture) GLEW_NV_video_capture = !_glewInit_GL_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_video_capture */ +#ifdef GL_OES_byte_coordinates + GLEW_OES_byte_coordinates = _glewSearchExtension("GL_OES_byte_coordinates", extStart, extEnd); +#endif /* GL_OES_byte_coordinates */ +#ifdef GL_OES_compressed_paletted_texture + GLEW_OES_compressed_paletted_texture = _glewSearchExtension("GL_OES_compressed_paletted_texture", extStart, extEnd); +#endif /* GL_OES_compressed_paletted_texture */ +#ifdef GL_OES_read_format + GLEW_OES_read_format = _glewSearchExtension("GL_OES_read_format", extStart, extEnd); +#endif /* GL_OES_read_format */ +#ifdef GL_OES_single_precision + GLEW_OES_single_precision = _glewSearchExtension("GL_OES_single_precision", extStart, extEnd); + if (glewExperimental || GLEW_OES_single_precision) GLEW_OES_single_precision = !_glewInit_GL_OES_single_precision(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_OES_single_precision */ +#ifdef GL_OML_interlace + GLEW_OML_interlace = _glewSearchExtension("GL_OML_interlace", extStart, extEnd); +#endif /* GL_OML_interlace */ +#ifdef GL_OML_resample + GLEW_OML_resample = _glewSearchExtension("GL_OML_resample", extStart, extEnd); +#endif /* GL_OML_resample */ +#ifdef GL_OML_subsample + GLEW_OML_subsample = _glewSearchExtension("GL_OML_subsample", extStart, extEnd); +#endif /* GL_OML_subsample */ +#ifdef GL_PGI_misc_hints + GLEW_PGI_misc_hints = _glewSearchExtension("GL_PGI_misc_hints", extStart, extEnd); +#endif /* GL_PGI_misc_hints */ +#ifdef GL_PGI_vertex_hints + GLEW_PGI_vertex_hints = _glewSearchExtension("GL_PGI_vertex_hints", extStart, extEnd); +#endif /* GL_PGI_vertex_hints */ +#ifdef GL_REGAL_ES1_0_compatibility + GLEW_REGAL_ES1_0_compatibility = _glewSearchExtension("GL_REGAL_ES1_0_compatibility", extStart, extEnd); + if (glewExperimental || GLEW_REGAL_ES1_0_compatibility) GLEW_REGAL_ES1_0_compatibility = !_glewInit_GL_REGAL_ES1_0_compatibility(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_REGAL_ES1_0_compatibility */ +#ifdef GL_REGAL_ES1_1_compatibility + GLEW_REGAL_ES1_1_compatibility = _glewSearchExtension("GL_REGAL_ES1_1_compatibility", extStart, extEnd); + if (glewExperimental || GLEW_REGAL_ES1_1_compatibility) GLEW_REGAL_ES1_1_compatibility = !_glewInit_GL_REGAL_ES1_1_compatibility(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_REGAL_ES1_1_compatibility */ +#ifdef GL_REGAL_enable + GLEW_REGAL_enable = _glewSearchExtension("GL_REGAL_enable", extStart, extEnd); +#endif /* GL_REGAL_enable */ +#ifdef GL_REGAL_error_string + GLEW_REGAL_error_string = _glewSearchExtension("GL_REGAL_error_string", extStart, extEnd); + if (glewExperimental || GLEW_REGAL_error_string) GLEW_REGAL_error_string = !_glewInit_GL_REGAL_error_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_REGAL_error_string */ +#ifdef GL_REGAL_extension_query + GLEW_REGAL_extension_query = _glewSearchExtension("GL_REGAL_extension_query", extStart, extEnd); + if (glewExperimental || GLEW_REGAL_extension_query) GLEW_REGAL_extension_query = !_glewInit_GL_REGAL_extension_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_REGAL_extension_query */ +#ifdef GL_REGAL_log + GLEW_REGAL_log = _glewSearchExtension("GL_REGAL_log", extStart, extEnd); + if (glewExperimental || GLEW_REGAL_log) GLEW_REGAL_log = !_glewInit_GL_REGAL_log(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_REGAL_log */ +#ifdef GL_REGAL_proc_address + GLEW_REGAL_proc_address = _glewSearchExtension("GL_REGAL_proc_address", extStart, extEnd); + if (glewExperimental || GLEW_REGAL_proc_address) GLEW_REGAL_proc_address = !_glewInit_GL_REGAL_proc_address(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_REGAL_proc_address */ +#ifdef GL_REND_screen_coordinates + GLEW_REND_screen_coordinates = _glewSearchExtension("GL_REND_screen_coordinates", extStart, extEnd); +#endif /* GL_REND_screen_coordinates */ +#ifdef GL_S3_s3tc + GLEW_S3_s3tc = _glewSearchExtension("GL_S3_s3tc", extStart, extEnd); +#endif /* GL_S3_s3tc */ +#ifdef GL_SGIS_color_range + GLEW_SGIS_color_range = _glewSearchExtension("GL_SGIS_color_range", extStart, extEnd); +#endif /* GL_SGIS_color_range */ +#ifdef GL_SGIS_detail_texture + GLEW_SGIS_detail_texture = _glewSearchExtension("GL_SGIS_detail_texture", extStart, extEnd); + if (glewExperimental || GLEW_SGIS_detail_texture) GLEW_SGIS_detail_texture = !_glewInit_GL_SGIS_detail_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_detail_texture */ +#ifdef GL_SGIS_fog_function + GLEW_SGIS_fog_function = _glewSearchExtension("GL_SGIS_fog_function", extStart, extEnd); + if (glewExperimental || GLEW_SGIS_fog_function) GLEW_SGIS_fog_function = !_glewInit_GL_SGIS_fog_function(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_fog_function */ +#ifdef GL_SGIS_generate_mipmap + GLEW_SGIS_generate_mipmap = _glewSearchExtension("GL_SGIS_generate_mipmap", extStart, extEnd); +#endif /* GL_SGIS_generate_mipmap */ +#ifdef GL_SGIS_multisample + GLEW_SGIS_multisample = _glewSearchExtension("GL_SGIS_multisample", extStart, extEnd); + if (glewExperimental || GLEW_SGIS_multisample) GLEW_SGIS_multisample = !_glewInit_GL_SGIS_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_multisample */ +#ifdef GL_SGIS_pixel_texture + GLEW_SGIS_pixel_texture = _glewSearchExtension("GL_SGIS_pixel_texture", extStart, extEnd); +#endif /* GL_SGIS_pixel_texture */ +#ifdef GL_SGIS_point_line_texgen + GLEW_SGIS_point_line_texgen = _glewSearchExtension("GL_SGIS_point_line_texgen", extStart, extEnd); +#endif /* GL_SGIS_point_line_texgen */ +#ifdef GL_SGIS_sharpen_texture + GLEW_SGIS_sharpen_texture = _glewSearchExtension("GL_SGIS_sharpen_texture", extStart, extEnd); + if (glewExperimental || GLEW_SGIS_sharpen_texture) GLEW_SGIS_sharpen_texture = !_glewInit_GL_SGIS_sharpen_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_sharpen_texture */ +#ifdef GL_SGIS_texture4D + GLEW_SGIS_texture4D = _glewSearchExtension("GL_SGIS_texture4D", extStart, extEnd); + if (glewExperimental || GLEW_SGIS_texture4D) GLEW_SGIS_texture4D = !_glewInit_GL_SGIS_texture4D(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_texture4D */ +#ifdef GL_SGIS_texture_border_clamp + GLEW_SGIS_texture_border_clamp = _glewSearchExtension("GL_SGIS_texture_border_clamp", extStart, extEnd); +#endif /* GL_SGIS_texture_border_clamp */ +#ifdef GL_SGIS_texture_edge_clamp + GLEW_SGIS_texture_edge_clamp = _glewSearchExtension("GL_SGIS_texture_edge_clamp", extStart, extEnd); +#endif /* GL_SGIS_texture_edge_clamp */ +#ifdef GL_SGIS_texture_filter4 + GLEW_SGIS_texture_filter4 = _glewSearchExtension("GL_SGIS_texture_filter4", extStart, extEnd); + if (glewExperimental || GLEW_SGIS_texture_filter4) GLEW_SGIS_texture_filter4 = !_glewInit_GL_SGIS_texture_filter4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_texture_filter4 */ +#ifdef GL_SGIS_texture_lod + GLEW_SGIS_texture_lod = _glewSearchExtension("GL_SGIS_texture_lod", extStart, extEnd); +#endif /* GL_SGIS_texture_lod */ +#ifdef GL_SGIS_texture_select + GLEW_SGIS_texture_select = _glewSearchExtension("GL_SGIS_texture_select", extStart, extEnd); +#endif /* GL_SGIS_texture_select */ +#ifdef GL_SGIX_async + GLEW_SGIX_async = _glewSearchExtension("GL_SGIX_async", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_async) GLEW_SGIX_async = !_glewInit_GL_SGIX_async(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_async */ +#ifdef GL_SGIX_async_histogram + GLEW_SGIX_async_histogram = _glewSearchExtension("GL_SGIX_async_histogram", extStart, extEnd); +#endif /* GL_SGIX_async_histogram */ +#ifdef GL_SGIX_async_pixel + GLEW_SGIX_async_pixel = _glewSearchExtension("GL_SGIX_async_pixel", extStart, extEnd); +#endif /* GL_SGIX_async_pixel */ +#ifdef GL_SGIX_blend_alpha_minmax + GLEW_SGIX_blend_alpha_minmax = _glewSearchExtension("GL_SGIX_blend_alpha_minmax", extStart, extEnd); +#endif /* GL_SGIX_blend_alpha_minmax */ +#ifdef GL_SGIX_clipmap + GLEW_SGIX_clipmap = _glewSearchExtension("GL_SGIX_clipmap", extStart, extEnd); +#endif /* GL_SGIX_clipmap */ +#ifdef GL_SGIX_convolution_accuracy + GLEW_SGIX_convolution_accuracy = _glewSearchExtension("GL_SGIX_convolution_accuracy", extStart, extEnd); +#endif /* GL_SGIX_convolution_accuracy */ +#ifdef GL_SGIX_depth_texture + GLEW_SGIX_depth_texture = _glewSearchExtension("GL_SGIX_depth_texture", extStart, extEnd); +#endif /* GL_SGIX_depth_texture */ +#ifdef GL_SGIX_flush_raster + GLEW_SGIX_flush_raster = _glewSearchExtension("GL_SGIX_flush_raster", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_flush_raster) GLEW_SGIX_flush_raster = !_glewInit_GL_SGIX_flush_raster(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_flush_raster */ +#ifdef GL_SGIX_fog_offset + GLEW_SGIX_fog_offset = _glewSearchExtension("GL_SGIX_fog_offset", extStart, extEnd); +#endif /* GL_SGIX_fog_offset */ +#ifdef GL_SGIX_fog_texture + GLEW_SGIX_fog_texture = _glewSearchExtension("GL_SGIX_fog_texture", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_fog_texture) 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 + GLEW_SGIX_fragment_specular_lighting = _glewSearchExtension("GL_SGIX_fragment_specular_lighting", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) 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 + GLEW_SGIX_framezoom = _glewSearchExtension("GL_SGIX_framezoom", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_framezoom) GLEW_SGIX_framezoom = !_glewInit_GL_SGIX_framezoom(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_framezoom */ +#ifdef GL_SGIX_interlace + GLEW_SGIX_interlace = _glewSearchExtension("GL_SGIX_interlace", extStart, extEnd); +#endif /* GL_SGIX_interlace */ +#ifdef GL_SGIX_ir_instrument1 + GLEW_SGIX_ir_instrument1 = _glewSearchExtension("GL_SGIX_ir_instrument1", extStart, extEnd); +#endif /* GL_SGIX_ir_instrument1 */ +#ifdef GL_SGIX_list_priority + GLEW_SGIX_list_priority = _glewSearchExtension("GL_SGIX_list_priority", extStart, extEnd); +#endif /* GL_SGIX_list_priority */ +#ifdef GL_SGIX_pixel_texture + GLEW_SGIX_pixel_texture = _glewSearchExtension("GL_SGIX_pixel_texture", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_pixel_texture) 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 + GLEW_SGIX_pixel_texture_bits = _glewSearchExtension("GL_SGIX_pixel_texture_bits", extStart, extEnd); +#endif /* GL_SGIX_pixel_texture_bits */ +#ifdef GL_SGIX_reference_plane + GLEW_SGIX_reference_plane = _glewSearchExtension("GL_SGIX_reference_plane", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_reference_plane) GLEW_SGIX_reference_plane = !_glewInit_GL_SGIX_reference_plane(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_reference_plane */ +#ifdef GL_SGIX_resample + GLEW_SGIX_resample = _glewSearchExtension("GL_SGIX_resample", extStart, extEnd); +#endif /* GL_SGIX_resample */ +#ifdef GL_SGIX_shadow + GLEW_SGIX_shadow = _glewSearchExtension("GL_SGIX_shadow", extStart, extEnd); +#endif /* GL_SGIX_shadow */ +#ifdef GL_SGIX_shadow_ambient + GLEW_SGIX_shadow_ambient = _glewSearchExtension("GL_SGIX_shadow_ambient", extStart, extEnd); +#endif /* GL_SGIX_shadow_ambient */ +#ifdef GL_SGIX_sprite + GLEW_SGIX_sprite = _glewSearchExtension("GL_SGIX_sprite", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_sprite) GLEW_SGIX_sprite = !_glewInit_GL_SGIX_sprite(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_sprite */ +#ifdef GL_SGIX_tag_sample_buffer + GLEW_SGIX_tag_sample_buffer = _glewSearchExtension("GL_SGIX_tag_sample_buffer", extStart, extEnd); + if (glewExperimental || GLEW_SGIX_tag_sample_buffer) 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 + GLEW_SGIX_texture_add_env = _glewSearchExtension("GL_SGIX_texture_add_env", extStart, extEnd); +#endif /* GL_SGIX_texture_add_env */ +#ifdef GL_SGIX_texture_coordinate_clamp + GLEW_SGIX_texture_coordinate_clamp = _glewSearchExtension("GL_SGIX_texture_coordinate_clamp", extStart, extEnd); +#endif /* GL_SGIX_texture_coordinate_clamp */ +#ifdef GL_SGIX_texture_lod_bias + GLEW_SGIX_texture_lod_bias = _glewSearchExtension("GL_SGIX_texture_lod_bias", extStart, extEnd); +#endif /* GL_SGIX_texture_lod_bias */ +#ifdef GL_SGIX_texture_multi_buffer + GLEW_SGIX_texture_multi_buffer = _glewSearchExtension("GL_SGIX_texture_multi_buffer", extStart, extEnd); +#endif /* GL_SGIX_texture_multi_buffer */ +#ifdef GL_SGIX_texture_range + GLEW_SGIX_texture_range = _glewSearchExtension("GL_SGIX_texture_range", extStart, extEnd); +#endif /* GL_SGIX_texture_range */ +#ifdef GL_SGIX_texture_scale_bias + GLEW_SGIX_texture_scale_bias = _glewSearchExtension("GL_SGIX_texture_scale_bias", extStart, extEnd); +#endif /* GL_SGIX_texture_scale_bias */ +#ifdef GL_SGIX_vertex_preclip + GLEW_SGIX_vertex_preclip = _glewSearchExtension("GL_SGIX_vertex_preclip", extStart, extEnd); +#endif /* GL_SGIX_vertex_preclip */ +#ifdef GL_SGIX_vertex_preclip_hint + GLEW_SGIX_vertex_preclip_hint = _glewSearchExtension("GL_SGIX_vertex_preclip_hint", extStart, extEnd); +#endif /* GL_SGIX_vertex_preclip_hint */ +#ifdef GL_SGIX_ycrcb + GLEW_SGIX_ycrcb = _glewSearchExtension("GL_SGIX_ycrcb", extStart, extEnd); +#endif /* GL_SGIX_ycrcb */ +#ifdef GL_SGI_color_matrix + GLEW_SGI_color_matrix = _glewSearchExtension("GL_SGI_color_matrix", extStart, extEnd); +#endif /* GL_SGI_color_matrix */ +#ifdef GL_SGI_color_table + GLEW_SGI_color_table = _glewSearchExtension("GL_SGI_color_table", extStart, extEnd); + if (glewExperimental || GLEW_SGI_color_table) 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 + GLEW_SGI_texture_color_table = _glewSearchExtension("GL_SGI_texture_color_table", extStart, extEnd); +#endif /* GL_SGI_texture_color_table */ +#ifdef GL_SUNX_constant_data + GLEW_SUNX_constant_data = _glewSearchExtension("GL_SUNX_constant_data", extStart, extEnd); + if (glewExperimental || GLEW_SUNX_constant_data) 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 + GLEW_SUN_convolution_border_modes = _glewSearchExtension("GL_SUN_convolution_border_modes", extStart, extEnd); +#endif /* GL_SUN_convolution_border_modes */ +#ifdef GL_SUN_global_alpha + GLEW_SUN_global_alpha = _glewSearchExtension("GL_SUN_global_alpha", extStart, extEnd); + if (glewExperimental || GLEW_SUN_global_alpha) GLEW_SUN_global_alpha = !_glewInit_GL_SUN_global_alpha(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_global_alpha */ +#ifdef GL_SUN_mesh_array + GLEW_SUN_mesh_array = _glewSearchExtension("GL_SUN_mesh_array", extStart, extEnd); +#endif /* GL_SUN_mesh_array */ +#ifdef GL_SUN_read_video_pixels + GLEW_SUN_read_video_pixels = _glewSearchExtension("GL_SUN_read_video_pixels", extStart, extEnd); + if (glewExperimental || GLEW_SUN_read_video_pixels) 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 + GLEW_SUN_slice_accum = _glewSearchExtension("GL_SUN_slice_accum", extStart, extEnd); +#endif /* GL_SUN_slice_accum */ +#ifdef GL_SUN_triangle_list + GLEW_SUN_triangle_list = _glewSearchExtension("GL_SUN_triangle_list", extStart, extEnd); + if (glewExperimental || GLEW_SUN_triangle_list) GLEW_SUN_triangle_list = !_glewInit_GL_SUN_triangle_list(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_triangle_list */ +#ifdef GL_SUN_vertex + GLEW_SUN_vertex = _glewSearchExtension("GL_SUN_vertex", extStart, extEnd); + if (glewExperimental || GLEW_SUN_vertex) GLEW_SUN_vertex = !_glewInit_GL_SUN_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_vertex */ +#ifdef GL_WIN_phong_shading + GLEW_WIN_phong_shading = _glewSearchExtension("GL_WIN_phong_shading", extStart, extEnd); +#endif /* GL_WIN_phong_shading */ +#ifdef GL_WIN_specular_fog + GLEW_WIN_specular_fog = _glewSearchExtension("GL_WIN_specular_fog", extStart, extEnd); +#endif /* GL_WIN_specular_fog */ +#ifdef GL_WIN_swap_hint + GLEW_WIN_swap_hint = _glewSearchExtension("GL_WIN_swap_hint", extStart, extEnd); + if (glewExperimental || GLEW_WIN_swap_hint) 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; + +PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD = NULL; +PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD = NULL; +PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD = NULL; +PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD = NULL; +PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD = NULL; +PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD = NULL; +PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD = NULL; +PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD = NULL; +PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD = 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; + +PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV = NULL; +PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV = NULL; +PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV = NULL; +PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV = NULL; +PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV = NULL; +PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV = NULL; +PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV = NULL; +PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV = NULL; + +PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV = NULL; + +PFNWGLDELAYBEFORESWAPNVPROC __wglewDelayBeforeSwapNV = 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; + +PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV = NULL; +PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV = NULL; +PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV = NULL; +PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV = NULL; +PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV = 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_AMD_gpu_association = GL_FALSE; +GLboolean __WGLEW_ARB_buffer_region = GL_FALSE; +GLboolean __WGLEW_ARB_create_context = GL_FALSE; +GLboolean __WGLEW_ARB_create_context_profile = GL_FALSE; +GLboolean __WGLEW_ARB_create_context_robustness = 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_ARB_robustness_application_isolation = GL_FALSE; +GLboolean __WGLEW_ARB_robustness_share_group_isolation = GL_FALSE; +GLboolean __WGLEW_ATI_pixel_format_float = GL_FALSE; +GLboolean __WGLEW_ATI_render_texture_rectangle = GL_FALSE; +GLboolean __WGLEW_EXT_create_context_es2_profile = GL_FALSE; +GLboolean __WGLEW_EXT_create_context_es_profile = 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_EXT_swap_control_tear = 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_DX_interop = GL_FALSE; +GLboolean __WGLEW_NV_DX_interop2 = GL_FALSE; +GLboolean __WGLEW_NV_copy_image = GL_FALSE; +GLboolean __WGLEW_NV_delay_before_swap = GL_FALSE; +GLboolean __WGLEW_NV_float_buffer = GL_FALSE; +GLboolean __WGLEW_NV_gpu_affinity = GL_FALSE; +GLboolean __WGLEW_NV_multisample_coverage = 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_capture = 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_AMD_gpu_association + +static GLboolean _glewInit_WGL_AMD_gpu_association (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBlitContextFramebufferAMD = (PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)glewGetProcAddress((const GLubyte*)"wglBlitContextFramebufferAMD")) == NULL) || r; + r = ((wglCreateAssociatedContextAMD = (PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglCreateAssociatedContextAMD")) == NULL) || r; + r = ((wglCreateAssociatedContextAttribsAMD = (PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)glewGetProcAddress((const GLubyte*)"wglCreateAssociatedContextAttribsAMD")) == NULL) || r; + r = ((wglDeleteAssociatedContextAMD = (PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglDeleteAssociatedContextAMD")) == NULL) || r; + r = ((wglGetContextGPUIDAMD = (PFNWGLGETCONTEXTGPUIDAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetContextGPUIDAMD")) == NULL) || r; + r = ((wglGetCurrentAssociatedContextAMD = (PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentAssociatedContextAMD")) == NULL) || r; + r = ((wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetGPUIDsAMD")) == NULL) || r; + r = ((wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetGPUInfoAMD")) == NULL) || r; + r = ((wglMakeAssociatedContextCurrentAMD = (PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)glewGetProcAddress((const GLubyte*)"wglMakeAssociatedContextCurrentAMD")) == NULL) || r; + + return r; +} + +#endif /* WGL_AMD_gpu_association */ + +#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_create_context_profile + +#endif /* WGL_ARB_create_context_profile */ + +#ifdef WGL_ARB_create_context_robustness + +#endif /* WGL_ARB_create_context_robustness */ + +#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_ARB_robustness_application_isolation + +#endif /* WGL_ARB_robustness_application_isolation */ + +#ifdef WGL_ARB_robustness_share_group_isolation + +#endif /* WGL_ARB_robustness_share_group_isolation */ + +#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_create_context_es2_profile + +#endif /* WGL_EXT_create_context_es2_profile */ + +#ifdef WGL_EXT_create_context_es_profile + +#endif /* WGL_EXT_create_context_es_profile */ + +#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_EXT_swap_control_tear + +#endif /* WGL_EXT_swap_control_tear */ + +#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_DX_interop + +static GLboolean _glewInit_WGL_NV_DX_interop (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglDXCloseDeviceNV = (PFNWGLDXCLOSEDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglDXCloseDeviceNV")) == NULL) || r; + r = ((wglDXLockObjectsNV = (PFNWGLDXLOCKOBJECTSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXLockObjectsNV")) == NULL) || r; + r = ((wglDXObjectAccessNV = (PFNWGLDXOBJECTACCESSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXObjectAccessNV")) == NULL) || r; + r = ((wglDXOpenDeviceNV = (PFNWGLDXOPENDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglDXOpenDeviceNV")) == NULL) || r; + r = ((wglDXRegisterObjectNV = (PFNWGLDXREGISTEROBJECTNVPROC)glewGetProcAddress((const GLubyte*)"wglDXRegisterObjectNV")) == NULL) || r; + r = ((wglDXSetResourceShareHandleNV = (PFNWGLDXSETRESOURCESHAREHANDLENVPROC)glewGetProcAddress((const GLubyte*)"wglDXSetResourceShareHandleNV")) == NULL) || r; + r = ((wglDXUnlockObjectsNV = (PFNWGLDXUNLOCKOBJECTSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXUnlockObjectsNV")) == NULL) || r; + r = ((wglDXUnregisterObjectNV = (PFNWGLDXUNREGISTEROBJECTNVPROC)glewGetProcAddress((const GLubyte*)"wglDXUnregisterObjectNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_DX_interop */ + +#ifdef WGL_NV_DX_interop2 + +#endif /* WGL_NV_DX_interop2 */ + +#ifdef WGL_NV_copy_image + +static GLboolean _glewInit_WGL_NV_copy_image (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCopyImageSubDataNV = (PFNWGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"wglCopyImageSubDataNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_copy_image */ + +#ifdef WGL_NV_delay_before_swap + +static GLboolean _glewInit_WGL_NV_delay_before_swap (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglDelayBeforeSwapNV = (PFNWGLDELAYBEFORESWAPNVPROC)glewGetProcAddress((const GLubyte*)"wglDelayBeforeSwapNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_delay_before_swap */ + +#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_multisample_coverage + +#endif /* WGL_NV_multisample_coverage */ + +#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_capture + +static GLboolean _glewInit_WGL_NV_video_capture (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindVideoCaptureDeviceNV = (PFNWGLBINDVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoCaptureDeviceNV")) == NULL) || r; + r = ((wglEnumerateVideoCaptureDevicesNV = (PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumerateVideoCaptureDevicesNV")) == NULL) || r; + r = ((wglLockVideoCaptureDeviceNV = (PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglLockVideoCaptureDeviceNV")) == NULL) || r; + r = ((wglQueryVideoCaptureDeviceNV = (PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglQueryVideoCaptureDeviceNV")) == NULL) || r; + r = ((wglReleaseVideoCaptureDeviceNV = (PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoCaptureDeviceNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_video_capture */ + +#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 GLEWAPIENTRY wglewGetExtension (const char* name) +{ + const GLubyte* start; + const GLubyte* end; + if (_wglewGetExtensionsStringARB == NULL) + if (_wglewGetExtensionsStringEXT == NULL) + return GL_FALSE; + else + start = (const GLubyte*)_wglewGetExtensionsStringEXT(); + else + start = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); + if (start == 0) + return GL_FALSE; + end = start + _glewStrLen(start); + return _glewSearchExtension(name, start, end); +} + +GLenum GLEWAPIENTRY wglewContextInit (WGLEW_CONTEXT_ARG_DEF_LIST) +{ + GLboolean crippled; + const GLubyte* extStart; + const GLubyte* extEnd; + /* find wgl extension string query functions */ + _wglewGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB"); + _wglewGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT"); + /* query wgl extension string */ + if (_wglewGetExtensionsStringARB == NULL) + if (_wglewGetExtensionsStringEXT == NULL) + extStart = (const GLubyte*)""; + else + extStart = (const GLubyte*)_wglewGetExtensionsStringEXT(); + else + extStart = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); + extEnd = extStart + _glewStrLen(extStart); + /* initialize extensions */ + crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL; +#ifdef WGL_3DFX_multisample + WGLEW_3DFX_multisample = _glewSearchExtension("WGL_3DFX_multisample", extStart, extEnd); +#endif /* WGL_3DFX_multisample */ +#ifdef WGL_3DL_stereo_control + WGLEW_3DL_stereo_control = _glewSearchExtension("WGL_3DL_stereo_control", extStart, extEnd); + if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) WGLEW_3DL_stereo_control= !_glewInit_WGL_3DL_stereo_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_3DL_stereo_control */ +#ifdef WGL_AMD_gpu_association + WGLEW_AMD_gpu_association = _glewSearchExtension("WGL_AMD_gpu_association", extStart, extEnd); + if (glewExperimental || WGLEW_AMD_gpu_association|| crippled) WGLEW_AMD_gpu_association= !_glewInit_WGL_AMD_gpu_association(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_AMD_gpu_association */ +#ifdef WGL_ARB_buffer_region + WGLEW_ARB_buffer_region = _glewSearchExtension("WGL_ARB_buffer_region", extStart, extEnd); + if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) WGLEW_ARB_buffer_region= !_glewInit_WGL_ARB_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_buffer_region */ +#ifdef WGL_ARB_create_context + WGLEW_ARB_create_context = _glewSearchExtension("WGL_ARB_create_context", extStart, extEnd); + if (glewExperimental || WGLEW_ARB_create_context|| crippled) WGLEW_ARB_create_context= !_glewInit_WGL_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_create_context */ +#ifdef WGL_ARB_create_context_profile + WGLEW_ARB_create_context_profile = _glewSearchExtension("WGL_ARB_create_context_profile", extStart, extEnd); +#endif /* WGL_ARB_create_context_profile */ +#ifdef WGL_ARB_create_context_robustness + WGLEW_ARB_create_context_robustness = _glewSearchExtension("WGL_ARB_create_context_robustness", extStart, extEnd); +#endif /* WGL_ARB_create_context_robustness */ +#ifdef WGL_ARB_extensions_string + WGLEW_ARB_extensions_string = _glewSearchExtension("WGL_ARB_extensions_string", extStart, extEnd); + if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) WGLEW_ARB_extensions_string= !_glewInit_WGL_ARB_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_extensions_string */ +#ifdef WGL_ARB_framebuffer_sRGB + WGLEW_ARB_framebuffer_sRGB = _glewSearchExtension("WGL_ARB_framebuffer_sRGB", extStart, extEnd); +#endif /* WGL_ARB_framebuffer_sRGB */ +#ifdef WGL_ARB_make_current_read + WGLEW_ARB_make_current_read = _glewSearchExtension("WGL_ARB_make_current_read", extStart, extEnd); + if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) 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 + WGLEW_ARB_multisample = _glewSearchExtension("WGL_ARB_multisample", extStart, extEnd); +#endif /* WGL_ARB_multisample */ +#ifdef WGL_ARB_pbuffer + WGLEW_ARB_pbuffer = _glewSearchExtension("WGL_ARB_pbuffer", extStart, extEnd); + if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) WGLEW_ARB_pbuffer= !_glewInit_WGL_ARB_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_pbuffer */ +#ifdef WGL_ARB_pixel_format + WGLEW_ARB_pixel_format = _glewSearchExtension("WGL_ARB_pixel_format", extStart, extEnd); + if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) 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 + WGLEW_ARB_pixel_format_float = _glewSearchExtension("WGL_ARB_pixel_format_float", extStart, extEnd); +#endif /* WGL_ARB_pixel_format_float */ +#ifdef WGL_ARB_render_texture + WGLEW_ARB_render_texture = _glewSearchExtension("WGL_ARB_render_texture", extStart, extEnd); + if (glewExperimental || WGLEW_ARB_render_texture|| crippled) WGLEW_ARB_render_texture= !_glewInit_WGL_ARB_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_render_texture */ +#ifdef WGL_ARB_robustness_application_isolation + WGLEW_ARB_robustness_application_isolation = _glewSearchExtension("WGL_ARB_robustness_application_isolation", extStart, extEnd); +#endif /* WGL_ARB_robustness_application_isolation */ +#ifdef WGL_ARB_robustness_share_group_isolation + WGLEW_ARB_robustness_share_group_isolation = _glewSearchExtension("WGL_ARB_robustness_share_group_isolation", extStart, extEnd); +#endif /* WGL_ARB_robustness_share_group_isolation */ +#ifdef WGL_ATI_pixel_format_float + WGLEW_ATI_pixel_format_float = _glewSearchExtension("WGL_ATI_pixel_format_float", extStart, extEnd); +#endif /* WGL_ATI_pixel_format_float */ +#ifdef WGL_ATI_render_texture_rectangle + WGLEW_ATI_render_texture_rectangle = _glewSearchExtension("WGL_ATI_render_texture_rectangle", extStart, extEnd); +#endif /* WGL_ATI_render_texture_rectangle */ +#ifdef WGL_EXT_create_context_es2_profile + WGLEW_EXT_create_context_es2_profile = _glewSearchExtension("WGL_EXT_create_context_es2_profile", extStart, extEnd); +#endif /* WGL_EXT_create_context_es2_profile */ +#ifdef WGL_EXT_create_context_es_profile + WGLEW_EXT_create_context_es_profile = _glewSearchExtension("WGL_EXT_create_context_es_profile", extStart, extEnd); +#endif /* WGL_EXT_create_context_es_profile */ +#ifdef WGL_EXT_depth_float + WGLEW_EXT_depth_float = _glewSearchExtension("WGL_EXT_depth_float", extStart, extEnd); +#endif /* WGL_EXT_depth_float */ +#ifdef WGL_EXT_display_color_table + WGLEW_EXT_display_color_table = _glewSearchExtension("WGL_EXT_display_color_table", extStart, extEnd); + if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) 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 + WGLEW_EXT_extensions_string = _glewSearchExtension("WGL_EXT_extensions_string", extStart, extEnd); + if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) WGLEW_EXT_extensions_string= !_glewInit_WGL_EXT_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_extensions_string */ +#ifdef WGL_EXT_framebuffer_sRGB + WGLEW_EXT_framebuffer_sRGB = _glewSearchExtension("WGL_EXT_framebuffer_sRGB", extStart, extEnd); +#endif /* WGL_EXT_framebuffer_sRGB */ +#ifdef WGL_EXT_make_current_read + WGLEW_EXT_make_current_read = _glewSearchExtension("WGL_EXT_make_current_read", extStart, extEnd); + if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) 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 + WGLEW_EXT_multisample = _glewSearchExtension("WGL_EXT_multisample", extStart, extEnd); +#endif /* WGL_EXT_multisample */ +#ifdef WGL_EXT_pbuffer + WGLEW_EXT_pbuffer = _glewSearchExtension("WGL_EXT_pbuffer", extStart, extEnd); + if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) WGLEW_EXT_pbuffer= !_glewInit_WGL_EXT_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_pbuffer */ +#ifdef WGL_EXT_pixel_format + WGLEW_EXT_pixel_format = _glewSearchExtension("WGL_EXT_pixel_format", extStart, extEnd); + if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) 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 + WGLEW_EXT_pixel_format_packed_float = _glewSearchExtension("WGL_EXT_pixel_format_packed_float", extStart, extEnd); +#endif /* WGL_EXT_pixel_format_packed_float */ +#ifdef WGL_EXT_swap_control + WGLEW_EXT_swap_control = _glewSearchExtension("WGL_EXT_swap_control", extStart, extEnd); + if (glewExperimental || WGLEW_EXT_swap_control|| crippled) WGLEW_EXT_swap_control= !_glewInit_WGL_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_swap_control */ +#ifdef WGL_EXT_swap_control_tear + WGLEW_EXT_swap_control_tear = _glewSearchExtension("WGL_EXT_swap_control_tear", extStart, extEnd); +#endif /* WGL_EXT_swap_control_tear */ +#ifdef WGL_I3D_digital_video_control + WGLEW_I3D_digital_video_control = _glewSearchExtension("WGL_I3D_digital_video_control", extStart, extEnd); + if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) 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 + WGLEW_I3D_gamma = _glewSearchExtension("WGL_I3D_gamma", extStart, extEnd); + if (glewExperimental || WGLEW_I3D_gamma|| crippled) WGLEW_I3D_gamma= !_glewInit_WGL_I3D_gamma(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_gamma */ +#ifdef WGL_I3D_genlock + WGLEW_I3D_genlock = _glewSearchExtension("WGL_I3D_genlock", extStart, extEnd); + if (glewExperimental || WGLEW_I3D_genlock|| crippled) WGLEW_I3D_genlock= !_glewInit_WGL_I3D_genlock(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_genlock */ +#ifdef WGL_I3D_image_buffer + WGLEW_I3D_image_buffer = _glewSearchExtension("WGL_I3D_image_buffer", extStart, extEnd); + if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) 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 + WGLEW_I3D_swap_frame_lock = _glewSearchExtension("WGL_I3D_swap_frame_lock", extStart, extEnd); + if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) 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 + WGLEW_I3D_swap_frame_usage = _glewSearchExtension("WGL_I3D_swap_frame_usage", extStart, extEnd); + if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) 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_DX_interop + WGLEW_NV_DX_interop = _glewSearchExtension("WGL_NV_DX_interop", extStart, extEnd); + if (glewExperimental || WGLEW_NV_DX_interop|| crippled) WGLEW_NV_DX_interop= !_glewInit_WGL_NV_DX_interop(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_DX_interop */ +#ifdef WGL_NV_DX_interop2 + WGLEW_NV_DX_interop2 = _glewSearchExtension("WGL_NV_DX_interop2", extStart, extEnd); +#endif /* WGL_NV_DX_interop2 */ +#ifdef WGL_NV_copy_image + WGLEW_NV_copy_image = _glewSearchExtension("WGL_NV_copy_image", extStart, extEnd); + if (glewExperimental || WGLEW_NV_copy_image|| crippled) WGLEW_NV_copy_image= !_glewInit_WGL_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_copy_image */ +#ifdef WGL_NV_delay_before_swap + WGLEW_NV_delay_before_swap = _glewSearchExtension("WGL_NV_delay_before_swap", extStart, extEnd); + if (glewExperimental || WGLEW_NV_delay_before_swap|| crippled) WGLEW_NV_delay_before_swap= !_glewInit_WGL_NV_delay_before_swap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_delay_before_swap */ +#ifdef WGL_NV_float_buffer + WGLEW_NV_float_buffer = _glewSearchExtension("WGL_NV_float_buffer", extStart, extEnd); +#endif /* WGL_NV_float_buffer */ +#ifdef WGL_NV_gpu_affinity + WGLEW_NV_gpu_affinity = _glewSearchExtension("WGL_NV_gpu_affinity", extStart, extEnd); + if (glewExperimental || WGLEW_NV_gpu_affinity|| crippled) WGLEW_NV_gpu_affinity= !_glewInit_WGL_NV_gpu_affinity(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_gpu_affinity */ +#ifdef WGL_NV_multisample_coverage + WGLEW_NV_multisample_coverage = _glewSearchExtension("WGL_NV_multisample_coverage", extStart, extEnd); +#endif /* WGL_NV_multisample_coverage */ +#ifdef WGL_NV_present_video + WGLEW_NV_present_video = _glewSearchExtension("WGL_NV_present_video", extStart, extEnd); + if (glewExperimental || WGLEW_NV_present_video|| crippled) 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 + WGLEW_NV_render_depth_texture = _glewSearchExtension("WGL_NV_render_depth_texture", extStart, extEnd); +#endif /* WGL_NV_render_depth_texture */ +#ifdef WGL_NV_render_texture_rectangle + WGLEW_NV_render_texture_rectangle = _glewSearchExtension("WGL_NV_render_texture_rectangle", extStart, extEnd); +#endif /* WGL_NV_render_texture_rectangle */ +#ifdef WGL_NV_swap_group + WGLEW_NV_swap_group = _glewSearchExtension("WGL_NV_swap_group", extStart, extEnd); + if (glewExperimental || WGLEW_NV_swap_group|| crippled) 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 + WGLEW_NV_vertex_array_range = _glewSearchExtension("WGL_NV_vertex_array_range", extStart, extEnd); + if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) 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_capture + WGLEW_NV_video_capture = _glewSearchExtension("WGL_NV_video_capture", extStart, extEnd); + if (glewExperimental || WGLEW_NV_video_capture|| crippled) WGLEW_NV_video_capture= !_glewInit_WGL_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_video_capture */ +#ifdef WGL_NV_video_output + WGLEW_NV_video_output = _glewSearchExtension("WGL_NV_video_output", extStart, extEnd); + if (glewExperimental || WGLEW_NV_video_output|| crippled) WGLEW_NV_video_output= !_glewInit_WGL_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_video_output */ +#ifdef WGL_OML_sync_control + WGLEW_OML_sync_control = _glewSearchExtension("WGL_OML_sync_control", extStart, extEnd); + if (glewExperimental || WGLEW_OML_sync_control|| crippled) WGLEW_OML_sync_control= !_glewInit_WGL_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_OML_sync_control */ + + return GLEW_OK; +} + +#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!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; + +PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC __glewXBlitContextFramebufferAMD = NULL; +PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC __glewXCreateAssociatedContextAMD = NULL; +PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __glewXCreateAssociatedContextAttribsAMD = NULL; +PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC __glewXDeleteAssociatedContextAMD = NULL; +PFNGLXGETCONTEXTGPUIDAMDPROC __glewXGetContextGPUIDAMD = NULL; +PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC __glewXGetCurrentAssociatedContextAMD = NULL; +PFNGLXGETGPUIDSAMDPROC __glewXGetGPUIDsAMD = NULL; +PFNGLXGETGPUINFOAMDPROC __glewXGetGPUInfoAMD = NULL; +PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __glewXMakeAssociatedContextCurrentAMD = 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; + +PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT = NULL; + +PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT = NULL; +PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT = NULL; + +PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA = NULL; + +PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA = NULL; + +PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA = NULL; + +PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC __glewXQueryCurrentRendererIntegerMESA = NULL; +PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC __glewXQueryCurrentRendererStringMESA = NULL; +PFNGLXQUERYRENDERERINTEGERMESAPROC __glewXQueryRendererIntegerMESA = NULL; +PFNGLXQUERYRENDERERSTRINGMESAPROC __glewXQueryRendererStringMESA = NULL; + +PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA = NULL; + +PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA = NULL; + +PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA = NULL; +PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA = NULL; + +PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV = NULL; + +PFNGLXDELAYBEFORESWAPNVPROC __glewXDelayBeforeSwapNV = 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; + +PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV = NULL; +PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV = NULL; +PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV = NULL; +PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV = NULL; +PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV = NULL; + +PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV = NULL; +PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV = NULL; +PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV = NULL; +PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV = NULL; +PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV = NULL; +PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV = NULL; + +PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML = NULL; +PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML = NULL; +PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML = NULL; +PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML = NULL; +PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML = NULL; + +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_AMD_gpu_association = GL_FALSE; +GLboolean __GLXEW_ARB_create_context = GL_FALSE; +GLboolean __GLXEW_ARB_create_context_profile = GL_FALSE; +GLboolean __GLXEW_ARB_create_context_robustness = 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_ARB_robustness_application_isolation = GL_FALSE; +GLboolean __GLXEW_ARB_robustness_share_group_isolation = GL_FALSE; +GLboolean __GLXEW_ARB_vertex_buffer_object = GL_FALSE; +GLboolean __GLXEW_ATI_pixel_format_float = GL_FALSE; +GLboolean __GLXEW_ATI_render_texture = GL_FALSE; +GLboolean __GLXEW_EXT_buffer_age = GL_FALSE; +GLboolean __GLXEW_EXT_create_context_es2_profile = GL_FALSE; +GLboolean __GLXEW_EXT_create_context_es_profile = 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_stereo_tree = GL_FALSE; +GLboolean __GLXEW_EXT_swap_control = GL_FALSE; +GLboolean __GLXEW_EXT_swap_control_tear = 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_INTEL_swap_event = 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_query_renderer = GL_FALSE; +GLboolean __GLXEW_MESA_release_buffers = GL_FALSE; +GLboolean __GLXEW_MESA_set_3dfx_mode = GL_FALSE; +GLboolean __GLXEW_MESA_swap_control = GL_FALSE; +GLboolean __GLXEW_NV_copy_image = GL_FALSE; +GLboolean __GLXEW_NV_delay_before_swap = GL_FALSE; +GLboolean __GLXEW_NV_float_buffer = GL_FALSE; +GLboolean __GLXEW_NV_multisample_coverage = 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_capture = GL_FALSE; +GLboolean __GLXEW_NV_video_out = GL_FALSE; +GLboolean __GLXEW_OML_swap_method = GL_FALSE; +GLboolean __GLXEW_OML_sync_control = GL_FALSE; +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_AMD_gpu_association + +static GLboolean _glewInit_GLX_AMD_gpu_association (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBlitContextFramebufferAMD = (PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC)glewGetProcAddress((const GLubyte*)"glXBlitContextFramebufferAMD")) == NULL) || r; + r = ((glXCreateAssociatedContextAMD = (PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXCreateAssociatedContextAMD")) == NULL) || r; + r = ((glXCreateAssociatedContextAttribsAMD = (PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)glewGetProcAddress((const GLubyte*)"glXCreateAssociatedContextAttribsAMD")) == NULL) || r; + r = ((glXDeleteAssociatedContextAMD = (PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXDeleteAssociatedContextAMD")) == NULL) || r; + r = ((glXGetContextGPUIDAMD = (PFNGLXGETCONTEXTGPUIDAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetContextGPUIDAMD")) == NULL) || r; + r = ((glXGetCurrentAssociatedContextAMD = (PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentAssociatedContextAMD")) == NULL) || r; + r = ((glXGetGPUIDsAMD = (PFNGLXGETGPUIDSAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetGPUIDsAMD")) == NULL) || r; + r = ((glXGetGPUInfoAMD = (PFNGLXGETGPUINFOAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetGPUInfoAMD")) == NULL) || r; + r = ((glXMakeAssociatedContextCurrentAMD = (PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)glewGetProcAddress((const GLubyte*)"glXMakeAssociatedContextCurrentAMD")) == NULL) || r; + + return r; +} + +#endif /* GLX_AMD_gpu_association */ + +#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_create_context_profile + +#endif /* GLX_ARB_create_context_profile */ + +#ifdef GLX_ARB_create_context_robustness + +#endif /* GLX_ARB_create_context_robustness */ + +#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_ARB_robustness_application_isolation + +#endif /* GLX_ARB_robustness_application_isolation */ + +#ifdef GLX_ARB_robustness_share_group_isolation + +#endif /* GLX_ARB_robustness_share_group_isolation */ + +#ifdef GLX_ARB_vertex_buffer_object + +#endif /* GLX_ARB_vertex_buffer_object */ + +#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_buffer_age + +#endif /* GLX_EXT_buffer_age */ + +#ifdef GLX_EXT_create_context_es2_profile + +#endif /* GLX_EXT_create_context_es2_profile */ + +#ifdef GLX_EXT_create_context_es_profile + +#endif /* GLX_EXT_create_context_es_profile */ + +#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_stereo_tree + +#endif /* GLX_EXT_stereo_tree */ + +#ifdef GLX_EXT_swap_control + +static GLboolean _glewInit_GLX_EXT_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalEXT")) == NULL) || r; + + return r; +} + +#endif /* GLX_EXT_swap_control */ + +#ifdef GLX_EXT_swap_control_tear + +#endif /* GLX_EXT_swap_control_tear */ + +#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_INTEL_swap_event + +#endif /* GLX_INTEL_swap_event */ + +#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_query_renderer + +static GLboolean _glewInit_GLX_MESA_query_renderer (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXQueryCurrentRendererIntegerMESA = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)glewGetProcAddress((const GLubyte*)"glXQueryCurrentRendererIntegerMESA")) == NULL) || r; + r = ((glXQueryCurrentRendererStringMESA = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC)glewGetProcAddress((const GLubyte*)"glXQueryCurrentRendererStringMESA")) == NULL) || r; + r = ((glXQueryRendererIntegerMESA = (PFNGLXQUERYRENDERERINTEGERMESAPROC)glewGetProcAddress((const GLubyte*)"glXQueryRendererIntegerMESA")) == NULL) || r; + r = ((glXQueryRendererStringMESA = (PFNGLXQUERYRENDERERSTRINGMESAPROC)glewGetProcAddress((const GLubyte*)"glXQueryRendererStringMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_query_renderer */ + +#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_MESA_swap_control + +static GLboolean _glewInit_GLX_MESA_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetSwapIntervalMESA")) == NULL) || r; + r = ((glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_swap_control */ + +#ifdef GLX_NV_copy_image + +static GLboolean _glewInit_GLX_NV_copy_image (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCopyImageSubDataNV = (PFNGLXCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glXCopyImageSubDataNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_copy_image */ + +#ifdef GLX_NV_delay_before_swap + +static GLboolean _glewInit_GLX_NV_delay_before_swap (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXDelayBeforeSwapNV = (PFNGLXDELAYBEFORESWAPNVPROC)glewGetProcAddress((const GLubyte*)"glXDelayBeforeSwapNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_delay_before_swap */ + +#ifdef GLX_NV_float_buffer + +#endif /* GLX_NV_float_buffer */ + +#ifdef GLX_NV_multisample_coverage + +#endif /* GLX_NV_multisample_coverage */ + +#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_capture + +static GLboolean _glewInit_GLX_NV_video_capture (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindVideoCaptureDeviceNV = (PFNGLXBINDVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoCaptureDeviceNV")) == NULL) || r; + r = ((glXEnumerateVideoCaptureDevicesNV = (PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"glXEnumerateVideoCaptureDevicesNV")) == NULL) || r; + r = ((glXLockVideoCaptureDeviceNV = (PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXLockVideoCaptureDeviceNV")) == NULL) || r; + r = ((glXQueryVideoCaptureDeviceNV = (PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXQueryVideoCaptureDeviceNV")) == NULL) || r; + r = ((glXReleaseVideoCaptureDeviceNV = (PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoCaptureDeviceNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_video_capture */ + +#ifdef GLX_NV_video_out + +static GLboolean _glewInit_GLX_NV_video_out (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_out */ + +#ifdef GLX_OML_swap_method + +#endif /* GLX_OML_swap_method */ + +#ifdef GLX_OML_sync_control + +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) +{ + const GLubyte* start; + const GLubyte* end; + + if (glXGetCurrentDisplay == NULL) return GL_FALSE; + start = (const GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); + if (0 == start) return GL_FALSE; + end = start + _glewStrLen(start); + return _glewSearchExtension(name, start, end); +} + +GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST) +{ + int major, minor; + const GLubyte* extStart; + const GLubyte* extEnd; + /* 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 */ + GLXEW_VERSION_1_0 = GL_TRUE; + GLXEW_VERSION_1_1 = GL_TRUE; + GLXEW_VERSION_1_2 = GL_TRUE; + GLXEW_VERSION_1_3 = GL_TRUE; + GLXEW_VERSION_1_4 = GL_TRUE; + /* query GLX version */ + glXQueryVersion(glXGetCurrentDisplay(), &major, &minor); + if (major == 1 && minor <= 3) + { + switch (minor) + { + case 3: + GLXEW_VERSION_1_4 = GL_FALSE; + break; + case 2: + GLXEW_VERSION_1_4 = GL_FALSE; + GLXEW_VERSION_1_3 = GL_FALSE; + break; + default: + return GLEW_ERROR_GLX_VERSION_11_ONLY; + break; + } + } + /* query GLX extension string */ + extStart = 0; + if (glXGetCurrentDisplay != NULL) + extStart = (const GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); + if (extStart == 0) + extStart = (const GLubyte *)""; + extEnd = extStart + _glewStrLen(extStart); + /* initialize extensions */ +#ifdef GLX_VERSION_1_3 + if (glewExperimental || GLXEW_VERSION_1_3) GLXEW_VERSION_1_3 = !_glewInit_GLX_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_VERSION_1_3 */ +#ifdef GLX_3DFX_multisample + GLXEW_3DFX_multisample = _glewSearchExtension("GLX_3DFX_multisample", extStart, extEnd); +#endif /* GLX_3DFX_multisample */ +#ifdef GLX_AMD_gpu_association + GLXEW_AMD_gpu_association = _glewSearchExtension("GLX_AMD_gpu_association", extStart, extEnd); + if (glewExperimental || GLXEW_AMD_gpu_association) GLXEW_AMD_gpu_association = !_glewInit_GLX_AMD_gpu_association(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_AMD_gpu_association */ +#ifdef GLX_ARB_create_context + GLXEW_ARB_create_context = _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd); + if (glewExperimental || GLXEW_ARB_create_context) GLXEW_ARB_create_context = !_glewInit_GLX_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_ARB_create_context */ +#ifdef GLX_ARB_create_context_profile + GLXEW_ARB_create_context_profile = _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd); +#endif /* GLX_ARB_create_context_profile */ +#ifdef GLX_ARB_create_context_robustness + GLXEW_ARB_create_context_robustness = _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd); +#endif /* GLX_ARB_create_context_robustness */ +#ifdef GLX_ARB_fbconfig_float + GLXEW_ARB_fbconfig_float = _glewSearchExtension("GLX_ARB_fbconfig_float", extStart, extEnd); +#endif /* GLX_ARB_fbconfig_float */ +#ifdef GLX_ARB_framebuffer_sRGB + GLXEW_ARB_framebuffer_sRGB = _glewSearchExtension("GLX_ARB_framebuffer_sRGB", extStart, extEnd); +#endif /* GLX_ARB_framebuffer_sRGB */ +#ifdef GLX_ARB_get_proc_address + GLXEW_ARB_get_proc_address = _glewSearchExtension("GLX_ARB_get_proc_address", extStart, extEnd); +#endif /* GLX_ARB_get_proc_address */ +#ifdef GLX_ARB_multisample + GLXEW_ARB_multisample = _glewSearchExtension("GLX_ARB_multisample", extStart, extEnd); +#endif /* GLX_ARB_multisample */ +#ifdef GLX_ARB_robustness_application_isolation + GLXEW_ARB_robustness_application_isolation = _glewSearchExtension("GLX_ARB_robustness_application_isolation", extStart, extEnd); +#endif /* GLX_ARB_robustness_application_isolation */ +#ifdef GLX_ARB_robustness_share_group_isolation + GLXEW_ARB_robustness_share_group_isolation = _glewSearchExtension("GLX_ARB_robustness_share_group_isolation", extStart, extEnd); +#endif /* GLX_ARB_robustness_share_group_isolation */ +#ifdef GLX_ARB_vertex_buffer_object + GLXEW_ARB_vertex_buffer_object = _glewSearchExtension("GLX_ARB_vertex_buffer_object", extStart, extEnd); +#endif /* GLX_ARB_vertex_buffer_object */ +#ifdef GLX_ATI_pixel_format_float + GLXEW_ATI_pixel_format_float = _glewSearchExtension("GLX_ATI_pixel_format_float", extStart, extEnd); +#endif /* GLX_ATI_pixel_format_float */ +#ifdef GLX_ATI_render_texture + GLXEW_ATI_render_texture = _glewSearchExtension("GLX_ATI_render_texture", extStart, extEnd); + if (glewExperimental || GLXEW_ATI_render_texture) GLXEW_ATI_render_texture = !_glewInit_GLX_ATI_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_ATI_render_texture */ +#ifdef GLX_EXT_buffer_age + GLXEW_EXT_buffer_age = _glewSearchExtension("GLX_EXT_buffer_age", extStart, extEnd); +#endif /* GLX_EXT_buffer_age */ +#ifdef GLX_EXT_create_context_es2_profile + GLXEW_EXT_create_context_es2_profile = _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd); +#endif /* GLX_EXT_create_context_es2_profile */ +#ifdef GLX_EXT_create_context_es_profile + GLXEW_EXT_create_context_es_profile = _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd); +#endif /* GLX_EXT_create_context_es_profile */ +#ifdef GLX_EXT_fbconfig_packed_float + GLXEW_EXT_fbconfig_packed_float = _glewSearchExtension("GLX_EXT_fbconfig_packed_float", extStart, extEnd); +#endif /* GLX_EXT_fbconfig_packed_float */ +#ifdef GLX_EXT_framebuffer_sRGB + GLXEW_EXT_framebuffer_sRGB = _glewSearchExtension("GLX_EXT_framebuffer_sRGB", extStart, extEnd); +#endif /* GLX_EXT_framebuffer_sRGB */ +#ifdef GLX_EXT_import_context + GLXEW_EXT_import_context = _glewSearchExtension("GLX_EXT_import_context", extStart, extEnd); + if (glewExperimental || GLXEW_EXT_import_context) GLXEW_EXT_import_context = !_glewInit_GLX_EXT_import_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_EXT_import_context */ +#ifdef GLX_EXT_scene_marker + GLXEW_EXT_scene_marker = _glewSearchExtension("GLX_EXT_scene_marker", extStart, extEnd); +#endif /* GLX_EXT_scene_marker */ +#ifdef GLX_EXT_stereo_tree + GLXEW_EXT_stereo_tree = _glewSearchExtension("GLX_EXT_stereo_tree", extStart, extEnd); +#endif /* GLX_EXT_stereo_tree */ +#ifdef GLX_EXT_swap_control + GLXEW_EXT_swap_control = _glewSearchExtension("GLX_EXT_swap_control", extStart, extEnd); + if (glewExperimental || GLXEW_EXT_swap_control) GLXEW_EXT_swap_control = !_glewInit_GLX_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_EXT_swap_control */ +#ifdef GLX_EXT_swap_control_tear + GLXEW_EXT_swap_control_tear = _glewSearchExtension("GLX_EXT_swap_control_tear", extStart, extEnd); +#endif /* GLX_EXT_swap_control_tear */ +#ifdef GLX_EXT_texture_from_pixmap + GLXEW_EXT_texture_from_pixmap = _glewSearchExtension("GLX_EXT_texture_from_pixmap", extStart, extEnd); + if (glewExperimental || GLXEW_EXT_texture_from_pixmap) 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 + GLXEW_EXT_visual_info = _glewSearchExtension("GLX_EXT_visual_info", extStart, extEnd); +#endif /* GLX_EXT_visual_info */ +#ifdef GLX_EXT_visual_rating + GLXEW_EXT_visual_rating = _glewSearchExtension("GLX_EXT_visual_rating", extStart, extEnd); +#endif /* GLX_EXT_visual_rating */ +#ifdef GLX_INTEL_swap_event + GLXEW_INTEL_swap_event = _glewSearchExtension("GLX_INTEL_swap_event", extStart, extEnd); +#endif /* GLX_INTEL_swap_event */ +#ifdef GLX_MESA_agp_offset + GLXEW_MESA_agp_offset = _glewSearchExtension("GLX_MESA_agp_offset", extStart, extEnd); + if (glewExperimental || GLXEW_MESA_agp_offset) 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 + GLXEW_MESA_copy_sub_buffer = _glewSearchExtension("GLX_MESA_copy_sub_buffer", extStart, extEnd); + if (glewExperimental || GLXEW_MESA_copy_sub_buffer) 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 + GLXEW_MESA_pixmap_colormap = _glewSearchExtension("GLX_MESA_pixmap_colormap", extStart, extEnd); + if (glewExperimental || GLXEW_MESA_pixmap_colormap) GLXEW_MESA_pixmap_colormap = !_glewInit_GLX_MESA_pixmap_colormap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_pixmap_colormap */ +#ifdef GLX_MESA_query_renderer + GLXEW_MESA_query_renderer = _glewSearchExtension("GLX_MESA_query_renderer", extStart, extEnd); + if (glewExperimental || GLXEW_MESA_query_renderer) GLXEW_MESA_query_renderer = !_glewInit_GLX_MESA_query_renderer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_query_renderer */ +#ifdef GLX_MESA_release_buffers + GLXEW_MESA_release_buffers = _glewSearchExtension("GLX_MESA_release_buffers", extStart, extEnd); + if (glewExperimental || GLXEW_MESA_release_buffers) 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 + GLXEW_MESA_set_3dfx_mode = _glewSearchExtension("GLX_MESA_set_3dfx_mode", extStart, extEnd); + if (glewExperimental || GLXEW_MESA_set_3dfx_mode) GLXEW_MESA_set_3dfx_mode = !_glewInit_GLX_MESA_set_3dfx_mode(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_set_3dfx_mode */ +#ifdef GLX_MESA_swap_control + GLXEW_MESA_swap_control = _glewSearchExtension("GLX_MESA_swap_control", extStart, extEnd); + if (glewExperimental || GLXEW_MESA_swap_control) GLXEW_MESA_swap_control = !_glewInit_GLX_MESA_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_swap_control */ +#ifdef GLX_NV_copy_image + GLXEW_NV_copy_image = _glewSearchExtension("GLX_NV_copy_image", extStart, extEnd); + if (glewExperimental || GLXEW_NV_copy_image) GLXEW_NV_copy_image = !_glewInit_GLX_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_copy_image */ +#ifdef GLX_NV_delay_before_swap + GLXEW_NV_delay_before_swap = _glewSearchExtension("GLX_NV_delay_before_swap", extStart, extEnd); + if (glewExperimental || GLXEW_NV_delay_before_swap) GLXEW_NV_delay_before_swap = !_glewInit_GLX_NV_delay_before_swap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_delay_before_swap */ +#ifdef GLX_NV_float_buffer + GLXEW_NV_float_buffer = _glewSearchExtension("GLX_NV_float_buffer", extStart, extEnd); +#endif /* GLX_NV_float_buffer */ +#ifdef GLX_NV_multisample_coverage + GLXEW_NV_multisample_coverage = _glewSearchExtension("GLX_NV_multisample_coverage", extStart, extEnd); +#endif /* GLX_NV_multisample_coverage */ +#ifdef GLX_NV_present_video + GLXEW_NV_present_video = _glewSearchExtension("GLX_NV_present_video", extStart, extEnd); + if (glewExperimental || GLXEW_NV_present_video) GLXEW_NV_present_video = !_glewInit_GLX_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_present_video */ +#ifdef GLX_NV_swap_group + GLXEW_NV_swap_group = _glewSearchExtension("GLX_NV_swap_group", extStart, extEnd); + if (glewExperimental || GLXEW_NV_swap_group) 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 + GLXEW_NV_vertex_array_range = _glewSearchExtension("GLX_NV_vertex_array_range", extStart, extEnd); + if (glewExperimental || GLXEW_NV_vertex_array_range) 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_capture + GLXEW_NV_video_capture = _glewSearchExtension("GLX_NV_video_capture", extStart, extEnd); + if (glewExperimental || GLXEW_NV_video_capture) GLXEW_NV_video_capture = !_glewInit_GLX_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_video_capture */ +#ifdef GLX_NV_video_out + GLXEW_NV_video_out = _glewSearchExtension("GLX_NV_video_out", extStart, extEnd); + if (glewExperimental || GLXEW_NV_video_out) GLXEW_NV_video_out = !_glewInit_GLX_NV_video_out(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_video_out */ +#ifdef GLX_OML_swap_method + GLXEW_OML_swap_method = _glewSearchExtension("GLX_OML_swap_method", extStart, extEnd); +#endif /* GLX_OML_swap_method */ +#ifdef GLX_OML_sync_control + GLXEW_OML_sync_control = _glewSearchExtension("GLX_OML_sync_control", extStart, extEnd); + if (glewExperimental || GLXEW_OML_sync_control) GLXEW_OML_sync_control = !_glewInit_GLX_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_OML_sync_control */ +#ifdef GLX_SGIS_blended_overlay + GLXEW_SGIS_blended_overlay = _glewSearchExtension("GLX_SGIS_blended_overlay", extStart, extEnd); +#endif /* GLX_SGIS_blended_overlay */ +#ifdef GLX_SGIS_color_range + GLXEW_SGIS_color_range = _glewSearchExtension("GLX_SGIS_color_range", extStart, extEnd); +#endif /* GLX_SGIS_color_range */ +#ifdef GLX_SGIS_multisample + GLXEW_SGIS_multisample = _glewSearchExtension("GLX_SGIS_multisample", extStart, extEnd); +#endif /* GLX_SGIS_multisample */ +#ifdef GLX_SGIS_shared_multisample + GLXEW_SGIS_shared_multisample = _glewSearchExtension("GLX_SGIS_shared_multisample", extStart, extEnd); +#endif /* GLX_SGIS_shared_multisample */ +#ifdef GLX_SGIX_fbconfig + GLXEW_SGIX_fbconfig = _glewSearchExtension("GLX_SGIX_fbconfig", extStart, extEnd); + if (glewExperimental || GLXEW_SGIX_fbconfig) GLXEW_SGIX_fbconfig = !_glewInit_GLX_SGIX_fbconfig(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_fbconfig */ +#ifdef GLX_SGIX_hyperpipe + GLXEW_SGIX_hyperpipe = _glewSearchExtension("GLX_SGIX_hyperpipe", extStart, extEnd); + if (glewExperimental || GLXEW_SGIX_hyperpipe) GLXEW_SGIX_hyperpipe = !_glewInit_GLX_SGIX_hyperpipe(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_hyperpipe */ +#ifdef GLX_SGIX_pbuffer + GLXEW_SGIX_pbuffer = _glewSearchExtension("GLX_SGIX_pbuffer", extStart, extEnd); + if (glewExperimental || GLXEW_SGIX_pbuffer) GLXEW_SGIX_pbuffer = !_glewInit_GLX_SGIX_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_pbuffer */ +#ifdef GLX_SGIX_swap_barrier + GLXEW_SGIX_swap_barrier = _glewSearchExtension("GLX_SGIX_swap_barrier", extStart, extEnd); + if (glewExperimental || GLXEW_SGIX_swap_barrier) GLXEW_SGIX_swap_barrier = !_glewInit_GLX_SGIX_swap_barrier(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_swap_barrier */ +#ifdef GLX_SGIX_swap_group + GLXEW_SGIX_swap_group = _glewSearchExtension("GLX_SGIX_swap_group", extStart, extEnd); + if (glewExperimental || GLXEW_SGIX_swap_group) GLXEW_SGIX_swap_group = !_glewInit_GLX_SGIX_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_swap_group */ +#ifdef GLX_SGIX_video_resize + GLXEW_SGIX_video_resize = _glewSearchExtension("GLX_SGIX_video_resize", extStart, extEnd); + if (glewExperimental || GLXEW_SGIX_video_resize) 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 + GLXEW_SGIX_visual_select_group = _glewSearchExtension("GLX_SGIX_visual_select_group", extStart, extEnd); +#endif /* GLX_SGIX_visual_select_group */ +#ifdef GLX_SGI_cushion + GLXEW_SGI_cushion = _glewSearchExtension("GLX_SGI_cushion", extStart, extEnd); + if (glewExperimental || GLXEW_SGI_cushion) GLXEW_SGI_cushion = !_glewInit_GLX_SGI_cushion(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_cushion */ +#ifdef GLX_SGI_make_current_read + GLXEW_SGI_make_current_read = _glewSearchExtension("GLX_SGI_make_current_read", extStart, extEnd); + if (glewExperimental || GLXEW_SGI_make_current_read) 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 + GLXEW_SGI_swap_control = _glewSearchExtension("GLX_SGI_swap_control", extStart, extEnd); + if (glewExperimental || GLXEW_SGI_swap_control) GLXEW_SGI_swap_control = !_glewInit_GLX_SGI_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_swap_control */ +#ifdef GLX_SGI_video_sync + GLXEW_SGI_video_sync = _glewSearchExtension("GLX_SGI_video_sync", extStart, extEnd); + if (glewExperimental || GLXEW_SGI_video_sync) 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 + GLXEW_SUN_get_transparent_index = _glewSearchExtension("GLX_SUN_get_transparent_index", extStart, extEnd); + if (glewExperimental || GLXEW_SUN_get_transparent_index) 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 + GLXEW_SUN_video_resize = _glewSearchExtension("GLX_SUN_video_resize", extStart, extEnd); + if (glewExperimental || GLXEW_SUN_video_resize) GLXEW_SUN_video_resize = !_glewInit_GLX_SUN_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SUN_video_resize */ + + return GLEW_OK; +} + +#endif /* !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) */ + +/* ------------------------------------------------------------------------ */ + +const GLubyte * GLEWAPIENTRY 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 size_t max_error = sizeof(_glewErrorString)/sizeof(*_glewErrorString) - 1; + return _glewErrorString[(size_t)error > max_error ? max_error : (size_t)error]; +} + +const GLubyte * GLEWAPIENTRY glewGetString (GLenum name) +{ + static const GLubyte* _glewString[] = + { + (const GLubyte*)NULL, + (const GLubyte*)"1.10.0", + (const GLubyte*)"1", + (const GLubyte*)"10", + (const GLubyte*)"0" + }; + const size_t max_string = sizeof(_glewString)/sizeof(*_glewString) - 1; + return _glewString[(size_t)name > max_string ? 0 : (size_t)name]; +} + +/* ------------------------------------------------------------------------ */ + +GLboolean glewExperimental = GL_FALSE; + +#if !defined(GLEW_MX) + +#if defined(_WIN32) +extern GLenum GLEWAPIENTRY wglewContextInit (void); +#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) +extern GLenum GLEWAPIENTRY glxewContextInit (void); +#endif /* _WIN32 */ + +GLenum GLEWAPIENTRY glewInit (void) +{ + GLenum r; + r = glewContextInit(); + if ( r != 0 ) return r; +#if defined(_WIN32) + return wglewContextInit(); +#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) /* _UNIX */ + return glxewContextInit(); +#else + return r; +#endif /* _WIN32 */ +} + +#endif /* !GLEW_MX */ +#ifdef GLEW_MX +GLboolean GLEWAPIENTRY glewContextIsSupported (const GLEWContext* ctx, const char* name) +#else +GLboolean GLEWAPIENTRY 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_2_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2_1", 5)) + { + ret = GLEW_VERSION_1_2_1; + 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 +#ifdef GL_VERSION_3_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_1", 3)) + { + ret = GLEW_VERSION_3_1; + continue; + } +#endif +#ifdef GL_VERSION_3_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_2", 3)) + { + ret = GLEW_VERSION_3_2; + continue; + } +#endif +#ifdef GL_VERSION_3_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_3", 3)) + { + ret = GLEW_VERSION_3_3; + continue; + } +#endif +#ifdef GL_VERSION_4_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_0", 3)) + { + ret = GLEW_VERSION_4_0; + continue; + } +#endif +#ifdef GL_VERSION_4_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_1", 3)) + { + ret = GLEW_VERSION_4_1; + continue; + } +#endif +#ifdef GL_VERSION_4_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_2", 3)) + { + ret = GLEW_VERSION_4_2; + continue; + } +#endif +#ifdef GL_VERSION_4_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_3", 3)) + { + ret = GLEW_VERSION_4_3; + continue; + } +#endif +#ifdef GL_VERSION_4_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_4", 3)) + { + ret = GLEW_VERSION_4_4; + 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*)"AMD_", 4)) + { +#ifdef GL_AMD_blend_minmax_factor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax_factor", 19)) + { + ret = GLEW_AMD_blend_minmax_factor; + continue; + } +#endif +#ifdef GL_AMD_conservative_depth + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18)) + { + ret = GLEW_AMD_conservative_depth; + continue; + } +#endif +#ifdef GL_AMD_debug_output + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_output", 12)) + { + ret = GLEW_AMD_debug_output; + continue; + } +#endif +#ifdef GL_AMD_depth_clamp_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp_separate", 20)) + { + ret = GLEW_AMD_depth_clamp_separate; + continue; + } +#endif +#ifdef GL_AMD_draw_buffers_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18)) + { + ret = GLEW_AMD_draw_buffers_blend; + continue; + } +#endif +#ifdef GL_AMD_gcn_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gcn_shader", 10)) + { + ret = GLEW_AMD_gcn_shader; + continue; + } +#endif +#ifdef GL_AMD_gpu_shader_int64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_int64", 16)) + { + ret = GLEW_AMD_gpu_shader_int64; + continue; + } +#endif +#ifdef GL_AMD_interleaved_elements + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interleaved_elements", 20)) + { + ret = GLEW_AMD_interleaved_elements; + continue; + } +#endif +#ifdef GL_AMD_multi_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19)) + { + ret = GLEW_AMD_multi_draw_indirect; + continue; + } +#endif +#ifdef GL_AMD_name_gen_delete + if (_glewStrSame3(&pos, &len, (const GLubyte*)"name_gen_delete", 15)) + { + ret = GLEW_AMD_name_gen_delete; + continue; + } +#endif +#ifdef GL_AMD_occlusion_query_event + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query_event", 21)) + { + ret = GLEW_AMD_occlusion_query_event; + continue; + } +#endif +#ifdef GL_AMD_performance_monitor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"performance_monitor", 19)) + { + ret = GLEW_AMD_performance_monitor; + continue; + } +#endif +#ifdef GL_AMD_pinned_memory + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pinned_memory", 13)) + { + ret = GLEW_AMD_pinned_memory; + continue; + } +#endif +#ifdef GL_AMD_query_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_buffer_object", 19)) + { + ret = GLEW_AMD_query_buffer_object; + continue; + } +#endif +#ifdef GL_AMD_sample_positions + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_positions", 16)) + { + ret = GLEW_AMD_sample_positions; + continue; + } +#endif +#ifdef GL_AMD_seamless_cubemap_per_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cubemap_per_texture", 28)) + { + ret = GLEW_AMD_seamless_cubemap_per_texture; + continue; + } +#endif +#ifdef GL_AMD_shader_atomic_counter_ops + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counter_ops", 25)) + { + ret = GLEW_AMD_shader_atomic_counter_ops; + continue; + } +#endif +#ifdef GL_AMD_shader_stencil_export + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21)) + { + ret = GLEW_AMD_shader_stencil_export; + continue; + } +#endif +#ifdef GL_AMD_shader_stencil_value_export + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_value_export", 27)) + { + ret = GLEW_AMD_shader_stencil_value_export; + continue; + } +#endif +#ifdef GL_AMD_shader_trinary_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_trinary_minmax", 21)) + { + ret = GLEW_AMD_shader_trinary_minmax; + continue; + } +#endif +#ifdef GL_AMD_sparse_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14)) + { + ret = GLEW_AMD_sparse_texture; + continue; + } +#endif +#ifdef GL_AMD_stencil_operation_extended + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_operation_extended", 26)) + { + ret = GLEW_AMD_stencil_operation_extended; + continue; + } +#endif +#ifdef GL_AMD_texture_texture4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_texture4", 16)) + { + ret = GLEW_AMD_texture_texture4; + continue; + } +#endif +#ifdef GL_AMD_transform_feedback3_lines_triangles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback3_lines_triangles", 35)) + { + ret = GLEW_AMD_transform_feedback3_lines_triangles; + continue; + } +#endif +#ifdef GL_AMD_transform_feedback4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback4", 19)) + { + ret = GLEW_AMD_transform_feedback4; + continue; + } +#endif +#ifdef GL_AMD_vertex_shader_layer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_layer", 19)) + { + ret = GLEW_AMD_vertex_shader_layer; + continue; + } +#endif +#ifdef GL_AMD_vertex_shader_tessellator + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_tessellator", 25)) + { + ret = GLEW_AMD_vertex_shader_tessellator; + continue; + } +#endif +#ifdef GL_AMD_vertex_shader_viewport_index + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_viewport_index", 28)) + { + ret = GLEW_AMD_vertex_shader_viewport_index; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANGLE_", 6)) + { +#ifdef GL_ANGLE_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_ANGLE_depth_texture; + continue; + } +#endif +#ifdef GL_ANGLE_framebuffer_blit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16)) + { + ret = GLEW_ANGLE_framebuffer_blit; + continue; + } +#endif +#ifdef GL_ANGLE_framebuffer_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) + { + ret = GLEW_ANGLE_framebuffer_multisample; + continue; + } +#endif +#ifdef GL_ANGLE_instanced_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16)) + { + ret = GLEW_ANGLE_instanced_arrays; + continue; + } +#endif +#ifdef GL_ANGLE_pack_reverse_row_order + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_reverse_row_order", 22)) + { + ret = GLEW_ANGLE_pack_reverse_row_order; + continue; + } +#endif +#ifdef GL_ANGLE_program_binary + if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_binary", 14)) + { + ret = GLEW_ANGLE_program_binary; + continue; + } +#endif +#ifdef GL_ANGLE_texture_compression_dxt1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24)) + { + ret = GLEW_ANGLE_texture_compression_dxt1; + continue; + } +#endif +#ifdef GL_ANGLE_texture_compression_dxt3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt3", 24)) + { + ret = GLEW_ANGLE_texture_compression_dxt3; + continue; + } +#endif +#ifdef GL_ANGLE_texture_compression_dxt5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt5", 24)) + { + ret = GLEW_ANGLE_texture_compression_dxt5; + continue; + } +#endif +#ifdef GL_ANGLE_texture_usage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_usage", 13)) + { + ret = GLEW_ANGLE_texture_usage; + continue; + } +#endif +#ifdef GL_ANGLE_timer_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11)) + { + ret = GLEW_ANGLE_timer_query; + continue; + } +#endif +#ifdef GL_ANGLE_translated_shader_source + if (_glewStrSame3(&pos, &len, (const GLubyte*)"translated_shader_source", 24)) + { + ret = GLEW_ANGLE_translated_shader_source; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6)) + { +#ifdef GL_APPLE_aux_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"aux_depth_stencil", 17)) + { + ret = GLEW_APPLE_aux_depth_stencil; + continue; + } +#endif +#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_object_purgeable + if (_glewStrSame3(&pos, &len, (const GLubyte*)"object_purgeable", 16)) + { + ret = GLEW_APPLE_object_purgeable; + 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_rgb_422 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rgb_422", 7)) + { + ret = GLEW_APPLE_rgb_422; + continue; + } +#endif +#ifdef GL_APPLE_row_bytes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"row_bytes", 9)) + { + ret = GLEW_APPLE_row_bytes; + 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_vertex_program_evaluators + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program_evaluators", 25)) + { + ret = GLEW_APPLE_vertex_program_evaluators; + 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_ES2_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES2_compatibility", 17)) + { + ret = GLEW_ARB_ES2_compatibility; + continue; + } +#endif +#ifdef GL_ARB_ES3_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES3_compatibility", 17)) + { + ret = GLEW_ARB_ES3_compatibility; + continue; + } +#endif +#ifdef GL_ARB_arrays_of_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"arrays_of_arrays", 16)) + { + ret = GLEW_ARB_arrays_of_arrays; + continue; + } +#endif +#ifdef GL_ARB_base_instance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"base_instance", 13)) + { + ret = GLEW_ARB_base_instance; + continue; + } +#endif +#ifdef GL_ARB_bindless_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_texture", 16)) + { + ret = GLEW_ARB_bindless_texture; + continue; + } +#endif +#ifdef GL_ARB_blend_func_extended + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_extended", 19)) + { + ret = GLEW_ARB_blend_func_extended; + continue; + } +#endif +#ifdef GL_ARB_buffer_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_storage", 14)) + { + ret = GLEW_ARB_buffer_storage; + continue; + } +#endif +#ifdef GL_ARB_cl_event + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cl_event", 8)) + { + ret = GLEW_ARB_cl_event; + continue; + } +#endif +#ifdef GL_ARB_clear_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_buffer_object", 19)) + { + ret = GLEW_ARB_clear_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_clear_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_texture", 13)) + { + ret = GLEW_ARB_clear_texture; + continue; + } +#endif +#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_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compatibility", 13)) + { + ret = GLEW_ARB_compatibility; + continue; + } +#endif +#ifdef GL_ARB_compressed_texture_pixel_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_texture_pixel_storage", 32)) + { + ret = GLEW_ARB_compressed_texture_pixel_storage; + continue; + } +#endif +#ifdef GL_ARB_compute_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_shader", 14)) + { + ret = GLEW_ARB_compute_shader; + continue; + } +#endif +#ifdef GL_ARB_compute_variable_group_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_variable_group_size", 27)) + { + ret = GLEW_ARB_compute_variable_group_size; + continue; + } +#endif +#ifdef GL_ARB_conservative_depth + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18)) + { + ret = GLEW_ARB_conservative_depth; + continue; + } +#endif +#ifdef GL_ARB_copy_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_buffer", 11)) + { + ret = GLEW_ARB_copy_buffer; + continue; + } +#endif +#ifdef GL_ARB_copy_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10)) + { + ret = GLEW_ARB_copy_image; + continue; + } +#endif +#ifdef GL_ARB_debug_output + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_output", 12)) + { + ret = GLEW_ARB_debug_output; + 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_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11)) + { + ret = GLEW_ARB_depth_clamp; + 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_buffers_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18)) + { + ret = GLEW_ARB_draw_buffers_blend; + continue; + } +#endif +#ifdef GL_ARB_draw_elements_base_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_elements_base_vertex", 25)) + { + ret = GLEW_ARB_draw_elements_base_vertex; + continue; + } +#endif +#ifdef GL_ARB_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_indirect", 13)) + { + ret = GLEW_ARB_draw_indirect; + 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_enhanced_layouts + if (_glewStrSame3(&pos, &len, (const GLubyte*)"enhanced_layouts", 16)) + { + ret = GLEW_ARB_enhanced_layouts; + continue; + } +#endif +#ifdef GL_ARB_explicit_attrib_location + if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_attrib_location", 24)) + { + ret = GLEW_ARB_explicit_attrib_location; + continue; + } +#endif +#ifdef GL_ARB_explicit_uniform_location + if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_uniform_location", 25)) + { + ret = GLEW_ARB_explicit_uniform_location; + continue; + } +#endif +#ifdef GL_ARB_fragment_coord_conventions + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_coord_conventions", 26)) + { + ret = GLEW_ARB_fragment_coord_conventions; + continue; + } +#endif +#ifdef GL_ARB_fragment_layer_viewport + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_layer_viewport", 23)) + { + ret = GLEW_ARB_fragment_layer_viewport; + 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_no_attachments + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_no_attachments", 26)) + { + ret = GLEW_ARB_framebuffer_no_attachments; + 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_get_program_binary + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_program_binary", 18)) + { + ret = GLEW_ARB_get_program_binary; + continue; + } +#endif +#ifdef GL_ARB_gpu_shader5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11)) + { + ret = GLEW_ARB_gpu_shader5; + continue; + } +#endif +#ifdef GL_ARB_gpu_shader_fp64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_fp64", 15)) + { + ret = GLEW_ARB_gpu_shader_fp64; + 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_indirect_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"indirect_parameters", 19)) + { + ret = GLEW_ARB_indirect_parameters; + 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_internalformat_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_query", 20)) + { + ret = GLEW_ARB_internalformat_query; + continue; + } +#endif +#ifdef GL_ARB_internalformat_query2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_query2", 21)) + { + ret = GLEW_ARB_internalformat_query2; + continue; + } +#endif +#ifdef GL_ARB_invalidate_subdata + if (_glewStrSame3(&pos, &len, (const GLubyte*)"invalidate_subdata", 18)) + { + ret = GLEW_ARB_invalidate_subdata; + continue; + } +#endif +#ifdef GL_ARB_map_buffer_alignment + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_alignment", 20)) + { + ret = GLEW_ARB_map_buffer_alignment; + 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_multi_bind + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_bind", 10)) + { + ret = GLEW_ARB_multi_bind; + continue; + } +#endif +#ifdef GL_ARB_multi_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19)) + { + ret = GLEW_ARB_multi_draw_indirect; + 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_occlusion_query2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query2", 16)) + { + ret = GLEW_ARB_occlusion_query2; + 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_program_interface_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_interface_query", 23)) + { + ret = GLEW_ARB_program_interface_query; + continue; + } +#endif +#ifdef GL_ARB_provoking_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16)) + { + ret = GLEW_ARB_provoking_vertex; + continue; + } +#endif +#ifdef GL_ARB_query_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_buffer_object", 19)) + { + ret = GLEW_ARB_query_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_robust_buffer_access_behavior + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robust_buffer_access_behavior", 29)) + { + ret = GLEW_ARB_robust_buffer_access_behavior; + continue; + } +#endif +#ifdef GL_ARB_robustness + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness", 10)) + { + ret = GLEW_ARB_robustness; + continue; + } +#endif +#ifdef GL_ARB_robustness_application_isolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32)) + { + ret = GLEW_ARB_robustness_application_isolation; + continue; + } +#endif +#ifdef GL_ARB_robustness_share_group_isolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32)) + { + ret = GLEW_ARB_robustness_share_group_isolation; + continue; + } +#endif +#ifdef GL_ARB_sample_shading + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_shading", 14)) + { + ret = GLEW_ARB_sample_shading; + continue; + } +#endif +#ifdef GL_ARB_sampler_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sampler_objects", 15)) + { + ret = GLEW_ARB_sampler_objects; + continue; + } +#endif +#ifdef GL_ARB_seamless_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cube_map", 17)) + { + ret = GLEW_ARB_seamless_cube_map; + continue; + } +#endif +#ifdef GL_ARB_seamless_cubemap_per_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cubemap_per_texture", 28)) + { + ret = GLEW_ARB_seamless_cubemap_per_texture; + continue; + } +#endif +#ifdef GL_ARB_separate_shader_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23)) + { + ret = GLEW_ARB_separate_shader_objects; + continue; + } +#endif +#ifdef GL_ARB_shader_atomic_counters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counters", 22)) + { + ret = GLEW_ARB_shader_atomic_counters; + continue; + } +#endif +#ifdef GL_ARB_shader_bit_encoding + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_bit_encoding", 19)) + { + ret = GLEW_ARB_shader_bit_encoding; + continue; + } +#endif +#ifdef GL_ARB_shader_draw_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_draw_parameters", 22)) + { + ret = GLEW_ARB_shader_draw_parameters; + continue; + } +#endif +#ifdef GL_ARB_shader_group_vote + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_group_vote", 17)) + { + ret = GLEW_ARB_shader_group_vote; + continue; + } +#endif +#ifdef GL_ARB_shader_image_load_store + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_store", 23)) + { + ret = GLEW_ARB_shader_image_load_store; + continue; + } +#endif +#ifdef GL_ARB_shader_image_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_size", 17)) + { + ret = GLEW_ARB_shader_image_size; + 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_shader_precision + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_precision", 16)) + { + ret = GLEW_ARB_shader_precision; + continue; + } +#endif +#ifdef GL_ARB_shader_stencil_export + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21)) + { + ret = GLEW_ARB_shader_stencil_export; + continue; + } +#endif +#ifdef GL_ARB_shader_storage_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_storage_buffer_object", 28)) + { + ret = GLEW_ARB_shader_storage_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_shader_subroutine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_subroutine", 17)) + { + ret = GLEW_ARB_shader_subroutine; + continue; + } +#endif +#ifdef GL_ARB_shader_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18)) + { + ret = GLEW_ARB_shader_texture_lod; + 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_shading_language_420pack + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_420pack", 24)) + { + ret = GLEW_ARB_shading_language_420pack; + continue; + } +#endif +#ifdef GL_ARB_shading_language_include + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_include", 24)) + { + ret = GLEW_ARB_shading_language_include; + continue; + } +#endif +#ifdef GL_ARB_shading_language_packing + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_packing", 24)) + { + ret = GLEW_ARB_shading_language_packing; + 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_sparse_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14)) + { + ret = GLEW_ARB_sparse_texture; + continue; + } +#endif +#ifdef GL_ARB_stencil_texturing + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_texturing", 17)) + { + ret = GLEW_ARB_stencil_texturing; + continue; + } +#endif +#ifdef GL_ARB_sync + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4)) + { + ret = GLEW_ARB_sync; + continue; + } +#endif +#ifdef GL_ARB_tessellation_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_shader", 19)) + { + ret = GLEW_ARB_tessellation_shader; + 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_buffer_object_rgb32 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object_rgb32", 27)) + { + ret = GLEW_ARB_texture_buffer_object_rgb32; + continue; + } +#endif +#ifdef GL_ARB_texture_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_range", 20)) + { + ret = GLEW_ARB_texture_buffer_range; + 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_bptc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_bptc", 24)) + { + ret = GLEW_ARB_texture_compression_bptc; + 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_cube_map_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map_array", 22)) + { + ret = GLEW_ARB_texture_cube_map_array; + 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_gather + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_gather", 14)) + { + ret = GLEW_ARB_texture_gather; + continue; + } +#endif +#ifdef GL_ARB_texture_mirror_clamp_to_edge + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp_to_edge", 28)) + { + ret = GLEW_ARB_texture_mirror_clamp_to_edge; + 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_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19)) + { + ret = GLEW_ARB_texture_multisample; + 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_query_levels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_levels", 20)) + { + ret = GLEW_ARB_texture_query_levels; + continue; + } +#endif +#ifdef GL_ARB_texture_query_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_lod", 17)) + { + ret = GLEW_ARB_texture_query_lod; + 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_texture_rgb10_a2ui + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rgb10_a2ui", 18)) + { + ret = GLEW_ARB_texture_rgb10_a2ui; + continue; + } +#endif +#ifdef GL_ARB_texture_stencil8 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stencil8", 16)) + { + ret = GLEW_ARB_texture_stencil8; + continue; + } +#endif +#ifdef GL_ARB_texture_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage", 15)) + { + ret = GLEW_ARB_texture_storage; + continue; + } +#endif +#ifdef GL_ARB_texture_storage_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage_multisample", 27)) + { + ret = GLEW_ARB_texture_storage_multisample; + continue; + } +#endif +#ifdef GL_ARB_texture_swizzle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15)) + { + ret = GLEW_ARB_texture_swizzle; + continue; + } +#endif +#ifdef GL_ARB_texture_view + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_view", 12)) + { + ret = GLEW_ARB_texture_view; + continue; + } +#endif +#ifdef GL_ARB_timer_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11)) + { + ret = GLEW_ARB_timer_query; + continue; + } +#endif +#ifdef GL_ARB_transform_feedback2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19)) + { + ret = GLEW_ARB_transform_feedback2; + continue; + } +#endif +#ifdef GL_ARB_transform_feedback3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback3", 19)) + { + ret = GLEW_ARB_transform_feedback3; + continue; + } +#endif +#ifdef GL_ARB_transform_feedback_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback_instanced", 28)) + { + ret = GLEW_ARB_transform_feedback_instanced; + 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_uniform_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"uniform_buffer_object", 21)) + { + ret = GLEW_ARB_uniform_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_array_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17)) + { + ret = GLEW_ARB_vertex_array_bgra; + 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_attrib_64bit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_64bit", 19)) + { + ret = GLEW_ARB_vertex_attrib_64bit; + continue; + } +#endif +#ifdef GL_ARB_vertex_attrib_binding + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_binding", 21)) + { + ret = GLEW_ARB_vertex_attrib_binding; + 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_vertex_type_10f_11f_11f_rev + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_type_10f_11f_11f_rev", 27)) + { + ret = GLEW_ARB_vertex_type_10f_11f_11f_rev; + continue; + } +#endif +#ifdef GL_ARB_vertex_type_2_10_10_10_rev + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_type_2_10_10_10_rev", 26)) + { + ret = GLEW_ARB_vertex_type_2_10_10_10_rev; + continue; + } +#endif +#ifdef GL_ARB_viewport_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_array", 14)) + { + ret = GLEW_ARB_viewport_array; + 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_meminfo + if (_glewStrSame3(&pos, &len, (const GLubyte*)"meminfo", 7)) + { + ret = GLEW_ATI_meminfo; + 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_debug_label + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_label", 11)) + { + ret = GLEW_EXT_debug_label; + continue; + } +#endif +#ifdef GL_EXT_debug_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_marker", 12)) + { + ret = GLEW_EXT_debug_marker; + 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_multisample_blit_scaled + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_blit_scaled", 35)) + { + ret = GLEW_EXT_framebuffer_multisample_blit_scaled; + 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_provoking_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16)) + { + ret = GLEW_EXT_provoking_vertex; + 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_shader_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23)) + { + ret = GLEW_EXT_separate_shader_objects; + 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_shader_image_load_formatted + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_formatted", 27)) + { + ret = GLEW_EXT_shader_image_load_formatted; + continue; + } +#endif +#ifdef GL_EXT_shader_image_load_store + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_store", 23)) + { + ret = GLEW_EXT_shader_image_load_store; + continue; + } +#endif +#ifdef GL_EXT_shader_integer_mix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_integer_mix", 18)) + { + ret = GLEW_EXT_shader_integer_mix; + 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_sRGB_decode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB_decode", 19)) + { + ret = GLEW_EXT_texture_sRGB_decode; + 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_snorm + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_snorm", 13)) + { + ret = GLEW_EXT_texture_snorm; + 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_attrib_64bit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_64bit", 19)) + { + ret = GLEW_EXT_vertex_attrib_64bit; + 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 +#ifdef GL_EXT_x11_sync_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"x11_sync_object", 15)) + { + ret = GLEW_EXT_x11_sync_object; + 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_fragment_shader_ordering + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader_ordering", 24)) + { + ret = GLEW_INTEL_fragment_shader_ordering; + continue; + } +#endif +#ifdef GL_INTEL_map_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_texture", 11)) + { + ret = GLEW_INTEL_map_texture; + continue; + } +#endif +#ifdef GL_INTEL_parallel_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_arrays", 15)) + { + ret = GLEW_INTEL_parallel_arrays; + continue; + } +#endif +#ifdef GL_INTEL_performance_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"performance_query", 17)) + { + ret = GLEW_INTEL_performance_query; + 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*)"KHR_", 4)) + { +#ifdef GL_KHR_debug + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug", 5)) + { + ret = GLEW_KHR_debug; + continue; + } +#endif +#ifdef GL_KHR_texture_compression_astc_hdr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_hdr", 28)) + { + ret = GLEW_KHR_texture_compression_astc_hdr; + continue; + } +#endif +#ifdef GL_KHR_texture_compression_astc_ldr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_ldr", 28)) + { + ret = GLEW_KHR_texture_compression_astc_ldr; + 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*)"NVX_", 4)) + { +#ifdef GL_NVX_conditional_render + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18)) + { + ret = GLEW_NVX_conditional_render; + continue; + } +#endif +#ifdef GL_NVX_gpu_memory_info + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_memory_info", 15)) + { + ret = GLEW_NVX_gpu_memory_info; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GL_NV_bindless_multi_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_multi_draw_indirect", 28)) + { + ret = GLEW_NV_bindless_multi_draw_indirect; + continue; + } +#endif +#ifdef GL_NV_bindless_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_texture", 16)) + { + ret = GLEW_NV_bindless_texture; + continue; + } +#endif +#ifdef GL_NV_blend_equation_advanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced", 23)) + { + ret = GLEW_NV_blend_equation_advanced; + continue; + } +#endif +#ifdef GL_NV_blend_equation_advanced_coherent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_coherent", 32)) + { + ret = GLEW_NV_blend_equation_advanced_coherent; + continue; + } +#endif +#ifdef GL_NV_blend_square + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_square", 12)) + { + ret = GLEW_NV_blend_square; + continue; + } +#endif +#ifdef GL_NV_compute_program5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_program5", 16)) + { + ret = GLEW_NV_compute_program5; + 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_copy_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10)) + { + ret = GLEW_NV_copy_image; + continue; + } +#endif +#ifdef GL_NV_deep_texture3D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"deep_texture3D", 14)) + { + ret = GLEW_NV_deep_texture3D; + 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_draw_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_texture", 12)) + { + ret = GLEW_NV_draw_texture; + 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_gpu_program5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program5", 12)) + { + ret = GLEW_NV_gpu_program5; + continue; + } +#endif +#ifdef GL_NV_gpu_program5_mem_extended + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program5_mem_extended", 25)) + { + ret = GLEW_NV_gpu_program5_mem_extended; + continue; + } +#endif +#ifdef GL_NV_gpu_program_fp64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_fp64", 16)) + { + ret = GLEW_NV_gpu_program_fp64; + continue; + } +#endif +#ifdef GL_NV_gpu_shader5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11)) + { + ret = GLEW_NV_gpu_shader5; + 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_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20)) + { + ret = GLEW_NV_multisample_coverage; + 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_parameter_buffer_object2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object2", 24)) + { + ret = GLEW_NV_parameter_buffer_object2; + continue; + } +#endif +#ifdef GL_NV_path_rendering + if (_glewStrSame3(&pos, &len, (const GLubyte*)"path_rendering", 14)) + { + ret = GLEW_NV_path_rendering; + 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_shader_atomic_counters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counters", 22)) + { + ret = GLEW_NV_shader_atomic_counters; + continue; + } +#endif +#ifdef GL_NV_shader_atomic_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_float", 19)) + { + ret = GLEW_NV_shader_atomic_float; + continue; + } +#endif +#ifdef GL_NV_shader_buffer_load + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_buffer_load", 18)) + { + ret = GLEW_NV_shader_buffer_load; + continue; + } +#endif +#ifdef GL_NV_shader_storage_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_storage_buffer_object", 28)) + { + ret = GLEW_NV_shader_storage_buffer_object; + continue; + } +#endif +#ifdef GL_NV_shader_thread_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_thread_group", 19)) + { + ret = GLEW_NV_shader_thread_group; + continue; + } +#endif +#ifdef GL_NV_shader_thread_shuffle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_thread_shuffle", 21)) + { + ret = GLEW_NV_shader_thread_shuffle; + continue; + } +#endif +#ifdef GL_NV_tessellation_program5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_program5", 21)) + { + ret = GLEW_NV_tessellation_program5; + 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_barrier + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_barrier", 15)) + { + ret = GLEW_NV_texture_barrier; + 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_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19)) + { + ret = GLEW_NV_texture_multisample; + 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_transform_feedback2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19)) + { + ret = GLEW_NV_transform_feedback2; + continue; + } +#endif +#ifdef GL_NV_vdpau_interop + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vdpau_interop", 13)) + { + ret = GLEW_NV_vdpau_interop; + 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_attrib_integer_64bit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_integer_64bit", 27)) + { + ret = GLEW_NV_vertex_attrib_integer_64bit; + continue; + } +#endif +#ifdef GL_NV_vertex_buffer_unified_memory + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_unified_memory", 28)) + { + ret = GLEW_NV_vertex_buffer_unified_memory; + 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 +#ifdef GL_NV_video_capture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13)) + { + ret = GLEW_NV_video_capture; + 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*)"REGAL_", 6)) + { +#ifdef GL_REGAL_ES1_0_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES1_0_compatibility", 19)) + { + ret = GLEW_REGAL_ES1_0_compatibility; + continue; + } +#endif +#ifdef GL_REGAL_ES1_1_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES1_1_compatibility", 19)) + { + ret = GLEW_REGAL_ES1_1_compatibility; + continue; + } +#endif +#ifdef GL_REGAL_enable + if (_glewStrSame3(&pos, &len, (const GLubyte*)"enable", 6)) + { + ret = GLEW_REGAL_enable; + continue; + } +#endif +#ifdef GL_REGAL_error_string + if (_glewStrSame3(&pos, &len, (const GLubyte*)"error_string", 12)) + { + ret = GLEW_REGAL_error_string; + continue; + } +#endif +#ifdef GL_REGAL_extension_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extension_query", 15)) + { + ret = GLEW_REGAL_extension_query; + continue; + } +#endif +#ifdef GL_REGAL_log + if (_glewStrSame3(&pos, &len, (const GLubyte*)"log", 3)) + { + ret = GLEW_REGAL_log; + continue; + } +#endif +#ifdef GL_REGAL_proc_address + if (_glewStrSame3(&pos, &len, (const GLubyte*)"proc_address", 12)) + { + ret = GLEW_REGAL_proc_address; + 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 GLEWAPIENTRY wglewContextIsSupported (const WGLEWContext* ctx, const char* name) +#else +GLboolean GLEWAPIENTRY 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*)"AMD_", 4)) + { +#ifdef WGL_AMD_gpu_association + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_association", 15)) + { + ret = WGLEW_AMD_gpu_association; + 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_create_context_profile + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_profile", 22)) + { + ret = WGLEW_ARB_create_context_profile; + continue; + } +#endif +#ifdef WGL_ARB_create_context_robustness + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_robustness", 25)) + { + ret = WGLEW_ARB_create_context_robustness; + 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 +#ifdef WGL_ARB_robustness_application_isolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32)) + { + ret = WGLEW_ARB_robustness_application_isolation; + continue; + } +#endif +#ifdef WGL_ARB_robustness_share_group_isolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32)) + { + ret = WGLEW_ARB_robustness_share_group_isolation; + 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_create_context_es2_profile + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es2_profile", 26)) + { + ret = WGLEW_EXT_create_context_es2_profile; + continue; + } +#endif +#ifdef WGL_EXT_create_context_es_profile + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es_profile", 25)) + { + ret = WGLEW_EXT_create_context_es_profile; + continue; + } +#endif +#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 +#ifdef WGL_EXT_swap_control_tear + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control_tear", 17)) + { + ret = WGLEW_EXT_swap_control_tear; + 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_DX_interop + if (_glewStrSame3(&pos, &len, (const GLubyte*)"DX_interop", 10)) + { + ret = WGLEW_NV_DX_interop; + continue; + } +#endif +#ifdef WGL_NV_DX_interop2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"DX_interop2", 11)) + { + ret = WGLEW_NV_DX_interop2; + continue; + } +#endif +#ifdef WGL_NV_copy_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10)) + { + ret = WGLEW_NV_copy_image; + continue; + } +#endif +#ifdef WGL_NV_delay_before_swap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"delay_before_swap", 17)) + { + ret = WGLEW_NV_delay_before_swap; + continue; + } +#endif +#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_multisample_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20)) + { + ret = WGLEW_NV_multisample_coverage; + 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_capture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13)) + { + ret = WGLEW_NV_video_capture; + 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(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + +#if defined(GLEW_MX) +GLboolean glxewContextIsSupported (const 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*)"AMD_", 4)) + { +#ifdef GLX_AMD_gpu_association + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_association", 15)) + { + ret = GLXEW_AMD_gpu_association; + 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_create_context_profile + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_profile", 22)) + { + ret = GLXEW_ARB_create_context_profile; + continue; + } +#endif +#ifdef GLX_ARB_create_context_robustness + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_robustness", 25)) + { + ret = GLXEW_ARB_create_context_robustness; + 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 +#ifdef GLX_ARB_robustness_application_isolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32)) + { + ret = GLXEW_ARB_robustness_application_isolation; + continue; + } +#endif +#ifdef GLX_ARB_robustness_share_group_isolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32)) + { + ret = GLXEW_ARB_robustness_share_group_isolation; + continue; + } +#endif +#ifdef GLX_ARB_vertex_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20)) + { + ret = GLXEW_ARB_vertex_buffer_object; + 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_buffer_age + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_age", 10)) + { + ret = GLXEW_EXT_buffer_age; + continue; + } +#endif +#ifdef GLX_EXT_create_context_es2_profile + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es2_profile", 26)) + { + ret = GLXEW_EXT_create_context_es2_profile; + continue; + } +#endif +#ifdef GLX_EXT_create_context_es_profile + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es_profile", 25)) + { + ret = GLXEW_EXT_create_context_es_profile; + continue; + } +#endif +#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_stereo_tree + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_tree", 11)) + { + ret = GLXEW_EXT_stereo_tree; + continue; + } +#endif +#ifdef GLX_EXT_swap_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) + { + ret = GLXEW_EXT_swap_control; + continue; + } +#endif +#ifdef GLX_EXT_swap_control_tear + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control_tear", 17)) + { + ret = GLXEW_EXT_swap_control_tear; + 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*)"INTEL_", 6)) + { +#ifdef GLX_INTEL_swap_event + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_event", 10)) + { + ret = GLXEW_INTEL_swap_event; + 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_query_renderer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_renderer", 14)) + { + ret = GLXEW_MESA_query_renderer; + 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 +#ifdef GLX_MESA_swap_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) + { + ret = GLXEW_MESA_swap_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GLX_NV_copy_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10)) + { + ret = GLXEW_NV_copy_image; + continue; + } +#endif +#ifdef GLX_NV_delay_before_swap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"delay_before_swap", 17)) + { + ret = GLXEW_NV_delay_before_swap; + continue; + } +#endif +#ifdef GLX_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = GLXEW_NV_float_buffer; + continue; + } +#endif +#ifdef GLX_NV_multisample_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20)) + { + ret = GLXEW_NV_multisample_coverage; + 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_capture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13)) + { + ret = GLXEW_NV_video_capture; + continue; + } +#endif +#ifdef GLX_NV_video_out + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_out", 9)) + { + ret = GLXEW_NV_video_out; + 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 +#ifdef GLX_OML_sync_control + 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/ext/native/ext/glew/glewinfo.c b/ext/native/ext/glew/glewinfo.c new file mode 100644 index 0000000000..de6dad5c18 --- /dev/null +++ b/ext/native/ext/glew/glewinfo.c @@ -0,0 +1,10964 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2014, Nigel Stewart +** 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 "GL/glew.h" +#if defined(_WIN32) +#include +#elif !defined(__APPLE__) && !defined(__HAIKU__) || defined(GLEW_APPLE_GLX) +#include "GL/glxew.h" +#endif + +#ifdef GLEW_REGAL +#include +#endif + +static FILE* f; + +#ifdef GLEW_MX +GLEWContext _glewctx; +#define glewGetContext() (&_glewctx) +#ifdef _WIN32 +WGLEWContext _wglewctx; +#define wglewGetContext() (&_wglewctx) +#elif !defined(__APPLE__) && !defined(__HAIKU__) || defined(GLEW_APPLE_GLX) +GLXEWContext _glxewctx; +#define glxewGetContext() (&_glxewctx) +#endif +#endif + +#if defined(_WIN32) +GLboolean glewCreateContext (int* pixelformat); +#elif !defined(__APPLE__) && !defined(__HAIKU__) || 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]\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) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + if (fopen_s(&f, "glewinfo.txt", "w") != 0) + f = stdout; +#else + f = fopen("glewinfo.txt", "w"); +#endif + 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(rc); + 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 (GL_FALSE == aglSetCurrentContext(ctx)) return GL_TRUE; + /* Needed for Regal on the Mac */ + #if defined(GLEW_REGAL) && defined(__APPLE__) + RegalMakeCurrent(ctx); + #endif + return GL_FALSE; +} + +void glewDestroyContext () +{ + aglSetCurrentContext(octx); + if (NULL != ctx) aglDestroyContext(ctx); +} + +/* ------------------------------------------------------------------------ */ + +#elif defined(__HAIKU__) + +GLboolean glewCreateContext () +{ + /* TODO: Haiku: We need to call C++ code here */ + return GL_FALSE; +} + +void glewDestroyContext () +{ + /* TODO: Haiku: We need to call C++ code here */ +} + +/* ------------------------------------------------------------------------ */ + +#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/ext/native/ext/glew/visualinfo.c b/ext/native/ext/glew/visualinfo.c new file mode 100644 index 0000000000..6a7df43717 --- /dev/null +++ b/ext/native/ext/glew/visualinfo.c @@ -0,0 +1,1227 @@ +/* +** visualinfo.c +** +** Copyright (C) Nate Robins, 1997 +** Michael Wimmer, 1999 +** Milan Ikits, 2002-2008 +** Nigel Stewart, 2008-2013 +** +** 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 "GL/glew.h" +#if defined(_WIN32) +#include +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) +#include +#elif !defined(__HAIKU__) +#include "GL/glxew.h" +#endif + +#ifdef GLEW_MX +GLEWContext _glewctx; +# define glewGetContext() (&_glewctx) +# ifdef _WIN32 +WGLEWContext _wglewctx; +# define wglewGetContext() (&_wglewctx) +# elif !defined(__APPLE__) && !defined(__HAIKU__) || 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; +#elif !defined(__HAIKU__) + 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; + +int +main (int argc, char** argv) +{ + GLenum err; + GLContext ctx; + + /* ---------------------------------------------------------------------- */ + /* 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(__HAIKU__) || 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) + { +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + if (fopen_s(&file, "visualinfo.txt", "w") != 0) + file = stdout; +#else + file = fopen("visualinfo.txt", "w"); +#endif + } + 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((const char*)glGetString(GL_EXTENSIONS)); + +#ifndef GLEW_NO_GLU + /* GLU extensions */ + fprintf(file, "GLU version string: %s\n", gluGetString(GLU_VERSION)); + fprintf(file, "GLU extensions (GLU_): \n"); + PrintExtensions((const char*)gluGetString(GLU_EXTENSIONS)); +#endif + + /* ---------------------------------------------------------------------- */ + /* extensions string */ +#if defined(_WIN32) + /* WGL extensions */ + if (WGLEW_ARB_extensions_string || WGLEW_EXT_extensions_string) + { + fprintf(file, "WGL extensions (WGL_): \n"); + PrintExtensions(wglGetExtensionsStringARB ? + (const char*)wglGetExtensionsStringARB(ctx.dc) : + (const char*)wglGetExtensionsStringEXT()); + } +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) + +#elif defined(__HAIKU__) + + /* TODO */ + +#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); +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + strcpy_s(t, sizeof(t), p); +#else + strcpy(t, p); +#endif + } + 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 "); + else if (value[7] == WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT) fprintf(file," p "); + else fprintf(file," ? "); + /* 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* __attribute__((__unused__)) 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); + } +*/ +} + +/* ---------------------------------------------------------------------- */ + +#elif defined(__HAIKU__) + +void +VisualInfo (GLContext* ctx) +{ + /* TODO */ +} + +#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 (GL_FALSE == 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); +} + +/* ------------------------------------------------------------------------ */ + +#elif defined(__HAIKU__) + +void +InitContext (GLContext* ctx) +{ + /* TODO */ +} + +GLboolean +CreateContext (GLContext* ctx) +{ + /* TODO */ + return GL_FALSE; +} + +void +DestroyContext (GLContext* ctx) +{ + /* TODO */ +} + +/* ------------------------------------------------------------------------ */ + +#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/ext/native/ext/jpge/jpgd.cpp b/ext/native/ext/jpge/jpgd.cpp new file mode 100644 index 0000000000..cc47bd721c --- /dev/null +++ b/ext/native/ext/jpge/jpgd.cpp @@ -0,0 +1,3172 @@ +// jpgd.cpp - C++ class for JPEG decompression. +// Public domain, Rich Geldreich +// Alex Evans: Linear memory allocator (taken from jpge.h). +// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings (all looked harmless) +// +// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2. +// +// Chroma upsampling quality: H2V2 is upsampled in the frequency domain, H2V1 and H1V2 are upsampled using point sampling. +// Chroma upsampling reference: "Fast Scheme for Image Size Change in the Compressed Domain" +// http://vision.ai.uiuc.edu/~dugad/research/dct/index.html + +#include "jpgd.h" +#include + +#include +#define JPGD_ASSERT(x) assert(x) + +#ifdef _MSC_VER +#pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable +#endif + +// Set to 1 to enable freq. domain chroma upsampling on images using H2V2 subsampling (0=faster nearest neighbor sampling). +// This is slower, but results in higher quality on images with highly saturated colors. +#define JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING 1 + +#define JPGD_TRUE (1) +#define JPGD_FALSE (0) + +#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b)) +#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b)) + +namespace jpgd { + +static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); } +static inline void jpgd_free(void *p) { free(p); } + +// DCT coefficients are stored in this sequence. +static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 }; + +enum JPEG_MARKER +{ + 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_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0 +}; + +enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 }; + +#define CONST_BITS 13 +#define PASS1_BITS 2 +#define SCALEDONE ((int32)1) + +#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) */ + +#define DESCALE(x,n) (((x) + (SCALEDONE << ((n)-1))) >> (n)) +#define DESCALE_ZEROSHIFT(x,n) (((x) + (128 << (n)) + (SCALEDONE << ((n)-1))) >> (n)) + +#define MULTIPLY(var, cnst) ((var) * (cnst)) + +#define CLAMP(i) ((static_cast(i) > 255) ? (((~i) >> 31) & 0xFF) : (i)) + +// Compiler creates a fast path 1D IDCT for X non-zero columns +template +struct Row +{ + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { + // ACCESS_COL() will be optimized at compile time to either an array access, or 0. + #define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0) + + const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = (ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS; + const int tmp1 = (ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS; + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, - FIX_0_899976223); + const int az2 = MULTIPLY(bz2, - FIX_2_562915447); + const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS-PASS1_BITS); + pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS-PASS1_BITS); + pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS-PASS1_BITS); + pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS-PASS1_BITS); + pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS-PASS1_BITS); + pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS-PASS1_BITS); + pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS-PASS1_BITS); + pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS-PASS1_BITS); + } +}; + +template <> +struct Row<0> +{ + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { +#ifdef _MSC_VER + pTemp; pSrc; +#endif + } +}; + +template <> +struct Row<1> +{ + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { + const int dcval = (pSrc[0] << PASS1_BITS); + + pTemp[0] = dcval; + pTemp[1] = dcval; + pTemp[2] = dcval; + pTemp[3] = dcval; + pTemp[4] = dcval; + pTemp[5] = dcval; + pTemp[6] = dcval; + pTemp[7] = dcval; + } +}; + +// Compiler creates a fast path 1D IDCT for X non-zero rows +template +struct Col +{ + static void idct(uint8* pDst_ptr, const int* pTemp) + { + // ACCESS_ROW() will be optimized at compile time to either an array access, or 0. + #define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0) + + const int z2 = ACCESS_ROW(2); + const int z3 = ACCESS_ROW(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = (ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS; + const int tmp1 = (ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS; + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, - FIX_0_899976223); + const int az2 = MULTIPLY(bz2, - FIX_2_562915447); + const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*0] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*7] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*1] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*6] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*2] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*5] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*3] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*4] = (uint8)CLAMP(i); + } +}; + +template <> +struct Col<1> +{ + static void idct(uint8* pDst_ptr, const int* pTemp) + { + int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS+3); + const uint8 dcval_clamped = (uint8)CLAMP(dcval); + pDst_ptr[0*8] = dcval_clamped; + pDst_ptr[1*8] = dcval_clamped; + pDst_ptr[2*8] = dcval_clamped; + pDst_ptr[3*8] = dcval_clamped; + pDst_ptr[4*8] = dcval_clamped; + pDst_ptr[5*8] = dcval_clamped; + pDst_ptr[6*8] = dcval_clamped; + pDst_ptr[7*8] = dcval_clamped; + } +}; + +static const uint8 s_idct_row_table[] = +{ + 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0, + 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0, + 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0, + 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0, + 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2, + 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2, + 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4, + 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8, +}; + +static const uint8 s_idct_col_table[] = { 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; + +void idct(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag) +{ + JPGD_ASSERT(block_max_zag >= 1); + JPGD_ASSERT(block_max_zag <= 64); + + if (block_max_zag <= 1) + { + int k = ((pSrc_ptr[0] + 4) >> 3) + 128; + k = CLAMP(k); + k = k | (k<<8); + k = k | (k<<16); + + for (int i = 8; i > 0; i--) + { + *(int*)&pDst_ptr[0] = k; + *(int*)&pDst_ptr[4] = k; + pDst_ptr += 8; + } + return; + } + + int temp[64]; + + const jpgd_block_t* pSrc = pSrc_ptr; + int* pTemp = temp; + + const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8]; + int i; + for (i = 8; i > 0; i--, pRow_tab++) + { + switch (*pRow_tab) + { + case 0: Row<0>::idct(pTemp, pSrc); break; + case 1: Row<1>::idct(pTemp, pSrc); break; + case 2: Row<2>::idct(pTemp, pSrc); break; + case 3: Row<3>::idct(pTemp, pSrc); break; + case 4: Row<4>::idct(pTemp, pSrc); break; + case 5: Row<5>::idct(pTemp, pSrc); break; + case 6: Row<6>::idct(pTemp, pSrc); break; + case 7: Row<7>::idct(pTemp, pSrc); break; + case 8: Row<8>::idct(pTemp, pSrc); break; + } + + pSrc += 8; + pTemp += 8; + } + + pTemp = temp; + + const int nonzero_rows = s_idct_col_table[block_max_zag - 1]; + for (i = 8; i > 0; i--) + { + switch (nonzero_rows) + { + case 1: Col<1>::idct(pDst_ptr, pTemp); break; + case 2: Col<2>::idct(pDst_ptr, pTemp); break; + case 3: Col<3>::idct(pDst_ptr, pTemp); break; + case 4: Col<4>::idct(pDst_ptr, pTemp); break; + case 5: Col<5>::idct(pDst_ptr, pTemp); break; + case 6: Col<6>::idct(pDst_ptr, pTemp); break; + case 7: Col<7>::idct(pDst_ptr, pTemp); break; + case 8: Col<8>::idct(pDst_ptr, pTemp); break; + } + + pTemp++; + pDst_ptr++; + } +} + +void idct_4x4(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr) +{ + int temp[64]; + int* pTemp = temp; + const jpgd_block_t* pSrc = pSrc_ptr; + + for (int i = 4; i > 0; i--) + { + Row<4>::idct(pTemp, pSrc); + pSrc += 8; + pTemp += 8; + } + + pTemp = temp; + for (int i = 8; i > 0; i--) + { + Col<4>::idct(pDst_ptr, pTemp); + pTemp++; + pDst_ptr++; + } +} + +// Retrieve one character from the input stream. +inline uint jpeg_decoder::get_char() +{ + // Any bytes remaining in buffer? + if (!m_in_buf_left) + { + // Try to get more bytes. + prep_in_buffer(); + // Still nothing to get? + if (!m_in_buf_left) + { + // Pad the end of the stream with 0xFF 0xD9 (EOI marker) + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) + return 0xD9; + else + return 0xFF; + } + } + + uint c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; +} + +// Same as previous method, except can indicate if the character is a pad character or not. +inline uint jpeg_decoder::get_char(bool *pPadding_flag) +{ + if (!m_in_buf_left) + { + prep_in_buffer(); + if (!m_in_buf_left) + { + *pPadding_flag = true; + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) + return 0xD9; + else + return 0xFF; + } + } + + *pPadding_flag = false; + + uint c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; +} + +// Inserts a previously retrieved character back into the input buffer. +inline void jpeg_decoder::stuff_char(uint8 q) +{ + *(--m_pIn_buf_ofs) = q; + m_in_buf_left++; +} + +// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered. +inline uint8 jpeg_decoder::get_octet() +{ + bool padding_flag; + int c = get_char(&padding_flag); + + if (c == 0xFF) + { + if (padding_flag) + return 0xFF; + + c = get_char(&padding_flag); + if (padding_flag) + { + stuff_char(0xFF); + return 0xFF; + } + + if (c == 0x00) + return 0xFF; + else + { + stuff_char(static_cast(c)); + stuff_char(0xFF); + return 0xFF; + } + } + + return static_cast(c); +} + +// Retrieves a variable number of bits from the input stream. Does not recognize markers. +inline uint jpeg_decoder::get_bits(int num_bits) +{ + if (!num_bits) + return 0; + + uint i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) + { + m_bit_buf <<= (num_bits += m_bits_left); + + uint c1 = get_char(); + uint c2 = get_char(); + m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2; + + m_bit_buf <<= -m_bits_left; + + m_bits_left += 16; + + JPGD_ASSERT(m_bits_left >= 0); + } + else + m_bit_buf <<= num_bits; + + return i; +} + +// Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered. +inline uint jpeg_decoder::get_bits_no_markers(int num_bits) +{ + if (!num_bits) + return 0; + + uint i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) + { + m_bit_buf <<= (num_bits += m_bits_left); + + if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF)) + { + uint c1 = get_octet(); + uint c2 = get_octet(); + m_bit_buf |= (c1 << 8) | c2; + } + else + { + m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1]; + m_in_buf_left -= 2; + m_pIn_buf_ofs += 2; + } + + m_bit_buf <<= -m_bits_left; + + m_bits_left += 16; + + JPGD_ASSERT(m_bits_left >= 0); + } + else + m_bit_buf <<= num_bits; + + return i; +} + +// Decodes a Huffman encoded symbol. +inline int jpeg_decoder::huff_decode(huff_tables *pH) +{ + int symbol; + + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0) + { + // Decode more bits, use a tree traversal to find symbol. + int ofs = 23; + do + { + symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + } + else + get_bits_no_markers(pH->code_size[symbol]); + + return symbol; +} + +// Decodes a Huffman encoded symbol. +inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits) +{ + int symbol; + + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0) + { + // Use a tree traversal to find symbol. + int ofs = 23; + do + { + symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + + extra_bits = get_bits_no_markers(symbol & 0xF); + } + else + { + JPGD_ASSERT(((symbol >> 8) & 31) == pH->code_size[symbol & 255] + ((symbol & 0x8000) ? (symbol & 15) : 0)); + + if (symbol & 0x8000) + { + get_bits_no_markers((symbol >> 8) & 31); + extra_bits = symbol >> 16; + } + else + { + int code_size = (symbol >> 8) & 31; + int num_extra_bits = symbol & 0xF; + int bits = code_size + num_extra_bits; + if (bits <= (m_bits_left + 16)) + extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1); + else + { + get_bits_no_markers(code_size); + extra_bits = get_bits_no_markers(num_extra_bits); + } + } + + symbol &= 0xFF; + } + + return symbol; +} + +// Tables and macro used to fully decode the DPCM differences. +static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; +static const int s_extend_offset[16] = { 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 }; +//static const int s_extend_mask[] = { 0, (1<<0), (1<<1), (1<<2), (1<<3), (1<<4), (1<<5), (1<<6), (1<<7), (1<<8), (1<<9), (1<<10), (1<<11), (1<<12), (1<<13), (1<<14), (1<<15), (1<<16) }; +// The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this) +#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x)) + +// Clamps a value between 0-255. +inline uint8 jpeg_decoder::clamp(int i) +{ + if (static_cast(i) > 255) + i = (((~i) >> 31) & 0xFF); + + return static_cast(i); +} + +namespace DCT_Upsample +{ + struct Matrix44 + { + typedef int Element_Type; + enum { NUM_ROWS = 4, NUM_COLS = 4 }; + + Element_Type v[NUM_ROWS][NUM_COLS]; + + inline int rows() const { return NUM_ROWS; } + inline int cols() const { return NUM_COLS; } + + inline const Element_Type & at(int r, int c) const { return v[r][c]; } + inline Element_Type & at(int r, int c) { return v[r][c]; } + + inline Matrix44() { } + + inline Matrix44& operator += (const Matrix44& a) + { + for (int r = 0; r < NUM_ROWS; r++) + { + at(r, 0) += a.at(r, 0); + at(r, 1) += a.at(r, 1); + at(r, 2) += a.at(r, 2); + at(r, 3) += a.at(r, 3); + } + return *this; + } + + inline Matrix44& operator -= (const Matrix44& a) + { + for (int r = 0; r < NUM_ROWS; r++) + { + at(r, 0) -= a.at(r, 0); + at(r, 1) -= a.at(r, 1); + at(r, 2) -= a.at(r, 2); + at(r, 3) -= a.at(r, 3); + } + return *this; + } + + friend inline Matrix44 operator + (const Matrix44& a, const Matrix44& b) + { + Matrix44 ret; + for (int r = 0; r < NUM_ROWS; r++) + { + ret.at(r, 0) = a.at(r, 0) + b.at(r, 0); + ret.at(r, 1) = a.at(r, 1) + b.at(r, 1); + ret.at(r, 2) = a.at(r, 2) + b.at(r, 2); + ret.at(r, 3) = a.at(r, 3) + b.at(r, 3); + } + return ret; + } + + friend inline Matrix44 operator - (const Matrix44& a, const Matrix44& b) + { + Matrix44 ret; + for (int r = 0; r < NUM_ROWS; r++) + { + ret.at(r, 0) = a.at(r, 0) - b.at(r, 0); + ret.at(r, 1) = a.at(r, 1) - b.at(r, 1); + ret.at(r, 2) = a.at(r, 2) - b.at(r, 2); + ret.at(r, 3) = a.at(r, 3) - b.at(r, 3); + } + return ret; + } + + static inline void add_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b) + { + for (int r = 0; r < 4; r++) + { + pDst[0*8 + r] = static_cast(a.at(r, 0) + b.at(r, 0)); + pDst[1*8 + r] = static_cast(a.at(r, 1) + b.at(r, 1)); + pDst[2*8 + r] = static_cast(a.at(r, 2) + b.at(r, 2)); + pDst[3*8 + r] = static_cast(a.at(r, 3) + b.at(r, 3)); + } + } + + static inline void sub_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b) + { + for (int r = 0; r < 4; r++) + { + pDst[0*8 + r] = static_cast(a.at(r, 0) - b.at(r, 0)); + pDst[1*8 + r] = static_cast(a.at(r, 1) - b.at(r, 1)); + pDst[2*8 + r] = static_cast(a.at(r, 2) - b.at(r, 2)); + pDst[3*8 + r] = static_cast(a.at(r, 3) - b.at(r, 3)); + } + } + }; + + const int FRACT_BITS = 10; + const int SCALE = 1 << FRACT_BITS; + + typedef int Temp_Type; + #define D(i) (((i) + (SCALE >> 1)) >> FRACT_BITS) + #define F(i) ((int)((i) * SCALE + .5f)) + + // Any decent C++ compiler will optimize this at compile time to a 0, or an array access. + #define AT(c, r) ((((c)>=NUM_COLS)||((r)>=NUM_ROWS)) ? 0 : pSrc[(c)+(r)*8]) + + // NUM_ROWS/NUM_COLS = # of non-zero rows/cols in input matrix + template + struct P_Q + { + static void calc(Matrix44& P, Matrix44& Q, const jpgd_block_t* pSrc) + { + // 4x8 = 4x8 times 8x8, matrix 0 is constant + const Temp_Type X000 = AT(0, 0); + const Temp_Type X001 = AT(0, 1); + const Temp_Type X002 = AT(0, 2); + const Temp_Type X003 = AT(0, 3); + const Temp_Type X004 = AT(0, 4); + const Temp_Type X005 = AT(0, 5); + const Temp_Type X006 = AT(0, 6); + const Temp_Type X007 = AT(0, 7); + const Temp_Type X010 = D(F(0.415735f) * AT(1, 0) + F(0.791065f) * AT(3, 0) + F(-0.352443f) * AT(5, 0) + F(0.277785f) * AT(7, 0)); + const Temp_Type X011 = D(F(0.415735f) * AT(1, 1) + F(0.791065f) * AT(3, 1) + F(-0.352443f) * AT(5, 1) + F(0.277785f) * AT(7, 1)); + const Temp_Type X012 = D(F(0.415735f) * AT(1, 2) + F(0.791065f) * AT(3, 2) + F(-0.352443f) * AT(5, 2) + F(0.277785f) * AT(7, 2)); + const Temp_Type X013 = D(F(0.415735f) * AT(1, 3) + F(0.791065f) * AT(3, 3) + F(-0.352443f) * AT(5, 3) + F(0.277785f) * AT(7, 3)); + const Temp_Type X014 = D(F(0.415735f) * AT(1, 4) + F(0.791065f) * AT(3, 4) + F(-0.352443f) * AT(5, 4) + F(0.277785f) * AT(7, 4)); + const Temp_Type X015 = D(F(0.415735f) * AT(1, 5) + F(0.791065f) * AT(3, 5) + F(-0.352443f) * AT(5, 5) + F(0.277785f) * AT(7, 5)); + const Temp_Type X016 = D(F(0.415735f) * AT(1, 6) + F(0.791065f) * AT(3, 6) + F(-0.352443f) * AT(5, 6) + F(0.277785f) * AT(7, 6)); + const Temp_Type X017 = D(F(0.415735f) * AT(1, 7) + F(0.791065f) * AT(3, 7) + F(-0.352443f) * AT(5, 7) + F(0.277785f) * AT(7, 7)); + const Temp_Type X020 = AT(4, 0); + const Temp_Type X021 = AT(4, 1); + const Temp_Type X022 = AT(4, 2); + const Temp_Type X023 = AT(4, 3); + const Temp_Type X024 = AT(4, 4); + const Temp_Type X025 = AT(4, 5); + const Temp_Type X026 = AT(4, 6); + const Temp_Type X027 = AT(4, 7); + const Temp_Type X030 = D(F(0.022887f) * AT(1, 0) + F(-0.097545f) * AT(3, 0) + F(0.490393f) * AT(5, 0) + F(0.865723f) * AT(7, 0)); + const Temp_Type X031 = D(F(0.022887f) * AT(1, 1) + F(-0.097545f) * AT(3, 1) + F(0.490393f) * AT(5, 1) + F(0.865723f) * AT(7, 1)); + const Temp_Type X032 = D(F(0.022887f) * AT(1, 2) + F(-0.097545f) * AT(3, 2) + F(0.490393f) * AT(5, 2) + F(0.865723f) * AT(7, 2)); + const Temp_Type X033 = D(F(0.022887f) * AT(1, 3) + F(-0.097545f) * AT(3, 3) + F(0.490393f) * AT(5, 3) + F(0.865723f) * AT(7, 3)); + const Temp_Type X034 = D(F(0.022887f) * AT(1, 4) + F(-0.097545f) * AT(3, 4) + F(0.490393f) * AT(5, 4) + F(0.865723f) * AT(7, 4)); + const Temp_Type X035 = D(F(0.022887f) * AT(1, 5) + F(-0.097545f) * AT(3, 5) + F(0.490393f) * AT(5, 5) + F(0.865723f) * AT(7, 5)); + const Temp_Type X036 = D(F(0.022887f) * AT(1, 6) + F(-0.097545f) * AT(3, 6) + F(0.490393f) * AT(5, 6) + F(0.865723f) * AT(7, 6)); + const Temp_Type X037 = D(F(0.022887f) * AT(1, 7) + F(-0.097545f) * AT(3, 7) + F(0.490393f) * AT(5, 7) + F(0.865723f) * AT(7, 7)); + + // 4x4 = 4x8 times 8x4, matrix 1 is constant + P.at(0, 0) = X000; + P.at(0, 1) = D(X001 * F(0.415735f) + X003 * F(0.791065f) + X005 * F(-0.352443f) + X007 * F(0.277785f)); + P.at(0, 2) = X004; + P.at(0, 3) = D(X001 * F(0.022887f) + X003 * F(-0.097545f) + X005 * F(0.490393f) + X007 * F(0.865723f)); + P.at(1, 0) = X010; + P.at(1, 1) = D(X011 * F(0.415735f) + X013 * F(0.791065f) + X015 * F(-0.352443f) + X017 * F(0.277785f)); + P.at(1, 2) = X014; + P.at(1, 3) = D(X011 * F(0.022887f) + X013 * F(-0.097545f) + X015 * F(0.490393f) + X017 * F(0.865723f)); + P.at(2, 0) = X020; + P.at(2, 1) = D(X021 * F(0.415735f) + X023 * F(0.791065f) + X025 * F(-0.352443f) + X027 * F(0.277785f)); + P.at(2, 2) = X024; + P.at(2, 3) = D(X021 * F(0.022887f) + X023 * F(-0.097545f) + X025 * F(0.490393f) + X027 * F(0.865723f)); + P.at(3, 0) = X030; + P.at(3, 1) = D(X031 * F(0.415735f) + X033 * F(0.791065f) + X035 * F(-0.352443f) + X037 * F(0.277785f)); + P.at(3, 2) = X034; + P.at(3, 3) = D(X031 * F(0.022887f) + X033 * F(-0.097545f) + X035 * F(0.490393f) + X037 * F(0.865723f)); + // 40 muls 24 adds + + // 4x4 = 4x8 times 8x4, matrix 1 is constant + Q.at(0, 0) = D(X001 * F(0.906127f) + X003 * F(-0.318190f) + X005 * F(0.212608f) + X007 * F(-0.180240f)); + Q.at(0, 1) = X002; + Q.at(0, 2) = D(X001 * F(-0.074658f) + X003 * F(0.513280f) + X005 * F(0.768178f) + X007 * F(-0.375330f)); + Q.at(0, 3) = X006; + Q.at(1, 0) = D(X011 * F(0.906127f) + X013 * F(-0.318190f) + X015 * F(0.212608f) + X017 * F(-0.180240f)); + Q.at(1, 1) = X012; + Q.at(1, 2) = D(X011 * F(-0.074658f) + X013 * F(0.513280f) + X015 * F(0.768178f) + X017 * F(-0.375330f)); + Q.at(1, 3) = X016; + Q.at(2, 0) = D(X021 * F(0.906127f) + X023 * F(-0.318190f) + X025 * F(0.212608f) + X027 * F(-0.180240f)); + Q.at(2, 1) = X022; + Q.at(2, 2) = D(X021 * F(-0.074658f) + X023 * F(0.513280f) + X025 * F(0.768178f) + X027 * F(-0.375330f)); + Q.at(2, 3) = X026; + Q.at(3, 0) = D(X031 * F(0.906127f) + X033 * F(-0.318190f) + X035 * F(0.212608f) + X037 * F(-0.180240f)); + Q.at(3, 1) = X032; + Q.at(3, 2) = D(X031 * F(-0.074658f) + X033 * F(0.513280f) + X035 * F(0.768178f) + X037 * F(-0.375330f)); + Q.at(3, 3) = X036; + // 40 muls 24 adds + } + }; + + template + struct R_S + { + static void calc(Matrix44& R, Matrix44& S, const jpgd_block_t* pSrc) + { + // 4x8 = 4x8 times 8x8, matrix 0 is constant + const Temp_Type X100 = D(F(0.906127f) * AT(1, 0) + F(-0.318190f) * AT(3, 0) + F(0.212608f) * AT(5, 0) + F(-0.180240f) * AT(7, 0)); + const Temp_Type X101 = D(F(0.906127f) * AT(1, 1) + F(-0.318190f) * AT(3, 1) + F(0.212608f) * AT(5, 1) + F(-0.180240f) * AT(7, 1)); + const Temp_Type X102 = D(F(0.906127f) * AT(1, 2) + F(-0.318190f) * AT(3, 2) + F(0.212608f) * AT(5, 2) + F(-0.180240f) * AT(7, 2)); + const Temp_Type X103 = D(F(0.906127f) * AT(1, 3) + F(-0.318190f) * AT(3, 3) + F(0.212608f) * AT(5, 3) + F(-0.180240f) * AT(7, 3)); + const Temp_Type X104 = D(F(0.906127f) * AT(1, 4) + F(-0.318190f) * AT(3, 4) + F(0.212608f) * AT(5, 4) + F(-0.180240f) * AT(7, 4)); + const Temp_Type X105 = D(F(0.906127f) * AT(1, 5) + F(-0.318190f) * AT(3, 5) + F(0.212608f) * AT(5, 5) + F(-0.180240f) * AT(7, 5)); + const Temp_Type X106 = D(F(0.906127f) * AT(1, 6) + F(-0.318190f) * AT(3, 6) + F(0.212608f) * AT(5, 6) + F(-0.180240f) * AT(7, 6)); + const Temp_Type X107 = D(F(0.906127f) * AT(1, 7) + F(-0.318190f) * AT(3, 7) + F(0.212608f) * AT(5, 7) + F(-0.180240f) * AT(7, 7)); + const Temp_Type X110 = AT(2, 0); + const Temp_Type X111 = AT(2, 1); + const Temp_Type X112 = AT(2, 2); + const Temp_Type X113 = AT(2, 3); + const Temp_Type X114 = AT(2, 4); + const Temp_Type X115 = AT(2, 5); + const Temp_Type X116 = AT(2, 6); + const Temp_Type X117 = AT(2, 7); + const Temp_Type X120 = D(F(-0.074658f) * AT(1, 0) + F(0.513280f) * AT(3, 0) + F(0.768178f) * AT(5, 0) + F(-0.375330f) * AT(7, 0)); + const Temp_Type X121 = D(F(-0.074658f) * AT(1, 1) + F(0.513280f) * AT(3, 1) + F(0.768178f) * AT(5, 1) + F(-0.375330f) * AT(7, 1)); + const Temp_Type X122 = D(F(-0.074658f) * AT(1, 2) + F(0.513280f) * AT(3, 2) + F(0.768178f) * AT(5, 2) + F(-0.375330f) * AT(7, 2)); + const Temp_Type X123 = D(F(-0.074658f) * AT(1, 3) + F(0.513280f) * AT(3, 3) + F(0.768178f) * AT(5, 3) + F(-0.375330f) * AT(7, 3)); + const Temp_Type X124 = D(F(-0.074658f) * AT(1, 4) + F(0.513280f) * AT(3, 4) + F(0.768178f) * AT(5, 4) + F(-0.375330f) * AT(7, 4)); + const Temp_Type X125 = D(F(-0.074658f) * AT(1, 5) + F(0.513280f) * AT(3, 5) + F(0.768178f) * AT(5, 5) + F(-0.375330f) * AT(7, 5)); + const Temp_Type X126 = D(F(-0.074658f) * AT(1, 6) + F(0.513280f) * AT(3, 6) + F(0.768178f) * AT(5, 6) + F(-0.375330f) * AT(7, 6)); + const Temp_Type X127 = D(F(-0.074658f) * AT(1, 7) + F(0.513280f) * AT(3, 7) + F(0.768178f) * AT(5, 7) + F(-0.375330f) * AT(7, 7)); + const Temp_Type X130 = AT(6, 0); + const Temp_Type X131 = AT(6, 1); + const Temp_Type X132 = AT(6, 2); + const Temp_Type X133 = AT(6, 3); + const Temp_Type X134 = AT(6, 4); + const Temp_Type X135 = AT(6, 5); + const Temp_Type X136 = AT(6, 6); + const Temp_Type X137 = AT(6, 7); + // 80 muls 48 adds + + // 4x4 = 4x8 times 8x4, matrix 1 is constant + R.at(0, 0) = X100; + R.at(0, 1) = D(X101 * F(0.415735f) + X103 * F(0.791065f) + X105 * F(-0.352443f) + X107 * F(0.277785f)); + R.at(0, 2) = X104; + R.at(0, 3) = D(X101 * F(0.022887f) + X103 * F(-0.097545f) + X105 * F(0.490393f) + X107 * F(0.865723f)); + R.at(1, 0) = X110; + R.at(1, 1) = D(X111 * F(0.415735f) + X113 * F(0.791065f) + X115 * F(-0.352443f) + X117 * F(0.277785f)); + R.at(1, 2) = X114; + R.at(1, 3) = D(X111 * F(0.022887f) + X113 * F(-0.097545f) + X115 * F(0.490393f) + X117 * F(0.865723f)); + R.at(2, 0) = X120; + R.at(2, 1) = D(X121 * F(0.415735f) + X123 * F(0.791065f) + X125 * F(-0.352443f) + X127 * F(0.277785f)); + R.at(2, 2) = X124; + R.at(2, 3) = D(X121 * F(0.022887f) + X123 * F(-0.097545f) + X125 * F(0.490393f) + X127 * F(0.865723f)); + R.at(3, 0) = X130; + R.at(3, 1) = D(X131 * F(0.415735f) + X133 * F(0.791065f) + X135 * F(-0.352443f) + X137 * F(0.277785f)); + R.at(3, 2) = X134; + R.at(3, 3) = D(X131 * F(0.022887f) + X133 * F(-0.097545f) + X135 * F(0.490393f) + X137 * F(0.865723f)); + // 40 muls 24 adds + // 4x4 = 4x8 times 8x4, matrix 1 is constant + S.at(0, 0) = D(X101 * F(0.906127f) + X103 * F(-0.318190f) + X105 * F(0.212608f) + X107 * F(-0.180240f)); + S.at(0, 1) = X102; + S.at(0, 2) = D(X101 * F(-0.074658f) + X103 * F(0.513280f) + X105 * F(0.768178f) + X107 * F(-0.375330f)); + S.at(0, 3) = X106; + S.at(1, 0) = D(X111 * F(0.906127f) + X113 * F(-0.318190f) + X115 * F(0.212608f) + X117 * F(-0.180240f)); + S.at(1, 1) = X112; + S.at(1, 2) = D(X111 * F(-0.074658f) + X113 * F(0.513280f) + X115 * F(0.768178f) + X117 * F(-0.375330f)); + S.at(1, 3) = X116; + S.at(2, 0) = D(X121 * F(0.906127f) + X123 * F(-0.318190f) + X125 * F(0.212608f) + X127 * F(-0.180240f)); + S.at(2, 1) = X122; + S.at(2, 2) = D(X121 * F(-0.074658f) + X123 * F(0.513280f) + X125 * F(0.768178f) + X127 * F(-0.375330f)); + S.at(2, 3) = X126; + S.at(3, 0) = D(X131 * F(0.906127f) + X133 * F(-0.318190f) + X135 * F(0.212608f) + X137 * F(-0.180240f)); + S.at(3, 1) = X132; + S.at(3, 2) = D(X131 * F(-0.074658f) + X133 * F(0.513280f) + X135 * F(0.768178f) + X137 * F(-0.375330f)); + S.at(3, 3) = X136; + // 40 muls 24 adds + } + }; +} // end namespace DCT_Upsample + +// Unconditionally frees all allocated m_blocks. +void jpeg_decoder::free_all_blocks() +{ + m_pStream = NULL; + for (mem_block *b = m_pMem_blocks; b; ) + { + mem_block *n = b->m_pNext; + jpgd_free(b); + b = n; + } + m_pMem_blocks = NULL; +} + +// This method handles all errors. It will never return. +// It could easily be changed to use C++ exceptions. +JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status) +{ + m_error_code = status; + free_all_blocks(); + longjmp(m_jmp_state, status); +} + +void *jpeg_decoder::alloc(size_t nSize, bool zero) +{ + nSize = (JPGD_MAX(nSize, 1) + 3) & ~3; + char *rv = NULL; + for (mem_block *b = m_pMem_blocks; b; b = b->m_pNext) + { + if ((b->m_used_count + nSize) <= b->m_size) + { + rv = b->m_data + b->m_used_count; + b->m_used_count += nSize; + break; + } + } + if (!rv) + { + int capacity = (int)JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047); + mem_block *b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity); + if (!b) { stop_decoding(JPGD_NOTENOUGHMEM); } + b->m_pNext = m_pMem_blocks; m_pMem_blocks = b; + b->m_used_count = nSize; + b->m_size = capacity; + rv = b->m_data; + } + if (zero) memset(rv, 0, nSize); + return rv; +} + +void jpeg_decoder::word_clear(void *p, uint16 c, uint n) +{ + uint8 *pD = (uint8*)p; + const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF; + while (n) + { + pD[0] = l; pD[1] = h; pD += 2; + n--; + } +} + +// Refill the input buffer. +// This method will sit in a loop until (A) the buffer is full or (B) +// the stream's read() method reports and end of file condition. +void jpeg_decoder::prep_in_buffer() +{ + m_in_buf_left = 0; + m_pIn_buf_ofs = m_in_buf; + + if (m_eof_flag) + return; + + do + { + int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag); + if (bytes_read == -1) + stop_decoding(JPGD_STREAM_READ); + + m_in_buf_left += bytes_read; + } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag)); + + m_total_bytes_read += m_in_buf_left; + + // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid). + // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.) + word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64); +} + +// Read a Huffman code table. +void jpeg_decoder::read_dht_marker() +{ + int i, index, count; + uint8 huff_num[17]; + uint8 huff_val[256]; + + uint num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_DHT_MARKER); + + num_left -= 2; + + while (num_left) + { + index = get_bits(8); + + huff_num[0] = 0; + + count = 0; + + for (i = 1; i <= 16; i++) + { + huff_num[i] = static_cast(get_bits(8)); + count += huff_num[i]; + } + + if (count > 255) + stop_decoding(JPGD_BAD_DHT_COUNTS); + + for (i = 0; i < count; i++) + huff_val[i] = static_cast(get_bits(8)); + + i = 1 + 16 + count; + + if (num_left < (uint)i) + stop_decoding(JPGD_BAD_DHT_MARKER); + + num_left -= i; + + if ((index & 0x10) > 0x10) + stop_decoding(JPGD_BAD_DHT_INDEX); + + index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1); + + if (index >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_BAD_DHT_INDEX); + + if (!m_huff_num[index]) + m_huff_num[index] = (uint8 *)alloc(17); + + if (!m_huff_val[index]) + m_huff_val[index] = (uint8 *)alloc(256); + + m_huff_ac[index] = (index & 0x10) != 0; + memcpy(m_huff_num[index], huff_num, 17); + memcpy(m_huff_val[index], huff_val, 256); + } +} + +// Read a quantization table. +void jpeg_decoder::read_dqt_marker() +{ + int n, i, prec; + uint num_left; + uint temp; + + num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_DQT_MARKER); + + num_left -= 2; + + while (num_left) + { + n = get_bits(8); + prec = n >> 4; + n &= 0x0F; + + if (n >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_BAD_DQT_TABLE); + + if (!m_quant[n]) + m_quant[n] = (jpgd_quant_t *)alloc(64 * sizeof(jpgd_quant_t)); + + // read quantization entries, in zag order + for (i = 0; i < 64; i++) + { + temp = get_bits(8); + + if (prec) + temp = (temp << 8) + get_bits(8); + + m_quant[n][i] = static_cast(temp); + } + + i = 64 + 1; + + if (prec) + i += 64; + + if (num_left < (uint)i) + stop_decoding(JPGD_BAD_DQT_LENGTH); + + num_left -= i; + } +} + +// Read the start of frame (SOF) marker. +void jpeg_decoder::read_sof_marker() +{ + int i; + uint num_left; + + num_left = get_bits(16); + + if (get_bits(8) != 8) /* precision: sorry, only 8-bit precision is supported right now */ + stop_decoding(JPGD_BAD_PRECISION); + + m_image_y_size = get_bits(16); + + if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) + stop_decoding(JPGD_BAD_HEIGHT); + + m_image_x_size = get_bits(16); + + if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH)) + stop_decoding(JPGD_BAD_WIDTH); + + m_comps_in_frame = get_bits(8); + + if (m_comps_in_frame > JPGD_MAX_COMPONENTS) + stop_decoding(JPGD_TOO_MANY_COMPONENTS); + + if (num_left != (uint)(m_comps_in_frame * 3 + 8)) + stop_decoding(JPGD_BAD_SOF_LENGTH); + + for (i = 0; i < m_comps_in_frame; i++) + { + m_comp_ident[i] = get_bits(8); + m_comp_h_samp[i] = get_bits(4); + m_comp_v_samp[i] = get_bits(4); + m_comp_quant[i] = get_bits(8); + } +} + +// Used to skip unrecognized markers. +void jpeg_decoder::skip_variable_marker() +{ + uint num_left; + + num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_VARIABLE_MARKER); + + num_left -= 2; + + while (num_left) + { + get_bits(8); + num_left--; + } +} + +// Read a define restart interval (DRI) marker. +void jpeg_decoder::read_dri_marker() +{ + if (get_bits(16) != 4) + stop_decoding(JPGD_BAD_DRI_LENGTH); + + m_restart_interval = get_bits(16); +} + +// Read a start of scan (SOS) marker. +void jpeg_decoder::read_sos_marker() +{ + uint num_left; + int i, ci, n, c, cc; + + num_left = get_bits(16); + + n = get_bits(8); + + m_comps_in_scan = n; + + num_left -= 3; + + if ( (num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN) ) + stop_decoding(JPGD_BAD_SOS_LENGTH); + + for (i = 0; i < n; i++) + { + cc = get_bits(8); + c = get_bits(8); + num_left -= 2; + + for (ci = 0; ci < m_comps_in_frame; ci++) + if (cc == m_comp_ident[ci]) + break; + + if (ci >= m_comps_in_frame) + stop_decoding(JPGD_BAD_SOS_COMP_ID); + + m_comp_list[i] = ci; + m_comp_dc_tab[ci] = (c >> 4) & 15; + m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1); + } + + m_spectral_start = get_bits(8); + m_spectral_end = get_bits(8); + m_successive_high = get_bits(4); + m_successive_low = get_bits(4); + + if (!m_progressive_flag) + { + m_spectral_start = 0; + m_spectral_end = 63; + } + + num_left -= 3; + + while (num_left) /* read past whatever is num_left */ + { + get_bits(8); + num_left--; + } +} + +// Finds the next marker. +int jpeg_decoder::next_marker() +{ + uint c, bytes; + + bytes = 0; + + do + { + do + { + bytes++; + c = get_bits(8); + } while (c != 0xFF); + + do + { + c = get_bits(8); + } while (c == 0xFF); + + } while (c == 0); + + // If bytes > 0 here, there where extra bytes before the marker (not good). + + return c; +} + +// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is +// encountered. +int jpeg_decoder::process_markers() +{ + int c; + + for ( ; ; ) + { + c = next_marker(); + + switch (c) + { + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: +// case M_JPG: + case M_SOF9: + case M_SOF10: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + case M_SOI: + case M_EOI: + case M_SOS: + { + return c; + } + case M_DHT: + { + read_dht_marker(); + break; + } + // No arithmitic support - dumb patents! + case M_DAC: + { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + case M_DQT: + { + read_dqt_marker(); + break; + } + case M_DRI: + { + read_dri_marker(); + break; + } + //case M_APP0: /* no need to read the JFIF marker */ + + case M_JPG: + case M_RST0: /* no parameters */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: + { + stop_decoding(JPGD_UNEXPECTED_MARKER); + break; + } + default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ + { + skip_variable_marker(); + break; + } + } + } +} + +// Finds the start of image (SOI) marker. +// This code is rather defensive: it only checks the first 512 bytes to avoid +// false positives. +void jpeg_decoder::locate_soi_marker() +{ + uint lastchar, thischar; + uint bytesleft; + + lastchar = get_bits(8); + + thischar = get_bits(8); + + /* ok if it's a normal JPEG file without a special header */ + + if ((lastchar == 0xFF) && (thischar == M_SOI)) + return; + + bytesleft = 4096; //512; + + for ( ; ; ) + { + if (--bytesleft == 0) + stop_decoding(JPGD_NOT_JPEG); + + lastchar = thischar; + + thischar = get_bits(8); + + if (lastchar == 0xFF) + { + if (thischar == M_SOI) + break; + else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end + stop_decoding(JPGD_NOT_JPEG); + } + } + + // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad. + thischar = (m_bit_buf >> 24) & 0xFF; + + if (thischar != 0xFF) + stop_decoding(JPGD_NOT_JPEG); +} + +// Find a start of frame (SOF) marker. +void jpeg_decoder::locate_sof_marker() +{ + locate_soi_marker(); + + int c = process_markers(); + + switch (c) + { + case M_SOF2: + m_progressive_flag = JPGD_TRUE; + case M_SOF0: /* baseline DCT */ + case M_SOF1: /* extended sequential DCT */ + { + read_sof_marker(); + break; + } + case M_SOF9: /* Arithmitic coding */ + { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + default: + { + stop_decoding(JPGD_UNSUPPORTED_MARKER); + break; + } + } +} + +// Find a start of scan (SOS) marker. +int jpeg_decoder::locate_sos_marker() +{ + int c; + + c = process_markers(); + + if (c == M_EOI) + return JPGD_FALSE; + else if (c != M_SOS) + stop_decoding(JPGD_UNEXPECTED_MARKER); + + read_sos_marker(); + + return JPGD_TRUE; +} + +// Reset everything to default/uninitialized state. +void jpeg_decoder::init(jpeg_decoder_stream *pStream) +{ + m_pMem_blocks = NULL; + m_error_code = JPGD_SUCCESS; + m_ready_flag = false; + m_image_x_size = m_image_y_size = 0; + m_pStream = pStream; + m_progressive_flag = JPGD_FALSE; + + memset(m_huff_ac, 0, sizeof(m_huff_ac)); + memset(m_huff_num, 0, sizeof(m_huff_num)); + memset(m_huff_val, 0, sizeof(m_huff_val)); + memset(m_quant, 0, sizeof(m_quant)); + + m_scan_type = 0; + m_comps_in_frame = 0; + + memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp)); + memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp)); + memset(m_comp_quant, 0, sizeof(m_comp_quant)); + memset(m_comp_ident, 0, sizeof(m_comp_ident)); + memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks)); + memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks)); + + m_comps_in_scan = 0; + memset(m_comp_list, 0, sizeof(m_comp_list)); + memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab)); + memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab)); + + m_spectral_start = 0; + m_spectral_end = 0; + m_successive_low = 0; + m_successive_high = 0; + m_max_mcu_x_size = 0; + m_max_mcu_y_size = 0; + m_blocks_per_mcu = 0; + m_max_blocks_per_row = 0; + m_mcus_per_row = 0; + m_mcus_per_col = 0; + m_expanded_blocks_per_component = 0; + m_expanded_blocks_per_mcu = 0; + m_expanded_blocks_per_row = 0; + m_freq_domain_chroma_upsample = false; + + memset(m_mcu_org, 0, sizeof(m_mcu_org)); + + m_total_lines_left = 0; + m_mcu_lines_left = 0; + m_real_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_pixel = 0; + + memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs)); + + memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs)); + memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs)); + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + m_eob_run = 0; + + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + m_pIn_buf_ofs = m_in_buf; + m_in_buf_left = 0; + m_eof_flag = false; + m_tem_flag = 0; + + memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start)); + memset(m_in_buf, 0, sizeof(m_in_buf)); + memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end)); + + m_restart_interval = 0; + m_restarts_left = 0; + m_next_restart_num = 0; + + m_max_mcus_per_row = 0; + m_max_blocks_per_mcu = 0; + m_max_mcus_per_col = 0; + + memset(m_last_dc_val, 0, sizeof(m_last_dc_val)); + m_pMCU_coefficients = NULL; + m_pSample_buf = NULL; + + m_total_bytes_read = 0; + + m_pScan_line_0 = NULL; + m_pScan_line_1 = NULL; + + // Ready the input buffer. + prep_in_buffer(); + + // Prime the bit buffer. + m_bits_left = 16; + m_bit_buf = 0; + + get_bits(16); + get_bits(16); + + for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++) + m_mcu_block_max_zag[i] = 64; +} + +#define SCALEBITS 16 +#define ONE_HALF ((int) 1 << (SCALEBITS-1)) +#define FIX(x) ((int) ((x) * (1L<> SCALEBITS; + m_cbb[i] = ( FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS; + m_crg[i] = (-FIX(0.71414f)) * k; + m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF; + } +} + +// This method throws back into the stream any bytes that where read +// into the bit buffer during initial marker scanning. +void jpeg_decoder::fix_in_buffer() +{ + // In case any 0xFF's where pulled into the buffer during marker scanning. + JPGD_ASSERT((m_bits_left & 7) == 0); + + if (m_bits_left == 16) + stuff_char( (uint8)(m_bit_buf & 0xFF)); + + if (m_bits_left >= 8) + stuff_char( (uint8)((m_bit_buf >> 8) & 0xFF)); + + stuff_char((uint8)((m_bit_buf >> 16) & 0xFF)); + stuff_char((uint8)((m_bit_buf >> 24) & 0xFF)); + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); +} + +void jpeg_decoder::transform_mcu(int mcu_row) +{ + jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; + uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); + pSrc_ptr += 64; + pDst_ptr += 64; + } +} + +static const uint8 s_max_rc[64] = +{ + 17, 18, 34, 50, 50, 51, 52, 52, 52, 68, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86, + 102, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, 120, 120, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136 +}; + +void jpeg_decoder::transform_mcu_expand(int mcu_row) +{ + jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; + uint8* pDst_ptr = m_pSample_buf + mcu_row * m_expanded_blocks_per_mcu * 64; + + // Y IDCT + int mcu_block; + for (mcu_block = 0; mcu_block < m_expanded_blocks_per_component; mcu_block++) + { + idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); + pSrc_ptr += 64; + pDst_ptr += 64; + } + + // Chroma IDCT, with upsampling + jpgd_block_t temp_block[64]; + + for (int i = 0; i < 2; i++) + { + DCT_Upsample::Matrix44 P, Q, R, S; + + JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] >= 1); + JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] <= 64); + + int max_zag = m_mcu_block_max_zag[mcu_block++] - 1; + if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis + switch (s_max_rc[max_zag]) + { + case 1*16+1: + DCT_Upsample::P_Q<1, 1>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<1, 1>::calc(R, S, pSrc_ptr); + break; + case 1*16+2: + DCT_Upsample::P_Q<1, 2>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<1, 2>::calc(R, S, pSrc_ptr); + break; + case 2*16+2: + DCT_Upsample::P_Q<2, 2>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<2, 2>::calc(R, S, pSrc_ptr); + break; + case 3*16+2: + DCT_Upsample::P_Q<3, 2>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<3, 2>::calc(R, S, pSrc_ptr); + break; + case 3*16+3: + DCT_Upsample::P_Q<3, 3>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<3, 3>::calc(R, S, pSrc_ptr); + break; + case 3*16+4: + DCT_Upsample::P_Q<3, 4>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<3, 4>::calc(R, S, pSrc_ptr); + break; + case 4*16+4: + DCT_Upsample::P_Q<4, 4>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<4, 4>::calc(R, S, pSrc_ptr); + break; + case 5*16+4: + DCT_Upsample::P_Q<5, 4>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<5, 4>::calc(R, S, pSrc_ptr); + break; + case 5*16+5: + DCT_Upsample::P_Q<5, 5>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<5, 5>::calc(R, S, pSrc_ptr); + break; + case 5*16+6: + DCT_Upsample::P_Q<5, 6>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<5, 6>::calc(R, S, pSrc_ptr); + break; + case 6*16+6: + DCT_Upsample::P_Q<6, 6>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<6, 6>::calc(R, S, pSrc_ptr); + break; + case 7*16+6: + DCT_Upsample::P_Q<7, 6>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<7, 6>::calc(R, S, pSrc_ptr); + break; + case 7*16+7: + DCT_Upsample::P_Q<7, 7>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<7, 7>::calc(R, S, pSrc_ptr); + break; + case 7*16+8: + DCT_Upsample::P_Q<7, 8>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<7, 8>::calc(R, S, pSrc_ptr); + break; + case 8*16+8: + DCT_Upsample::P_Q<8, 8>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<8, 8>::calc(R, S, pSrc_ptr); + break; + default: + JPGD_ASSERT(false); + } + + DCT_Upsample::Matrix44 a(P + Q); P -= Q; + DCT_Upsample::Matrix44& b = P; + DCT_Upsample::Matrix44 c(R + S); R -= S; + DCT_Upsample::Matrix44& d = R; + + DCT_Upsample::Matrix44::add_and_store(temp_block, a, c); + idct_4x4(temp_block, pDst_ptr); + pDst_ptr += 64; + + DCT_Upsample::Matrix44::sub_and_store(temp_block, a, c); + idct_4x4(temp_block, pDst_ptr); + pDst_ptr += 64; + + DCT_Upsample::Matrix44::add_and_store(temp_block, b, d); + idct_4x4(temp_block, pDst_ptr); + pDst_ptr += 64; + + DCT_Upsample::Matrix44::sub_and_store(temp_block, b, d); + idct_4x4(temp_block, pDst_ptr); + pDst_ptr += 64; + + pSrc_ptr += 64; + } +} + +// Loads and dequantizes the next row of (already decoded) coefficients. +// Progressive images only. +void jpeg_decoder::load_next_row() +{ + int i; + jpgd_block_t *p; + jpgd_quant_t *q; + int mcu_row, mcu_block, row_block = 0; + int component_num, component_id; + int block_x_mcu[JPGD_MAX_COMPONENTS]; + + memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + component_id = m_mcu_org[mcu_block]; + q = m_quant[m_comp_quant[component_id]]; + + p = m_pMCU_coefficients + 64 * mcu_block; + + jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + p[0] = pDC[0]; + memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t)); + + for (i = 63; i > 0; i--) + if (p[g_ZAG[i]]) + break; + + m_mcu_block_max_zag[mcu_block] = i + 1; + + for ( ; i >= 0; i--) + if (p[g_ZAG[i]]) + p[g_ZAG[i]] = static_cast(p[g_ZAG[i]] * q[i]); + + row_block++; + + if (m_comps_in_scan == 1) + block_x_mcu[component_id]++; + else + { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) + { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) + { + block_y_mcu_ofs = 0; + + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + + if (m_freq_domain_chroma_upsample) + transform_mcu_expand(mcu_row); + else + transform_mcu(mcu_row); + } + + if (m_comps_in_scan == 1) + m_block_y_mcu[m_comp_list[0]]++; + else + { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + component_id = m_comp_list[component_num]; + + m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } +} + +// Restart interval processing. +void jpeg_decoder::process_restart() +{ + int i; + int c = 0; + + // Align to a byte boundry + // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers! + //get_bits_no_markers(m_bits_left & 7); + + // Let's scan a little bit to find the marker, but not _too_ far. + // 1536 is a "fudge factor" that determines how much to scan. + for (i = 1536; i > 0; i--) + if (get_char() == 0xFF) + break; + + if (i == 0) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + for ( ; i > 0; i--) + if ((c = get_char()) != 0xFF) + break; + + if (i == 0) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Is it the expected marker? If not, something bad happened. + if (c != (m_next_restart_num + M_RST0)) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Reset each component's DC prediction values. + memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); + + m_eob_run = 0; + + m_restarts_left = m_restart_interval; + + m_next_restart_num = (m_next_restart_num + 1) & 7; + + // Get the bit buffer going again... + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); +} + +static inline int dequantize_ac(int c, int q) { c *= q; return c; } + +// Decodes and dequantizes the next row of coefficients. +void jpeg_decoder::decode_next_row() +{ + int row_block = 0; + + for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + if ((m_restart_interval) && (m_restarts_left == 0)) + process_restart(); + + jpgd_block_t* p = m_pMCU_coefficients; + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64) + { + int component_id = m_mcu_org[mcu_block]; + jpgd_quant_t* q = m_quant[m_comp_quant[component_id]]; + + int r, s; + s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r); + s = JPGD_HUFF_EXTEND(r, s); + + m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]); + + p[0] = static_cast(s * q[0]); + + int prev_num_set = m_mcu_block_max_zag[mcu_block]; + + huff_tables *pH = m_pHuff_tabs[m_comp_ac_tab[component_id]]; + + int k; + for (k = 1; k < 64; k++) + { + int extra_bits; + s = huff_decode(pH, extra_bits); + + r = s >> 4; + s &= 15; + + if (s) + { + if (r) + { + if ((k + r) > 63) + stop_decoding(JPGD_DECODE_ERROR); + + if (k < prev_num_set) + { + int n = JPGD_MIN(r, prev_num_set - k); + int kt = k; + while (n--) + p[g_ZAG[kt++]] = 0; + } + + k += r; + } + + s = JPGD_HUFF_EXTEND(extra_bits, s); + + JPGD_ASSERT(k < 64); + + p[g_ZAG[k]] = static_cast(dequantize_ac(s, q[k])); //s * q[k]; + } + else + { + if (r == 15) + { + if ((k + 16) > 64) + stop_decoding(JPGD_DECODE_ERROR); + + if (k < prev_num_set) + { + int n = JPGD_MIN(16, prev_num_set - k); + int kt = k; + while (n--) + { + JPGD_ASSERT(kt <= 63); + p[g_ZAG[kt++]] = 0; + } + } + + k += 16 - 1; // - 1 because the loop counter is k + JPGD_ASSERT(p[g_ZAG[k]] == 0); + } + else + break; + } + } + + if (k < prev_num_set) + { + int kt = k; + while (kt < prev_num_set) + p[g_ZAG[kt++]] = 0; + } + + m_mcu_block_max_zag[mcu_block] = k; + + row_block++; + } + + if (m_freq_domain_chroma_upsample) + transform_mcu_expand(mcu_row); + else + transform_mcu(mcu_row); + + m_restarts_left--; + } +} + +// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB +void jpeg_decoder::H1V1Convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8 *d = m_pScan_line_0; + uint8 *s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + int y = s[j]; + int cb = s[64+j]; + int cr = s[128+j]; + + d[0] = clamp(y + m_crr[cr]); + d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); + d[2] = clamp(y + m_cbb[cb]); + d[3] = 255; + + d += 4; + } + + s += 64*3; + } +} + +// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB +void jpeg_decoder::H2V1Convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8 *d0 = m_pScan_line_0; + uint8 *y = m_pSample_buf + row * 8; + uint8 *c = m_pSample_buf + 2*64 + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int l = 0; l < 2; l++) + { + for (int j = 0; j < 4; j++) + { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j<<1]; + d0[0] = clamp(yy+rc); + d0[1] = clamp(yy+gc); + d0[2] = clamp(yy+bc); + d0[3] = 255; + + yy = y[(j<<1)+1]; + d0[4] = clamp(yy+rc); + d0[5] = clamp(yy+gc); + d0[6] = clamp(yy+bc); + d0[7] = 255; + + d0 += 8; + + c++; + } + y += 64; + } + + y += 64*4 - 64*2; + c += 64*4 - 8; + } +} + +// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB +void jpeg_decoder::H1V2Convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8 *d0 = m_pScan_line_0; + uint8 *d1 = m_pScan_line_1; + uint8 *y; + uint8 *c; + + if (row < 8) + y = m_pSample_buf + row * 8; + else + y = m_pSample_buf + 64*1 + (row & 7) * 8; + + c = m_pSample_buf + 64*2 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + int cb = c[0+j]; + int cr = c[64+j]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j]; + d0[0] = clamp(yy+rc); + d0[1] = clamp(yy+gc); + d0[2] = clamp(yy+bc); + d0[3] = 255; + + yy = y[8+j]; + d1[0] = clamp(yy+rc); + d1[1] = clamp(yy+gc); + d1[2] = clamp(yy+bc); + d1[3] = 255; + + d0 += 4; + d1 += 4; + } + + y += 64*4; + c += 64*4; + } +} + +// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB +void jpeg_decoder::H2V2Convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8 *d0 = m_pScan_line_0; + uint8 *d1 = m_pScan_line_1; + uint8 *y; + uint8 *c; + + if (row < 8) + y = m_pSample_buf + row * 8; + else + y = m_pSample_buf + 64*2 + (row & 7) * 8; + + c = m_pSample_buf + 64*4 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int l = 0; l < 2; l++) + { + for (int j = 0; j < 8; j += 2) + { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j]; + d0[0] = clamp(yy+rc); + d0[1] = clamp(yy+gc); + d0[2] = clamp(yy+bc); + d0[3] = 255; + + yy = y[j+1]; + d0[4] = clamp(yy+rc); + d0[5] = clamp(yy+gc); + d0[6] = clamp(yy+bc); + d0[7] = 255; + + yy = y[j+8]; + d1[0] = clamp(yy+rc); + d1[1] = clamp(yy+gc); + d1[2] = clamp(yy+bc); + d1[3] = 255; + + yy = y[j+8+1]; + d1[4] = clamp(yy+rc); + d1[5] = clamp(yy+gc); + d1[6] = clamp(yy+bc); + d1[7] = 255; + + d0 += 8; + d1 += 8; + + c++; + } + y += 64; + } + + y += 64*6 - 64*2; + c += 64*6 - 8; + } +} + +// Y (1 block per MCU) to 8-bit grayscale +void jpeg_decoder::gray_convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8 *d = m_pScan_line_0; + uint8 *s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + *(uint *)d = *(uint *)s; + *(uint *)(&d[4]) = *(uint *)(&s[4]); + + s += 64; + d += 8; + } +} + +void jpeg_decoder::expanded_convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + + uint8* Py = m_pSample_buf + (row / 8) * 64 * m_comp_h_samp[0] + (row & 7) * 8; + + uint8* d = m_pScan_line_0; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int k = 0; k < m_max_mcu_x_size; k += 8) + { + const int Y_ofs = k * 8; + const int Cb_ofs = Y_ofs + 64 * m_expanded_blocks_per_component; + const int Cr_ofs = Y_ofs + 64 * m_expanded_blocks_per_component * 2; + for (int j = 0; j < 8; j++) + { + int y = Py[Y_ofs + j]; + int cb = Py[Cb_ofs + j]; + int cr = Py[Cr_ofs + j]; + + d[0] = clamp(y + m_crr[cr]); + d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); + d[2] = clamp(y + m_cbb[cb]); + d[3] = 255; + + d += 4; + } + } + + Py += 64 * m_expanded_blocks_per_mcu; + } +} + +// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream. +void jpeg_decoder::find_eoi() +{ + if (!m_progressive_flag) + { + // Attempt to read the EOI marker. + //get_bits_no_markers(m_bits_left & 7); + + // Prime the bit buffer + m_bits_left = 16; + get_bits(16); + get_bits(16); + + // The next marker _should_ be EOI + process_markers(); + } + + m_total_bytes_read -= m_in_buf_left; +} + +int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len) +{ + if ((m_error_code) || (!m_ready_flag)) + return JPGD_FAILED; + + if (m_total_lines_left == 0) + return JPGD_DONE; + + if (m_mcu_lines_left == 0) + { + if (setjmp(m_jmp_state)) + return JPGD_FAILED; + + if (m_progressive_flag) + load_next_row(); + else + decode_next_row(); + + // Find the EOI marker if that was the last row. + if (m_total_lines_left <= m_max_mcu_y_size) + find_eoi(); + + m_mcu_lines_left = m_max_mcu_y_size; + } + + if (m_freq_domain_chroma_upsample) + { + expanded_convert(); + *pScan_line = m_pScan_line_0; + } + else + { + switch (m_scan_type) + { + case JPGD_YH2V2: + { + if ((m_mcu_lines_left & 1) == 0) + { + H2V2Convert(); + *pScan_line = m_pScan_line_0; + } + else + *pScan_line = m_pScan_line_1; + + break; + } + case JPGD_YH2V1: + { + H2V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_YH1V2: + { + if ((m_mcu_lines_left & 1) == 0) + { + H1V2Convert(); + *pScan_line = m_pScan_line_0; + } + else + *pScan_line = m_pScan_line_1; + + break; + } + case JPGD_YH1V1: + { + H1V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_GRAYSCALE: + { + gray_convert(); + *pScan_line = m_pScan_line_0; + + break; + } + } + } + + *pScan_line_len = m_real_dest_bytes_per_scan_line; + + m_mcu_lines_left--; + m_total_lines_left--; + + return JPGD_SUCCESS; +} + +// Creates the tables needed for efficient Huffman decoding. +void jpeg_decoder::make_huff_table(int index, huff_tables *pH) +{ + int p, i, l, si; + uint8 huffsize[257]; + uint huffcode[257]; + uint code; + uint subtree; + int code_size; + int lastp; + int nextfreeentry; + int currententry; + + pH->ac_table = m_huff_ac[index] != 0; + + p = 0; + + for (l = 1; l <= 16; l++) + { + for (i = 1; i <= m_huff_num[index][l]; i++) + huffsize[p++] = static_cast(l); + } + + huffsize[p] = 0; + + lastp = p; + + code = 0; + si = huffsize[0]; + p = 0; + + while (huffsize[p]) + { + while (huffsize[p] == si) + { + huffcode[p++] = code; + code++; + } + + code <<= 1; + si++; + } + + memset(pH->look_up, 0, sizeof(pH->look_up)); + memset(pH->look_up2, 0, sizeof(pH->look_up2)); + memset(pH->tree, 0, sizeof(pH->tree)); + memset(pH->code_size, 0, sizeof(pH->code_size)); + + nextfreeentry = -1; + + p = 0; + + while (p < lastp) + { + i = m_huff_val[index][p]; + code = huffcode[p]; + code_size = huffsize[p]; + + pH->code_size[i] = static_cast(code_size); + + if (code_size <= 8) + { + code <<= (8 - code_size); + + for (l = 1 << (8 - code_size); l > 0; l--) + { + JPGD_ASSERT(i < 256); + + pH->look_up[code] = i; + + bool has_extrabits = false; + int extra_bits = 0; + int num_extra_bits = i & 15; + + int bits_to_fetch = code_size; + if (num_extra_bits) + { + int total_codesize = code_size + num_extra_bits; + if (total_codesize <= 8) + { + has_extrabits = true; + extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize)); + JPGD_ASSERT(extra_bits <= 0x7FFF); + bits_to_fetch += num_extra_bits; + } + } + + if (!has_extrabits) + pH->look_up2[code] = i | (bits_to_fetch << 8); + else + pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8); + + code++; + } + } + else + { + subtree = (code >> (code_size - 8)) & 0xFF; + + currententry = pH->look_up[subtree]; + + if (currententry == 0) + { + pH->look_up[subtree] = currententry = nextfreeentry; + pH->look_up2[subtree] = currententry = nextfreeentry; + + nextfreeentry -= 2; + } + + code <<= (16 - (code_size - 8)); + + for (l = code_size; l > 9; l--) + { + if ((code & 0x8000) == 0) + currententry--; + + if (pH->tree[-currententry - 1] == 0) + { + pH->tree[-currententry - 1] = nextfreeentry; + + currententry = nextfreeentry; + + nextfreeentry -= 2; + } + else + currententry = pH->tree[-currententry - 1]; + + code <<= 1; + } + + if ((code & 0x8000) == 0) + currententry--; + + pH->tree[-currententry - 1] = i; + } + + p++; + } +} + +// Verifies the quantization tables needed for this scan are available. +void jpeg_decoder::check_quant_tables() +{ + for (int i = 0; i < m_comps_in_scan; i++) + if (m_quant[m_comp_quant[m_comp_list[i]]] == NULL) + stop_decoding(JPGD_UNDEFINED_QUANT_TABLE); +} + +// Verifies that all the Huffman tables needed for this scan are available. +void jpeg_decoder::check_huff_tables() +{ + for (int i = 0; i < m_comps_in_scan; i++) + { + if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == NULL)) + stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + + if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == NULL)) + stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + } + + for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++) + if (m_huff_num[i]) + { + if (!m_pHuff_tabs[i]) + m_pHuff_tabs[i] = (huff_tables *)alloc(sizeof(huff_tables)); + + make_huff_table(i, m_pHuff_tabs[i]); + } +} + +// Determines the component order inside each MCU. +// Also calcs how many MCU's are on each row, etc. +void jpeg_decoder::calc_mcu_block_order() +{ + int component_num, component_id; + int max_h_samp = 0, max_v_samp = 0; + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) + { + if (m_comp_h_samp[component_id] > max_h_samp) + max_h_samp = m_comp_h_samp[component_id]; + + if (m_comp_v_samp[component_id] > max_v_samp) + max_v_samp = m_comp_v_samp[component_id]; + } + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) + { + m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8; + m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8; + } + + if (m_comps_in_scan == 1) + { + m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]]; + m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]]; + } + else + { + m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp; + m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp; + } + + if (m_comps_in_scan == 1) + { + m_mcu_org[0] = m_comp_list[0]; + + m_blocks_per_mcu = 1; + } + else + { + m_blocks_per_mcu = 0; + + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + int num_blocks; + + component_id = m_comp_list[component_num]; + + num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id]; + + while (num_blocks--) + m_mcu_org[m_blocks_per_mcu++] = component_id; + } + } +} + +// Starts a new scan. +int jpeg_decoder::init_scan() +{ + if (!locate_sos_marker()) + return JPGD_FALSE; + + calc_mcu_block_order(); + + check_huff_tables(); + + check_quant_tables(); + + memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); + + m_eob_run = 0; + + if (m_restart_interval) + { + m_restarts_left = m_restart_interval; + m_next_restart_num = 0; + } + + fix_in_buffer(); + + return JPGD_TRUE; +} + +// Starts a frame. Determines if the number of components or sampling factors +// are supported. +void jpeg_decoder::init_frame() +{ + int i; + + if (m_comps_in_frame == 1) + { + if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1)) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + m_scan_type = JPGD_GRAYSCALE; + m_max_blocks_per_mcu = 1; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } + else if (m_comps_in_frame == 3) + { + if ( ((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) || + ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)) ) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1)) + { + m_scan_type = JPGD_YH1V1; + + m_max_blocks_per_mcu = 3; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1)) + { + m_scan_type = JPGD_YH2V1; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 8; + } + else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2)) + { + m_scan_type = JPGD_YH1V2; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 16; + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2)) + { + m_scan_type = JPGD_YH2V2; + m_max_blocks_per_mcu = 6; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 16; + } + else + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + } + else + stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size; + m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size; + + // These values are for the *destination* pixels: after conversion. + if (m_scan_type == JPGD_GRAYSCALE) + m_dest_bytes_per_pixel = 1; + else + m_dest_bytes_per_pixel = 4; + + m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel; + + m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel); + + // Initialize two scan line buffers. + m_pScan_line_0 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true); + if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2)) + m_pScan_line_1 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true); + + m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu; + + // Should never happen + if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW) + stop_decoding(JPGD_ASSERTION_ERROR); + + // Allocate the coefficient buffer, enough for one MCU + m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t)); + + for (i = 0; i < m_max_blocks_per_mcu; i++) + m_mcu_block_max_zag[i] = 64; + + m_expanded_blocks_per_component = m_comp_h_samp[0] * m_comp_v_samp[0]; + m_expanded_blocks_per_mcu = m_expanded_blocks_per_component * m_comps_in_frame; + m_expanded_blocks_per_row = m_max_mcus_per_row * m_expanded_blocks_per_mcu; + // Freq. domain chroma upsampling is only supported for H2V2 subsampling factor (the most common one I've seen). + m_freq_domain_chroma_upsample = false; +#if JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING + m_freq_domain_chroma_upsample = (m_expanded_blocks_per_mcu == 4*3); +#endif + + if (m_freq_domain_chroma_upsample) + m_pSample_buf = (uint8 *)alloc(m_expanded_blocks_per_row * 64); + else + m_pSample_buf = (uint8 *)alloc(m_max_blocks_per_row * 64); + + m_total_lines_left = m_image_y_size; + + m_mcu_lines_left = 0; + + create_look_ups(); +} + +// The coeff_buf series of methods originally stored the coefficients +// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache +// was used to make this process more efficient. Now, we can store the entire +// thing in RAM. +jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y) +{ + coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf)); + + cb->block_num_x = block_num_x; + cb->block_num_y = block_num_y; + cb->block_len_x = block_len_x; + cb->block_len_y = block_len_y; + cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t); + cb->pData = (uint8 *)alloc(cb->block_size * block_num_x * block_num_y, true); + return cb; +} + +inline jpgd_block_t *jpeg_decoder::coeff_buf_getp(coeff_buf *cb, int block_x, int block_y) +{ + JPGD_ASSERT((block_x < cb->block_num_x) && (block_y < cb->block_num_y)); + return (jpgd_block_t *)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x)); +} + +// The following methods decode the various types of m_blocks encountered +// in progressively encoded images. +void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y) +{ + int s, r; + jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0) + { + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + } + + pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]); + + p[0] = static_cast(s << pD->m_successive_low); +} + +void jpeg_decoder::decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y) +{ + if (pD->get_bits_no_markers(1)) + { + jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + p[0] |= (1 << pD->m_successive_low); + } +} + +void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y) +{ + int k, s, r; + + if (pD->m_eob_run) + { + pD->m_eob_run--; + return; + } + + jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + + for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++) + { + s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]); + + r = s >> 4; + s &= 15; + + if (s) + { + if ((k += r) > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + + p[g_ZAG[k]] = static_cast(s << pD->m_successive_low); + } + else + { + if (r == 15) + { + if ((k += 15) > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + } + else + { + pD->m_eob_run = 1 << r; + + if (r) + pD->m_eob_run += pD->get_bits_no_markers(r); + + pD->m_eob_run--; + + break; + } + } + } +} + +void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y) +{ + int s, k, r; + int p1 = 1 << pD->m_successive_low; + int m1 = (-1) << pD->m_successive_low; + jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + + JPGD_ASSERT(pD->m_spectral_end <= 63); + + k = pD->m_spectral_start; + + if (pD->m_eob_run == 0) + { + for ( ; k <= pD->m_spectral_end; k++) + { + s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]); + + r = s >> 4; + s &= 15; + + if (s) + { + if (s != 1) + pD->stop_decoding(JPGD_DECODE_ERROR); + + if (pD->get_bits_no_markers(1)) + s = p1; + else + s = m1; + } + else + { + if (r != 15) + { + pD->m_eob_run = 1 << r; + + if (r) + pD->m_eob_run += pD->get_bits_no_markers(r); + + break; + } + } + + do + { + jpgd_block_t *this_coef = p + g_ZAG[k & 63]; + + if (*this_coef != 0) + { + if (pD->get_bits_no_markers(1)) + { + if ((*this_coef & p1) == 0) + { + if (*this_coef >= 0) + *this_coef = static_cast(*this_coef + p1); + else + *this_coef = static_cast(*this_coef + m1); + } + } + } + else + { + if (--r < 0) + break; + } + + k++; + + } while (k <= pD->m_spectral_end); + + if ((s) && (k < 64)) + { + p[g_ZAG[k]] = static_cast(s); + } + } + } + + if (pD->m_eob_run > 0) + { + for ( ; k <= pD->m_spectral_end; k++) + { + jpgd_block_t *this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis + + if (*this_coef != 0) + { + if (pD->get_bits_no_markers(1)) + { + if ((*this_coef & p1) == 0) + { + if (*this_coef >= 0) + *this_coef = static_cast(*this_coef + p1); + else + *this_coef = static_cast(*this_coef + m1); + } + } + } + } + + pD->m_eob_run--; + } +} + +// Decode a scan in a progressively encoded image. +void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func) +{ + int mcu_row, mcu_col, mcu_block; + int block_x_mcu[JPGD_MAX_COMPONENTS], m_block_y_mcu[JPGD_MAX_COMPONENTS]; + + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++) + { + int component_num, component_id; + + memset(block_x_mcu, 0, sizeof(block_x_mcu)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + if ((m_restart_interval) && (m_restarts_left == 0)) + process_restart(); + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + component_id = m_mcu_org[mcu_block]; + + decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + + if (m_comps_in_scan == 1) + block_x_mcu[component_id]++; + else + { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) + { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) + { + block_y_mcu_ofs = 0; + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + + m_restarts_left--; + } + + if (m_comps_in_scan == 1) + m_block_y_mcu[m_comp_list[0]]++; + else + { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + component_id = m_comp_list[component_num]; + m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } + } +} + +// Decode a progressively encoded image. +void jpeg_decoder::init_progressive() +{ + int i; + + if (m_comps_in_frame == 4) + stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + // Allocate the coefficient buffers. + for (i = 0; i < m_comps_in_frame; i++) + { + m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1); + m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8); + } + + for ( ; ; ) + { + int dc_only_scan, refinement_scan; + pDecode_block_func decode_block_func; + + if (!init_scan()) + break; + + dc_only_scan = (m_spectral_start == 0); + refinement_scan = (m_successive_high != 0); + + if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63)) + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if (dc_only_scan) + { + if (m_spectral_end) + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + } + else if (m_comps_in_scan != 1) /* AC scans can only contain one component */ + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if ((refinement_scan) && (m_successive_low != m_successive_high - 1)) + stop_decoding(JPGD_BAD_SOS_SUCCESSIVE); + + if (dc_only_scan) + { + if (refinement_scan) + decode_block_func = decode_block_dc_refine; + else + decode_block_func = decode_block_dc_first; + } + else + { + if (refinement_scan) + decode_block_func = decode_block_ac_refine; + else + decode_block_func = decode_block_ac_first; + } + + decode_scan(decode_block_func); + + m_bits_left = 16; + get_bits(16); + get_bits(16); + } + + m_comps_in_scan = m_comps_in_frame; + + for (i = 0; i < m_comps_in_frame; i++) + m_comp_list[i] = i; + + calc_mcu_block_order(); +} + +void jpeg_decoder::init_sequential() +{ + if (!init_scan()) + stop_decoding(JPGD_UNEXPECTED_MARKER); +} + +void jpeg_decoder::decode_start() +{ + init_frame(); + + if (m_progressive_flag) + init_progressive(); + else + init_sequential(); +} + +void jpeg_decoder::decode_init(jpeg_decoder_stream *pStream) +{ + init(pStream); + locate_sof_marker(); +} + +jpeg_decoder::jpeg_decoder(jpeg_decoder_stream *pStream) +{ + if (setjmp(m_jmp_state)) + return; + decode_init(pStream); +} + +int jpeg_decoder::begin_decoding() +{ + if (m_ready_flag) + return JPGD_SUCCESS; + + if (m_error_code) + return JPGD_FAILED; + + if (setjmp(m_jmp_state)) + return JPGD_FAILED; + + decode_start(); + + m_ready_flag = true; + + return JPGD_SUCCESS; +} + +jpeg_decoder::~jpeg_decoder() +{ + free_all_blocks(); +} + +jpeg_decoder_file_stream::jpeg_decoder_file_stream() +{ + m_pFile = NULL; + m_eof_flag = false; + m_error_flag = false; +} + +void jpeg_decoder_file_stream::close() +{ + if (m_pFile) + { + fclose(m_pFile); + m_pFile = NULL; + } + + m_eof_flag = false; + m_error_flag = false; +} + +jpeg_decoder_file_stream::~jpeg_decoder_file_stream() +{ + close(); +} + +bool jpeg_decoder_file_stream::open(const char *Pfilename) +{ + close(); + + m_eof_flag = false; + m_error_flag = false; + +#if defined(_MSC_VER) + m_pFile = NULL; + fopen_s(&m_pFile, Pfilename, "rb"); +#else + m_pFile = fopen(Pfilename, "rb"); +#endif + return m_pFile != NULL; +} + +int jpeg_decoder_file_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) +{ + if (!m_pFile) + return -1; + + if (m_eof_flag) + { + *pEOF_flag = true; + return 0; + } + + if (m_error_flag) + return -1; + + int bytes_read = static_cast(fread(pBuf, 1, max_bytes_to_read, m_pFile)); + if (bytes_read < max_bytes_to_read) + { + if (ferror(m_pFile)) + { + m_error_flag = true; + return -1; + } + + m_eof_flag = true; + *pEOF_flag = true; + } + + return bytes_read; +} + +bool jpeg_decoder_mem_stream::open(const uint8 *pSrc_data, uint size) +{ + close(); + m_pSrc_data = pSrc_data; + m_ofs = 0; + m_size = size; + return true; +} + +int jpeg_decoder_mem_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) +{ + *pEOF_flag = false; + + if (!m_pSrc_data) + return -1; + + uint bytes_remaining = m_size - m_ofs; + if ((uint)max_bytes_to_read > bytes_remaining) + { + max_bytes_to_read = bytes_remaining; + *pEOF_flag = true; + } + + memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read); + m_ofs += max_bytes_to_read; + + return max_bytes_to_read; +} + +unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps) +{ + if (!actual_comps) + return NULL; + *actual_comps = 0; + + if ((!pStream) || (!width) || (!height) || (!req_comps)) + return NULL; + + if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4)) + return NULL; + + jpeg_decoder decoder(pStream); + if (decoder.get_error_code() != JPGD_SUCCESS) + return NULL; + + const int image_width = decoder.get_width(), image_height = decoder.get_height(); + *width = image_width; + *height = image_height; + *actual_comps = decoder.get_num_components(); + + if (decoder.begin_decoding() != JPGD_SUCCESS) + return NULL; + + const int dst_bpl = image_width * req_comps; + + uint8 *pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height); + if (!pImage_data) + return NULL; + + for (int y = 0; y < image_height; y++) + { + const uint8* pScan_line; + uint scan_line_len; + if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS) + { + jpgd_free(pImage_data); + return NULL; + } + + uint8 *pDst = pImage_data + y * dst_bpl; + + if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3))) + memcpy(pDst, pScan_line, dst_bpl); + else if (decoder.get_num_components() == 1) + { + if (req_comps == 3) + { + for (int x = 0; x < image_width; x++) + { + uint8 luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst += 3; + } + } + else + { + for (int x = 0; x < image_width; x++) + { + uint8 luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst[3] = 255; + pDst += 4; + } + } + } + else if (decoder.get_num_components() == 3) + { + if (req_comps == 1) + { + const int YR = 19595, YG = 38470, YB = 7471; + for (int x = 0; x < image_width; x++) + { + int r = pScan_line[x*4+0]; + int g = pScan_line[x*4+1]; + int b = pScan_line[x*4+2]; + *pDst++ = static_cast((r * YR + g * YG + b * YB + 32768) >> 16); + } + } + else + { + for (int x = 0; x < image_width; x++) + { + pDst[0] = pScan_line[x*4+0]; + pDst[1] = pScan_line[x*4+1]; + pDst[2] = pScan_line[x*4+2]; + pDst += 3; + } + } + } + } + + return pImage_data; +} + +unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps) +{ + jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size); + return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps); +} + +unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps) +{ + jpgd::jpeg_decoder_file_stream file_stream; + if (!file_stream.open(pSrc_filename)) + return NULL; + return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps); +} + +} // namespace jpgd \ No newline at end of file diff --git a/ext/native/ext/jpge/jpgd.h b/ext/native/ext/jpge/jpgd.h new file mode 100644 index 0000000000..150b9a0b26 --- /dev/null +++ b/ext/native/ext/jpge/jpgd.h @@ -0,0 +1,319 @@ +// jpgd.h - C++ class for JPEG decompression. +// Public domain, Rich Geldreich +#ifndef JPEG_DECODER_H +#define JPEG_DECODER_H + +#include +#include +#include + +#ifdef _MSC_VER + #define JPGD_NORETURN __declspec(noreturn) +#elif defined(__GNUC__) + #define JPGD_NORETURN __attribute__ ((noreturn)) +#else + #define JPGD_NORETURN +#endif + +namespace jpgd +{ + typedef unsigned char uint8; + typedef signed short int16; + typedef unsigned short uint16; + typedef unsigned int uint; + typedef signed int int32; + + // Loads a JPEG image from a memory buffer or a file. + // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA). + // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB). + // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly. + // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp. + unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps); + unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps); + + // Success/failure error codes. + enum jpgd_status + { + JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1, + JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE, + JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS, + JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH, + JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER, + JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS, + JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE, + JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, JPGD_ASSERTION_ERROR, + JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM + }; + + // Input stream interface. + // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available. + // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set. + // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer. + // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding. + class jpeg_decoder_stream + { + public: + jpeg_decoder_stream() { } + virtual ~jpeg_decoder_stream() { } + + // The read() method is called when the internal input buffer is empty. + // Parameters: + // pBuf - input buffer + // max_bytes_to_read - maximum bytes that can be written to pBuf + // pEOF_flag - set this to true if at end of stream (no more bytes remaining) + // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0). + // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full. + virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) = 0; + }; + + // stdio FILE stream class. + class jpeg_decoder_file_stream : public jpeg_decoder_stream + { + jpeg_decoder_file_stream(const jpeg_decoder_file_stream &); + jpeg_decoder_file_stream &operator =(const jpeg_decoder_file_stream &); + + FILE *m_pFile; + bool m_eof_flag, m_error_flag; + + public: + jpeg_decoder_file_stream(); + virtual ~jpeg_decoder_file_stream(); + + bool open(const char *Pfilename); + void close(); + + virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag); + }; + + // Memory stream class. + class jpeg_decoder_mem_stream : public jpeg_decoder_stream + { + const uint8 *m_pSrc_data; + uint m_ofs, m_size; + + public: + jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { } + jpeg_decoder_mem_stream(const uint8 *pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { } + + virtual ~jpeg_decoder_mem_stream() { } + + bool open(const uint8 *pSrc_data, uint size); + void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; } + + virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag); + }; + + // Loads JPEG file from a jpeg_decoder_stream. + unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps); + + enum + { + JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4, + JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384 + }; + + typedef int16 jpgd_quant_t; + typedef int16 jpgd_block_t; + + class jpeg_decoder + { + public: + // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc. + // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline. + jpeg_decoder(jpeg_decoder_stream *pStream); + + ~jpeg_decoder(); + + // Call this method after constructing the object to begin decompression. + // If JPGD_SUCCESS is returned you may then call decode() on each scanline. + int begin_decoding(); + + // Returns the next scan line. + // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1). + // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4). + // Returns JPGD_SUCCESS if a scan line has been returned. + // Returns JPGD_DONE if all scan lines have been returned. + // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info. + int decode(const void** pScan_line, uint* pScan_line_len); + + inline jpgd_status get_error_code() const { return m_error_code; } + + inline int get_width() const { return m_image_x_size; } + inline int get_height() const { return m_image_y_size; } + + inline int get_num_components() const { return m_comps_in_frame; } + + inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; } + inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); } + + // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file). + inline int get_total_bytes_read() const { return m_total_bytes_read; } + + private: + jpeg_decoder(const jpeg_decoder &); + jpeg_decoder &operator =(const jpeg_decoder &); + + typedef void (*pDecode_block_func)(jpeg_decoder *, int, int, int); + + struct huff_tables + { + bool ac_table; + uint look_up[256]; + uint look_up2[256]; + uint8 code_size[256]; + uint tree[512]; + }; + + struct coeff_buf + { + uint8 *pData; + int block_num_x, block_num_y; + int block_len_x, block_len_y; + int block_size; + }; + + struct mem_block + { + mem_block *m_pNext; + size_t m_used_count; + size_t m_size; + char m_data[1]; + }; + + jmp_buf m_jmp_state; + mem_block *m_pMem_blocks; + int m_image_x_size; + int m_image_y_size; + jpeg_decoder_stream *m_pStream; + int m_progressive_flag; + uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES]; + uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size + uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size + jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables + int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported) + int m_comps_in_frame; // # of components in frame + int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor + int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor + int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector + int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID + int m_comp_h_blocks[JPGD_MAX_COMPONENTS]; + int m_comp_v_blocks[JPGD_MAX_COMPONENTS]; + int m_comps_in_scan; // # of components in scan + int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan + int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector + int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector + int m_spectral_start; // spectral selection start + int m_spectral_end; // spectral selection end + int m_successive_low; // successive approximation low + int m_successive_high; // successive approximation high + int m_max_mcu_x_size; // MCU's max. X size in pixels + int m_max_mcu_y_size; // MCU's max. Y size in pixels + int m_blocks_per_mcu; + int m_max_blocks_per_row; + int m_mcus_per_row, m_mcus_per_col; + int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU]; + int m_total_lines_left; // total # lines left in image + int m_mcu_lines_left; // total # lines left in this MCU + int m_real_dest_bytes_per_scan_line; + int m_dest_bytes_per_scan_line; // rounded up + int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y) + huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES]; + coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS]; + coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS]; + int m_eob_run; + int m_block_y_mcu[JPGD_MAX_COMPONENTS]; + uint8* m_pIn_buf_ofs; + int m_in_buf_left; + int m_tem_flag; + bool m_eof_flag; + uint8 m_in_buf_pad_start[128]; + uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128]; + uint8 m_in_buf_pad_end[128]; + int m_bits_left; + uint m_bit_buf; + int m_restart_interval; + int m_restarts_left; + int m_next_restart_num; + int m_max_mcus_per_row; + int m_max_blocks_per_mcu; + int m_expanded_blocks_per_mcu; + int m_expanded_blocks_per_row; + int m_expanded_blocks_per_component; + bool m_freq_domain_chroma_upsample; + int m_max_mcus_per_col; + uint m_last_dc_val[JPGD_MAX_COMPONENTS]; + jpgd_block_t* m_pMCU_coefficients; + int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU]; + uint8* m_pSample_buf; + int m_crr[256]; + int m_cbb[256]; + int m_crg[256]; + int m_cbg[256]; + uint8* m_pScan_line_0; + uint8* m_pScan_line_1; + jpgd_status m_error_code; + bool m_ready_flag; + int m_total_bytes_read; + + void free_all_blocks(); + JPGD_NORETURN void stop_decoding(jpgd_status status); + void *alloc(size_t n, bool zero = false); + void word_clear(void *p, uint16 c, uint n); + void prep_in_buffer(); + void read_dht_marker(); + void read_dqt_marker(); + void read_sof_marker(); + void skip_variable_marker(); + void read_dri_marker(); + void read_sos_marker(); + int next_marker(); + int process_markers(); + void locate_soi_marker(); + void locate_sof_marker(); + int locate_sos_marker(); + void init(jpeg_decoder_stream * pStream); + void create_look_ups(); + void fix_in_buffer(); + void transform_mcu(int mcu_row); + void transform_mcu_expand(int mcu_row); + coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y); + inline jpgd_block_t *coeff_buf_getp(coeff_buf *cb, int block_x, int block_y); + void load_next_row(); + void decode_next_row(); + void make_huff_table(int index, huff_tables *pH); + void check_quant_tables(); + void check_huff_tables(); + void calc_mcu_block_order(); + int init_scan(); + void init_frame(); + void process_restart(); + void decode_scan(pDecode_block_func decode_block_func); + void init_progressive(); + void init_sequential(); + void decode_start(); + void decode_init(jpeg_decoder_stream * pStream); + void H2V2Convert(); + void H2V1Convert(); + void H1V2Convert(); + void H1V1Convert(); + void gray_convert(); + void expanded_convert(); + void find_eoi(); + inline uint get_char(); + inline uint get_char(bool *pPadding_flag); + inline void stuff_char(uint8 q); + inline uint8 get_octet(); + inline uint get_bits(int num_bits); + inline uint get_bits_no_markers(int numbits); + inline int huff_decode(huff_tables *pH); + inline int huff_decode(huff_tables *pH, int& extrabits); + static inline uint8 clamp(int i); + static void decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y); + static void decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y); + static void decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y); + static void decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y); + }; + +} // namespace jpgd + +#endif // JPEG_DECODER_H diff --git a/ext/native/ext/jpge/jpge.cpp b/ext/native/ext/jpge/jpge.cpp new file mode 100644 index 0000000000..d355b4f414 --- /dev/null +++ b/ext/native/ext/jpge/jpge.cpp @@ -0,0 +1,1036 @@ +// jpge.cpp - C++ class for JPEG compression. +// Public domain, Rich Geldreich +// v1.01, Dec. 18, 2010 - Initial release +// v1.02, Apr. 6, 2011 - Removed 2x2 ordered dither in H2V1 chroma subsampling method load_block_16_8_8(). (The rounding factor was 2, when it should have been 1. Either way, it wasn't helping.) +// v1.03, Apr. 16, 2011 - Added support for optimized Huffman code tables, optimized dynamic memory allocation down to only 1 alloc. +// Also from Alex Evans: Added RGBA support, linear memory allocator (no longer needed in v1.03). +// v1.04, May. 19, 2012: Forgot to set m_pFile ptr to NULL in cfile_stream::close(). Thanks to Owen Kaluza for reporting this bug. +// Code tweaks to fix VS2008 static code analysis warnings (all looked harmless). +// Code review revealed method load_block_16_8_8() (used for the non-default H2V1 sampling mode to downsample chroma) somehow didn't get the rounding factor fix from v1.02. + +#include "jpge.h" + +#include +#include +// Higher level wrappers/examples (optional). +#include + +#define JPGE_MAX(a,b) (((a)>(b))?(a):(b)) +#define JPGE_MIN(a,b) (((a)<(b))?(a):(b)) + +namespace jpge { + +static inline void *jpge_malloc(size_t nSize) { return malloc(nSize); } +static inline void jpge_free(void *p) { free(p); } + +// Various JPEG enums and tables. +enum { M_SOF0 = 0xC0, M_DHT = 0xC4, M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_APP0 = 0xE0 }; +enum { DC_LUM_CODES = 12, AC_LUM_CODES = 256, DC_CHROMA_CODES = 12, AC_CHROMA_CODES = 256, MAX_HUFF_SYMBOLS = 257, MAX_HUFF_CODESIZE = 32 }; + +static uint8 s_zag[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 }; +static int16 s_std_lum_quant[64] = { 16,11,12,14,12,10,16,14,13,14,18,17,16,19,24,40,26,24,22,22,24,49,35,37,29,40,58,51,61,60,57,51,56,55,64,72,92,78,64,68,87,69,55,56,80,109,81,87,95,98,103,104,103,62,77,113,121,112,100,120,92,101,103,99 }; +static int16 s_std_croma_quant[64] = { 17,18,18,24,21,24,47,26,26,47,99,66,56,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,99,99,99,99,99,99,99,99,99,99,99,99 }; +static uint8 s_dc_lum_bits[17] = { 0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0 }; +static uint8 s_dc_lum_val[DC_LUM_CODES] = { 0,1,2,3,4,5,6,7,8,9,10,11 }; +static uint8 s_ac_lum_bits[17] = { 0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d }; +static uint8 s_ac_lum_val[AC_LUM_CODES] = +{ + 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 uint8 s_dc_chroma_bits[17] = { 0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0 }; +static uint8 s_dc_chroma_val[DC_CHROMA_CODES] = { 0,1,2,3,4,5,6,7,8,9,10,11 }; +static uint8 s_ac_chroma_bits[17] = { 0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77 }; +static uint8 s_ac_chroma_val[AC_CHROMA_CODES] = +{ + 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 +}; + +// Low-level helper functions. +template inline void clear_obj(T &obj) { memset(&obj, 0, sizeof(obj)); } + +const int YR = 19595, YG = 38470, YB = 7471, CB_R = -11059, CB_G = -21709, CB_B = 32768, CR_R = 32768, CR_G = -27439, CR_B = -5329; +static inline uint8 clamp(int i) { if (static_cast(i) > 255U) { if (i < 0) i = 0; else if (i > 255) i = 255; } return static_cast(i); } + +static void RGB_to_YCC(uint8* pDst, const uint8 *pSrc, int num_pixels) +{ + for ( ; num_pixels; pDst += 3, pSrc += 3, num_pixels--) + { + const int r = pSrc[0], g = pSrc[1], b = pSrc[2]; + pDst[0] = static_cast((r * YR + g * YG + b * YB + 32768) >> 16); + pDst[1] = clamp(128 + ((r * CB_R + g * CB_G + b * CB_B + 32768) >> 16)); + pDst[2] = clamp(128 + ((r * CR_R + g * CR_G + b * CR_B + 32768) >> 16)); + } +} + +static void RGB_to_Y(uint8* pDst, const uint8 *pSrc, int num_pixels) +{ + for ( ; num_pixels; pDst++, pSrc += 3, num_pixels--) + pDst[0] = static_cast((pSrc[0] * YR + pSrc[1] * YG + pSrc[2] * YB + 32768) >> 16); +} + +static void RGBA_to_YCC(uint8* pDst, const uint8 *pSrc, int num_pixels) +{ + for ( ; num_pixels; pDst += 3, pSrc += 4, num_pixels--) + { + const int r = pSrc[0], g = pSrc[1], b = pSrc[2]; + pDst[0] = static_cast((r * YR + g * YG + b * YB + 32768) >> 16); + pDst[1] = clamp(128 + ((r * CB_R + g * CB_G + b * CB_B + 32768) >> 16)); + pDst[2] = clamp(128 + ((r * CR_R + g * CR_G + b * CR_B + 32768) >> 16)); + } +} + +static void RGBA_to_Y(uint8* pDst, const uint8 *pSrc, int num_pixels) +{ + for ( ; num_pixels; pDst++, pSrc += 4, num_pixels--) + pDst[0] = static_cast((pSrc[0] * YR + pSrc[1] * YG + pSrc[2] * YB + 32768) >> 16); +} + +static void Y_to_YCC(uint8* pDst, const uint8* pSrc, int num_pixels) +{ + for( ; num_pixels; pDst += 3, pSrc++, num_pixels--) { pDst[0] = pSrc[0]; pDst[1] = 128; pDst[2] = 128; } +} + +// Forward DCT - DCT derived from jfdctint. +enum { CONST_BITS = 13, ROW_BITS = 2 }; +#define DCT_DESCALE(x, n) (((x) + (((int32)1) << ((n) - 1))) >> (n)) +#define DCT_MUL(var, c) (static_cast(var) * static_cast(c)) +#define DCT1D(s0, s1, s2, s3, s4, s5, s6, s7) \ + int32 t0 = s0 + s7, t7 = s0 - s7, t1 = s1 + s6, t6 = s1 - s6, t2 = s2 + s5, t5 = s2 - s5, t3 = s3 + s4, t4 = s3 - s4; \ + int32 t10 = t0 + t3, t13 = t0 - t3, t11 = t1 + t2, t12 = t1 - t2; \ + int32 u1 = DCT_MUL(t12 + t13, 4433); \ + s2 = u1 + DCT_MUL(t13, 6270); \ + s6 = u1 + DCT_MUL(t12, -15137); \ + u1 = t4 + t7; \ + int32 u2 = t5 + t6, u3 = t4 + t6, u4 = t5 + t7; \ + int32 z5 = DCT_MUL(u3 + u4, 9633); \ + t4 = DCT_MUL(t4, 2446); t5 = DCT_MUL(t5, 16819); \ + t6 = DCT_MUL(t6, 25172); t7 = DCT_MUL(t7, 12299); \ + u1 = DCT_MUL(u1, -7373); u2 = DCT_MUL(u2, -20995); \ + u3 = DCT_MUL(u3, -16069); u4 = DCT_MUL(u4, -3196); \ + u3 += z5; u4 += z5; \ + s0 = t10 + t11; s1 = t7 + u1 + u4; s3 = t6 + u2 + u3; s4 = t10 - t11; s5 = t5 + u2 + u4; s7 = t4 + u1 + u3; + +static void DCT2D(int32 *p) +{ + int32 c, *q = p; + for (c = 7; c >= 0; c--, q += 8) + { + int32 s0 = q[0], s1 = q[1], s2 = q[2], s3 = q[3], s4 = q[4], s5 = q[5], s6 = q[6], s7 = q[7]; + DCT1D(s0, s1, s2, s3, s4, s5, s6, s7); + q[0] = s0 << ROW_BITS; q[1] = DCT_DESCALE(s1, CONST_BITS-ROW_BITS); q[2] = DCT_DESCALE(s2, CONST_BITS-ROW_BITS); q[3] = DCT_DESCALE(s3, CONST_BITS-ROW_BITS); + q[4] = s4 << ROW_BITS; q[5] = DCT_DESCALE(s5, CONST_BITS-ROW_BITS); q[6] = DCT_DESCALE(s6, CONST_BITS-ROW_BITS); q[7] = DCT_DESCALE(s7, CONST_BITS-ROW_BITS); + } + for (q = p, c = 7; c >= 0; c--, q++) + { + int32 s0 = q[0*8], s1 = q[1*8], s2 = q[2*8], s3 = q[3*8], s4 = q[4*8], s5 = q[5*8], s6 = q[6*8], s7 = q[7*8]; + DCT1D(s0, s1, s2, s3, s4, s5, s6, s7); + q[0*8] = DCT_DESCALE(s0, ROW_BITS+3); q[1*8] = DCT_DESCALE(s1, CONST_BITS+ROW_BITS+3); q[2*8] = DCT_DESCALE(s2, CONST_BITS+ROW_BITS+3); q[3*8] = DCT_DESCALE(s3, CONST_BITS+ROW_BITS+3); + q[4*8] = DCT_DESCALE(s4, ROW_BITS+3); q[5*8] = DCT_DESCALE(s5, CONST_BITS+ROW_BITS+3); q[6*8] = DCT_DESCALE(s6, CONST_BITS+ROW_BITS+3); q[7*8] = DCT_DESCALE(s7, CONST_BITS+ROW_BITS+3); + } +} + +struct sym_freq { uint m_key, m_sym_index; }; + +// Radix sorts sym_freq[] array by 32-bit key m_key. Returns ptr to sorted values. +static inline sym_freq* radix_sort_syms(uint num_syms, sym_freq* pSyms0, sym_freq* pSyms1) +{ + const uint cMaxPasses = 4; + uint32 hist[256 * cMaxPasses]; clear_obj(hist); + for (uint i = 0; i < num_syms; i++) { uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; hist[256*2 + ((freq >> 16) & 0xFF)]++; hist[256*3 + ((freq >> 24) & 0xFF)]++; } + sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; + uint total_passes = cMaxPasses; while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--; + for (uint pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) + { + const uint32* pHist = &hist[pass << 8]; + uint offsets[256], cur_ofs = 0; + for (uint i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; } + for (uint i = 0; i < num_syms; i++) + pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; + sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; + } + return pCur_syms; +} + +// calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. +static void calculate_minimum_redundancy(sym_freq *A, int n) +{ + int root, leaf, next, avbl, used, dpth; + if (n==0) return; else if (n==1) { A[0].m_key = 1; return; } + A[0].m_key += A[1].m_key; root = 0; leaf = 2; + for (next=1; next < n-1; next++) + { + if (leaf>=n || A[root].m_key=n || (root=0; next--) A[next].m_key = A[A[next].m_key].m_key+1; + avbl = 1; used = dpth = 0; root = n-2; next = n-1; + while (avbl>0) + { + while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; } + while (avbl>used) { A[next--].m_key = dpth; avbl--; } + avbl = 2*used; dpth++; used = 0; + } +} + +// Limits canonical Huffman code table's max code size to max_code_size. +static void huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) +{ + if (code_list_len <= 1) return; + + for (int i = max_code_size + 1; i <= MAX_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i]; + + uint32 total = 0; + for (int i = max_code_size; i > 0; i--) + total += (((uint32)pNum_codes[i]) << (max_code_size - i)); + + while (total != (1UL << max_code_size)) + { + pNum_codes[max_code_size]--; + for (int i = max_code_size - 1; i > 0; i--) + { + if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; } + } + total--; + } +} + +// Generates an optimized offman table. +void jpeg_encoder::optimize_huffman_table(int table_num, int table_len) +{ + sym_freq syms0[MAX_HUFF_SYMBOLS], syms1[MAX_HUFF_SYMBOLS]; + syms0[0].m_key = 1; syms0[0].m_sym_index = 0; // dummy symbol, assures that no valid code contains all 1's + int num_used_syms = 1; + const uint32 *pSym_count = &m_huff_count[table_num][0]; + for (int i = 0; i < table_len; i++) + if (pSym_count[i]) { syms0[num_used_syms].m_key = pSym_count[i]; syms0[num_used_syms++].m_sym_index = i + 1; } + sym_freq* pSyms = radix_sort_syms(num_used_syms, syms0, syms1); + calculate_minimum_redundancy(pSyms, num_used_syms); + + // Count the # of symbols of each code size. + int num_codes[1 + MAX_HUFF_CODESIZE]; clear_obj(num_codes); + for (int i = 0; i < num_used_syms; i++) + num_codes[pSyms[i].m_key]++; + + const uint JPGE_CODE_SIZE_LIMIT = 16; // the maximum possible size of a JPEG Huffman code (valid range is [9,16] - 9 vs. 8 because of the dummy symbol) + huffman_enforce_max_code_size(num_codes, num_used_syms, JPGE_CODE_SIZE_LIMIT); + + // Compute m_huff_bits array, which contains the # of symbols per code size. + clear_obj(m_huff_bits[table_num]); + for (int i = 1; i <= (int)JPGE_CODE_SIZE_LIMIT; i++) + m_huff_bits[table_num][i] = static_cast(num_codes[i]); + + // Remove the dummy symbol added above, which must be in largest bucket. + for (int i = JPGE_CODE_SIZE_LIMIT; i >= 1; i--) + { + if (m_huff_bits[table_num][i]) { m_huff_bits[table_num][i]--; break; } + } + + // Compute the m_huff_val array, which contains the symbol indices sorted by code size (smallest to largest). + for (int i = num_used_syms - 1; i >= 1; i--) + m_huff_val[table_num][num_used_syms - 1 - i] = static_cast(pSyms[i].m_sym_index - 1); +} + +// JPEG marker generation. +void jpeg_encoder::emit_byte(uint8 i) +{ + m_all_stream_writes_succeeded = m_all_stream_writes_succeeded && m_pStream->put_obj(i); +} + +void jpeg_encoder::emit_word(uint i) +{ + emit_byte(uint8(i >> 8)); emit_byte(uint8(i & 0xFF)); +} + +void jpeg_encoder::emit_marker(int marker) +{ + emit_byte(uint8(0xFF)); emit_byte(uint8(marker)); +} + +// Emit JFIF marker +void jpeg_encoder::emit_jfif_app0() +{ + emit_marker(M_APP0); + emit_word(2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); + emit_byte(0x4A); emit_byte(0x46); emit_byte(0x49); emit_byte(0x46); /* Identifier: ASCII "JFIF" */ + emit_byte(0); + emit_byte(1); /* Major version */ + emit_byte(1); /* Minor version */ + emit_byte(0); /* Density unit */ + emit_word(1); + emit_word(1); + emit_byte(0); /* No thumbnail image */ + emit_byte(0); +} + +// Emit quantization tables +void jpeg_encoder::emit_dqt() +{ + for (int i = 0; i < ((m_num_components == 3) ? 2 : 1); i++) + { + emit_marker(M_DQT); + emit_word(64 + 1 + 2); + emit_byte(static_cast(i)); + for (int j = 0; j < 64; j++) + emit_byte(static_cast(m_quantization_tables[i][j])); + } +} + +// Emit start of frame marker +void jpeg_encoder::emit_sof() +{ + emit_marker(M_SOF0); /* baseline */ + emit_word(3 * m_num_components + 2 + 5 + 1); + emit_byte(8); /* precision */ + emit_word(m_image_y); + emit_word(m_image_x); + emit_byte(m_num_components); + for (int i = 0; i < m_num_components; i++) + { + emit_byte(static_cast(i + 1)); /* component ID */ + emit_byte((m_comp_h_samp[i] << 4) + m_comp_v_samp[i]); /* h and v sampling */ + emit_byte(i > 0); /* quant. table num */ + } +} + +// Emit Huffman table. +void jpeg_encoder::emit_dht(uint8 *bits, uint8 *val, int index, bool ac_flag) +{ + emit_marker(M_DHT); + + int length = 0; + for (int i = 1; i <= 16; i++) + length += bits[i]; + + emit_word(length + 2 + 1 + 16); + emit_byte(static_cast(index + (ac_flag << 4))); + + for (int i = 1; i <= 16; i++) + emit_byte(bits[i]); + + for (int i = 0; i < length; i++) + emit_byte(val[i]); +} + +// Emit all Huffman tables. +void jpeg_encoder::emit_dhts() +{ + emit_dht(m_huff_bits[0+0], m_huff_val[0+0], 0, false); + emit_dht(m_huff_bits[2+0], m_huff_val[2+0], 0, true); + if (m_num_components == 3) + { + emit_dht(m_huff_bits[0+1], m_huff_val[0+1], 1, false); + emit_dht(m_huff_bits[2+1], m_huff_val[2+1], 1, true); + } +} + +// emit start of scan +void jpeg_encoder::emit_sos() +{ + emit_marker(M_SOS); + emit_word(2 * m_num_components + 2 + 1 + 3); + emit_byte(m_num_components); + for (int i = 0; i < m_num_components; i++) + { + emit_byte(static_cast(i + 1)); + if (i == 0) + emit_byte((0 << 4) + 0); + else + emit_byte((1 << 4) + 1); + } + emit_byte(0); /* spectral selection */ + emit_byte(63); + emit_byte(0); +} + +// Emit all markers at beginning of image file. +void jpeg_encoder::emit_markers() +{ + emit_marker(M_SOI); + emit_jfif_app0(); + emit_dqt(); + emit_sof(); + emit_dhts(); + emit_sos(); +} + +// Compute the actual canonical Huffman codes/code sizes given the JPEG huff bits and val arrays. +void jpeg_encoder::compute_huffman_table(uint *codes, uint8 *code_sizes, uint8 *bits, uint8 *val) +{ + int i, l, last_p, si; + uint8 huff_size[257]; + uint huff_code[257]; + uint code; + + int p = 0; + for (l = 1; l <= 16; l++) + for (i = 1; i <= bits[l]; i++) + huff_size[p++] = (char)l; + + huff_size[p] = 0; last_p = p; // write sentinel + + code = 0; si = huff_size[0]; p = 0; + + while (huff_size[p]) + { + while (huff_size[p] == si) + huff_code[p++] = code++; + code <<= 1; + si++; + } + + memset(codes, 0, sizeof(codes[0])*256); + memset(code_sizes, 0, sizeof(code_sizes[0])*256); + for (p = 0; p < last_p; p++) + { + codes[val[p]] = huff_code[p]; + code_sizes[val[p]] = huff_size[p]; + } +} + +// Quantization table generation. +void jpeg_encoder::compute_quant_table(int32 *pDst, int16 *pSrc) +{ + int32 q; + if (m_params.m_quality < 50) + q = 5000 / m_params.m_quality; + else + q = 200 - m_params.m_quality * 2; + for (int i = 0; i < 64; i++) + { + int32 j = *pSrc++; j = (j * q + 50L) / 100L; + *pDst++ = JPGE_MIN(JPGE_MAX(j, 1), 255); + } +} + +// Higher-level methods. +void jpeg_encoder::first_pass_init() +{ + m_bit_buffer = 0; m_bits_in = 0; + memset(m_last_dc_val, 0, 3 * sizeof(m_last_dc_val[0])); + m_mcu_y_ofs = 0; + m_pass_num = 1; +} + +bool jpeg_encoder::second_pass_init() +{ + compute_huffman_table(&m_huff_codes[0+0][0], &m_huff_code_sizes[0+0][0], m_huff_bits[0+0], m_huff_val[0+0]); + compute_huffman_table(&m_huff_codes[2+0][0], &m_huff_code_sizes[2+0][0], m_huff_bits[2+0], m_huff_val[2+0]); + if (m_num_components > 1) + { + compute_huffman_table(&m_huff_codes[0+1][0], &m_huff_code_sizes[0+1][0], m_huff_bits[0+1], m_huff_val[0+1]); + compute_huffman_table(&m_huff_codes[2+1][0], &m_huff_code_sizes[2+1][0], m_huff_bits[2+1], m_huff_val[2+1]); + } + first_pass_init(); + emit_markers(); + m_pass_num = 2; + return true; +} + +bool jpeg_encoder::jpg_open(int p_x_res, int p_y_res, int src_channels) +{ + m_num_components = 3; + switch (m_params.m_subsampling) + { + case Y_ONLY: + { + m_num_components = 1; + m_comp_h_samp[0] = 1; m_comp_v_samp[0] = 1; + m_mcu_x = 8; m_mcu_y = 8; + break; + } + case H1V1: + { + m_comp_h_samp[0] = 1; m_comp_v_samp[0] = 1; + m_comp_h_samp[1] = 1; m_comp_v_samp[1] = 1; + m_comp_h_samp[2] = 1; m_comp_v_samp[2] = 1; + m_mcu_x = 8; m_mcu_y = 8; + break; + } + case H2V1: + { + m_comp_h_samp[0] = 2; m_comp_v_samp[0] = 1; + m_comp_h_samp[1] = 1; m_comp_v_samp[1] = 1; + m_comp_h_samp[2] = 1; m_comp_v_samp[2] = 1; + m_mcu_x = 16; m_mcu_y = 8; + break; + } + case H2V2: + { + m_comp_h_samp[0] = 2; m_comp_v_samp[0] = 2; + m_comp_h_samp[1] = 1; m_comp_v_samp[1] = 1; + m_comp_h_samp[2] = 1; m_comp_v_samp[2] = 1; + m_mcu_x = 16; m_mcu_y = 16; + } + } + + m_image_x = p_x_res; m_image_y = p_y_res; + m_image_bpp = src_channels; + m_image_bpl = m_image_x * src_channels; + m_image_x_mcu = (m_image_x + m_mcu_x - 1) & (~(m_mcu_x - 1)); + m_image_y_mcu = (m_image_y + m_mcu_y - 1) & (~(m_mcu_y - 1)); + m_image_bpl_xlt = m_image_x * m_num_components; + m_image_bpl_mcu = m_image_x_mcu * m_num_components; + m_mcus_per_row = m_image_x_mcu / m_mcu_x; + + if ((m_mcu_lines[0] = static_cast(jpge_malloc(m_image_bpl_mcu * m_mcu_y))) == NULL) return false; + for (int i = 1; i < m_mcu_y; i++) + m_mcu_lines[i] = m_mcu_lines[i-1] + m_image_bpl_mcu; + + compute_quant_table(m_quantization_tables[0], s_std_lum_quant); + compute_quant_table(m_quantization_tables[1], m_params.m_no_chroma_discrim_flag ? s_std_lum_quant : s_std_croma_quant); + + m_out_buf_left = JPGE_OUT_BUF_SIZE; + m_pOut_buf = m_out_buf; + + if (m_params.m_two_pass_flag) + { + clear_obj(m_huff_count); + first_pass_init(); + } + else + { + memcpy(m_huff_bits[0+0], s_dc_lum_bits, 17); memcpy(m_huff_val [0+0], s_dc_lum_val, DC_LUM_CODES); + memcpy(m_huff_bits[2+0], s_ac_lum_bits, 17); memcpy(m_huff_val [2+0], s_ac_lum_val, AC_LUM_CODES); + memcpy(m_huff_bits[0+1], s_dc_chroma_bits, 17); memcpy(m_huff_val [0+1], s_dc_chroma_val, DC_CHROMA_CODES); + memcpy(m_huff_bits[2+1], s_ac_chroma_bits, 17); memcpy(m_huff_val [2+1], s_ac_chroma_val, AC_CHROMA_CODES); + if (!second_pass_init()) return false; // in effect, skip over the first pass + } + return m_all_stream_writes_succeeded; +} + +void jpeg_encoder::load_block_8_8_grey(int x) +{ + uint8 *pSrc; + sample_array_t *pDst = m_sample_array; + x <<= 3; + for (int i = 0; i < 8; i++, pDst += 8) + { + pSrc = m_mcu_lines[i] + x; + pDst[0] = pSrc[0] - 128; pDst[1] = pSrc[1] - 128; pDst[2] = pSrc[2] - 128; pDst[3] = pSrc[3] - 128; + pDst[4] = pSrc[4] - 128; pDst[5] = pSrc[5] - 128; pDst[6] = pSrc[6] - 128; pDst[7] = pSrc[7] - 128; + } +} + +void jpeg_encoder::load_block_8_8(int x, int y, int c) +{ + uint8 *pSrc; + sample_array_t *pDst = m_sample_array; + x = (x * (8 * 3)) + c; + y <<= 3; + for (int i = 0; i < 8; i++, pDst += 8) + { + pSrc = m_mcu_lines[y + i] + x; + pDst[0] = pSrc[0 * 3] - 128; pDst[1] = pSrc[1 * 3] - 128; pDst[2] = pSrc[2 * 3] - 128; pDst[3] = pSrc[3 * 3] - 128; + pDst[4] = pSrc[4 * 3] - 128; pDst[5] = pSrc[5 * 3] - 128; pDst[6] = pSrc[6 * 3] - 128; pDst[7] = pSrc[7 * 3] - 128; + } +} + +void jpeg_encoder::load_block_16_8(int x, int c) +{ + uint8 *pSrc1, *pSrc2; + sample_array_t *pDst = m_sample_array; + x = (x * (16 * 3)) + c; + int a = 0, b = 2; + for (int i = 0; i < 16; i += 2, pDst += 8) + { + pSrc1 = m_mcu_lines[i + 0] + x; + pSrc2 = m_mcu_lines[i + 1] + x; + pDst[0] = ((pSrc1[ 0 * 3] + pSrc1[ 1 * 3] + pSrc2[ 0 * 3] + pSrc2[ 1 * 3] + a) >> 2) - 128; pDst[1] = ((pSrc1[ 2 * 3] + pSrc1[ 3 * 3] + pSrc2[ 2 * 3] + pSrc2[ 3 * 3] + b) >> 2) - 128; + pDst[2] = ((pSrc1[ 4 * 3] + pSrc1[ 5 * 3] + pSrc2[ 4 * 3] + pSrc2[ 5 * 3] + a) >> 2) - 128; pDst[3] = ((pSrc1[ 6 * 3] + pSrc1[ 7 * 3] + pSrc2[ 6 * 3] + pSrc2[ 7 * 3] + b) >> 2) - 128; + pDst[4] = ((pSrc1[ 8 * 3] + pSrc1[ 9 * 3] + pSrc2[ 8 * 3] + pSrc2[ 9 * 3] + a) >> 2) - 128; pDst[5] = ((pSrc1[10 * 3] + pSrc1[11 * 3] + pSrc2[10 * 3] + pSrc2[11 * 3] + b) >> 2) - 128; + pDst[6] = ((pSrc1[12 * 3] + pSrc1[13 * 3] + pSrc2[12 * 3] + pSrc2[13 * 3] + a) >> 2) - 128; pDst[7] = ((pSrc1[14 * 3] + pSrc1[15 * 3] + pSrc2[14 * 3] + pSrc2[15 * 3] + b) >> 2) - 128; + int temp = a; a = b; b = temp; + } +} + +void jpeg_encoder::load_block_16_8_8(int x, int c) +{ + uint8 *pSrc1; + sample_array_t *pDst = m_sample_array; + x = (x * (16 * 3)) + c; + for (int i = 0; i < 8; i++, pDst += 8) + { + pSrc1 = m_mcu_lines[i + 0] + x; + pDst[0] = ((pSrc1[ 0 * 3] + pSrc1[ 1 * 3]) >> 1) - 128; pDst[1] = ((pSrc1[ 2 * 3] + pSrc1[ 3 * 3]) >> 1) - 128; + pDst[2] = ((pSrc1[ 4 * 3] + pSrc1[ 5 * 3]) >> 1) - 128; pDst[3] = ((pSrc1[ 6 * 3] + pSrc1[ 7 * 3]) >> 1) - 128; + pDst[4] = ((pSrc1[ 8 * 3] + pSrc1[ 9 * 3]) >> 1) - 128; pDst[5] = ((pSrc1[10 * 3] + pSrc1[11 * 3]) >> 1) - 128; + pDst[6] = ((pSrc1[12 * 3] + pSrc1[13 * 3]) >> 1) - 128; pDst[7] = ((pSrc1[14 * 3] + pSrc1[15 * 3]) >> 1) - 128; + } +} + +void jpeg_encoder::load_quantized_coefficients(int component_num) +{ + int32 *q = m_quantization_tables[component_num > 0]; + int16 *pDst = m_coefficient_array; + for (int i = 0; i < 64; i++) + { + sample_array_t j = m_sample_array[s_zag[i]]; + if (j < 0) + { + if ((j = -j + (*q >> 1)) < *q) + *pDst++ = 0; + else + *pDst++ = static_cast(-(j / *q)); + } + else + { + if ((j = j + (*q >> 1)) < *q) + *pDst++ = 0; + else + *pDst++ = static_cast((j / *q)); + } + q++; + } +} + +void jpeg_encoder::flush_output_buffer() +{ + if (m_out_buf_left != JPGE_OUT_BUF_SIZE) + m_all_stream_writes_succeeded = m_all_stream_writes_succeeded && m_pStream->put_buf(m_out_buf, JPGE_OUT_BUF_SIZE - m_out_buf_left); + m_pOut_buf = m_out_buf; + m_out_buf_left = JPGE_OUT_BUF_SIZE; +} + +void jpeg_encoder::put_bits(uint bits, uint len) +{ + m_bit_buffer |= ((uint32)bits << (24 - (m_bits_in += len))); + while (m_bits_in >= 8) + { + uint8 c; + #define JPGE_PUT_BYTE(c) { *m_pOut_buf++ = (c); if (--m_out_buf_left == 0) flush_output_buffer(); } + JPGE_PUT_BYTE(c = (uint8)((m_bit_buffer >> 16) & 0xFF)); + if (c == 0xFF) JPGE_PUT_BYTE(0); + m_bit_buffer <<= 8; + m_bits_in -= 8; + } +} + +void jpeg_encoder::code_coefficients_pass_one(int component_num) +{ + if (component_num >= 3) return; // just to shut up static analysis + int i, run_len, nbits, temp1; + int16 *src = m_coefficient_array; + uint32 *dc_count = component_num ? m_huff_count[0 + 1] : m_huff_count[0 + 0], *ac_count = component_num ? m_huff_count[2 + 1] : m_huff_count[2 + 0]; + + temp1 = src[0] - m_last_dc_val[component_num]; + m_last_dc_val[component_num] = src[0]; + if (temp1 < 0) temp1 = -temp1; + + nbits = 0; + while (temp1) + { + nbits++; temp1 >>= 1; + } + + dc_count[nbits]++; + for (run_len = 0, i = 1; i < 64; i++) + { + if ((temp1 = m_coefficient_array[i]) == 0) + run_len++; + else + { + while (run_len >= 16) + { + ac_count[0xF0]++; + run_len -= 16; + } + if (temp1 < 0) temp1 = -temp1; + nbits = 1; + while (temp1 >>= 1) nbits++; + ac_count[(run_len << 4) + nbits]++; + run_len = 0; + } + } + if (run_len) ac_count[0]++; +} + +void jpeg_encoder::code_coefficients_pass_two(int component_num) +{ + int i, j, run_len, nbits, temp1, temp2; + int16 *pSrc = m_coefficient_array; + uint *codes[2]; + uint8 *code_sizes[2]; + + if (component_num == 0) + { + codes[0] = m_huff_codes[0 + 0]; codes[1] = m_huff_codes[2 + 0]; + code_sizes[0] = m_huff_code_sizes[0 + 0]; code_sizes[1] = m_huff_code_sizes[2 + 0]; + } + else + { + codes[0] = m_huff_codes[0 + 1]; codes[1] = m_huff_codes[2 + 1]; + code_sizes[0] = m_huff_code_sizes[0 + 1]; code_sizes[1] = m_huff_code_sizes[2 + 1]; + } + + temp1 = temp2 = pSrc[0] - m_last_dc_val[component_num]; + m_last_dc_val[component_num] = pSrc[0]; + + if (temp1 < 0) + { + temp1 = -temp1; temp2--; + } + + nbits = 0; + while (temp1) + { + nbits++; temp1 >>= 1; + } + + put_bits(codes[0][nbits], code_sizes[0][nbits]); + if (nbits) put_bits(temp2 & ((1 << nbits) - 1), nbits); + + for (run_len = 0, i = 1; i < 64; i++) + { + if ((temp1 = m_coefficient_array[i]) == 0) + run_len++; + else + { + while (run_len >= 16) + { + put_bits(codes[1][0xF0], code_sizes[1][0xF0]); + run_len -= 16; + } + if ((temp2 = temp1) < 0) + { + temp1 = -temp1; + temp2--; + } + nbits = 1; + while (temp1 >>= 1) + nbits++; + j = (run_len << 4) + nbits; + put_bits(codes[1][j], code_sizes[1][j]); + put_bits(temp2 & ((1 << nbits) - 1), nbits); + run_len = 0; + } + } + if (run_len) + put_bits(codes[1][0], code_sizes[1][0]); +} + +void jpeg_encoder::code_block(int component_num) +{ + DCT2D(m_sample_array); + load_quantized_coefficients(component_num); + if (m_pass_num == 1) + code_coefficients_pass_one(component_num); + else + code_coefficients_pass_two(component_num); +} + +void jpeg_encoder::process_mcu_row() +{ + if (m_num_components == 1) + { + for (int i = 0; i < m_mcus_per_row; i++) + { + load_block_8_8_grey(i); code_block(0); + } + } + else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1)) + { + for (int i = 0; i < m_mcus_per_row; i++) + { + load_block_8_8(i, 0, 0); code_block(0); load_block_8_8(i, 0, 1); code_block(1); load_block_8_8(i, 0, 2); code_block(2); + } + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1)) + { + for (int i = 0; i < m_mcus_per_row; i++) + { + load_block_8_8(i * 2 + 0, 0, 0); code_block(0); load_block_8_8(i * 2 + 1, 0, 0); code_block(0); + load_block_16_8_8(i, 1); code_block(1); load_block_16_8_8(i, 2); code_block(2); + } + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2)) + { + for (int i = 0; i < m_mcus_per_row; i++) + { + load_block_8_8(i * 2 + 0, 0, 0); code_block(0); load_block_8_8(i * 2 + 1, 0, 0); code_block(0); + load_block_8_8(i * 2 + 0, 1, 0); code_block(0); load_block_8_8(i * 2 + 1, 1, 0); code_block(0); + load_block_16_8(i, 1); code_block(1); load_block_16_8(i, 2); code_block(2); + } + } +} + +bool jpeg_encoder::terminate_pass_one() +{ + optimize_huffman_table(0+0, DC_LUM_CODES); optimize_huffman_table(2+0, AC_LUM_CODES); + if (m_num_components > 1) + { + optimize_huffman_table(0+1, DC_CHROMA_CODES); optimize_huffman_table(2+1, AC_CHROMA_CODES); + } + return second_pass_init(); +} + +bool jpeg_encoder::terminate_pass_two() +{ + put_bits(0x7F, 7); + flush_output_buffer(); + emit_marker(M_EOI); + m_pass_num++; // purposely bump up m_pass_num, for debugging + return true; +} + +bool jpeg_encoder::process_end_of_image() +{ + if (m_mcu_y_ofs) + { + if (m_mcu_y_ofs < 16) // check here just to shut up static analysis + { + for (int i = m_mcu_y_ofs; i < m_mcu_y; i++) + memcpy(m_mcu_lines[i], m_mcu_lines[m_mcu_y_ofs - 1], m_image_bpl_mcu); + } + + process_mcu_row(); + } + + if (m_pass_num == 1) + return terminate_pass_one(); + else + return terminate_pass_two(); +} + +void jpeg_encoder::load_mcu(const void *pSrc) +{ + const uint8* Psrc = reinterpret_cast(pSrc); + + uint8* pDst = m_mcu_lines[m_mcu_y_ofs]; // OK to write up to m_image_bpl_xlt bytes to pDst + + if (m_num_components == 1) + { + if (m_image_bpp == 4) + RGBA_to_Y(pDst, Psrc, m_image_x); + else if (m_image_bpp == 3) + RGB_to_Y(pDst, Psrc, m_image_x); + else + memcpy(pDst, Psrc, m_image_x); + } + else + { + if (m_image_bpp == 4) + RGBA_to_YCC(pDst, Psrc, m_image_x); + else if (m_image_bpp == 3) + RGB_to_YCC(pDst, Psrc, m_image_x); + else + Y_to_YCC(pDst, Psrc, m_image_x); + } + + // Possibly duplicate pixels at end of scanline if not a multiple of 8 or 16 + if (m_num_components == 1) + memset(m_mcu_lines[m_mcu_y_ofs] + m_image_bpl_xlt, pDst[m_image_bpl_xlt - 1], m_image_x_mcu - m_image_x); + else + { + const uint8 y = pDst[m_image_bpl_xlt - 3 + 0], cb = pDst[m_image_bpl_xlt - 3 + 1], cr = pDst[m_image_bpl_xlt - 3 + 2]; + uint8 *q = m_mcu_lines[m_mcu_y_ofs] + m_image_bpl_xlt; + for (int i = m_image_x; i < m_image_x_mcu; i++) + { + *q++ = y; *q++ = cb; *q++ = cr; + } + } + + if (++m_mcu_y_ofs == m_mcu_y) + { + process_mcu_row(); + m_mcu_y_ofs = 0; + } +} + +void jpeg_encoder::clear() +{ + m_mcu_lines[0] = NULL; + m_pass_num = 0; + m_all_stream_writes_succeeded = true; +} + +jpeg_encoder::jpeg_encoder() +{ + clear(); +} + +jpeg_encoder::~jpeg_encoder() +{ + deinit(); +} + +bool jpeg_encoder::init(output_stream *pStream, int width, int height, int src_channels, const params &comp_params) +{ + deinit(); + if (((!pStream) || (width < 1) || (height < 1)) || ((src_channels != 1) && (src_channels != 3) && (src_channels != 4)) || (!comp_params.check())) return false; + m_pStream = pStream; + m_params = comp_params; + return jpg_open(width, height, src_channels); +} + +void jpeg_encoder::deinit() +{ + jpge_free(m_mcu_lines[0]); + clear(); +} + +bool jpeg_encoder::process_scanline(const void* pScanline) +{ + if ((m_pass_num < 1) || (m_pass_num > 2)) return false; + if (m_all_stream_writes_succeeded) + { + if (!pScanline) + { + if (!process_end_of_image()) return false; + } + else + { + load_mcu(pScanline); + } + } + return m_all_stream_writes_succeeded; +} + +class cfile_stream : public output_stream +{ + cfile_stream(const cfile_stream &); + cfile_stream &operator= (const cfile_stream &); + + FILE* m_pFile; + bool m_bStatus; + +public: + cfile_stream() : m_pFile(NULL), m_bStatus(false) { } + + virtual ~cfile_stream() + { + close(); + } + + bool open(const char *pFilename) + { + close(); + m_pFile = fopen(pFilename, "wb"); + m_bStatus = (m_pFile != NULL); + return m_bStatus; + } + + bool close() + { + if (m_pFile) + { + if (fclose(m_pFile) == EOF) + { + m_bStatus = false; + } + m_pFile = NULL; + } + return m_bStatus; + } + + virtual bool put_buf(const void* pBuf, int len) + { + m_bStatus = m_bStatus && (fwrite(pBuf, len, 1, m_pFile) == 1); + return m_bStatus; + } + + uint get_size() const + { + return m_pFile ? ftell(m_pFile) : 0; + } +}; + +// Writes JPEG image to file. +bool compress_image_to_jpeg_file(const char *pFilename, int width, int height, int num_channels, const uint8 *pImage_data, const params &comp_params) +{ + cfile_stream dst_stream; + if (!dst_stream.open(pFilename)) + return false; + + jpge::jpeg_encoder dst_image; + if (!dst_image.init(&dst_stream, width, height, num_channels, comp_params)) + return false; + + for (uint pass_index = 0; pass_index < dst_image.get_total_passes(); pass_index++) + { + for (int i = 0; i < height; i++) + { + const uint8* pBuf = pImage_data + i * width * num_channels; + if (!dst_image.process_scanline(pBuf)) + return false; + } + if (!dst_image.process_scanline(NULL)) + return false; + } + + dst_image.deinit(); + + return dst_stream.close(); +} + +class memory_stream : public output_stream +{ + memory_stream(const memory_stream &); + memory_stream &operator= (const memory_stream &); + + uint8 *m_pBuf; + uint m_buf_size, m_buf_ofs; + +public: + memory_stream(void *pBuf, uint buf_size) : m_pBuf(static_cast(pBuf)), m_buf_size(buf_size), m_buf_ofs(0) { } + + virtual ~memory_stream() { } + + virtual bool put_buf(const void* pBuf, int len) + { + uint buf_remaining = m_buf_size - m_buf_ofs; + if ((uint)len > buf_remaining) + return false; + memcpy(m_pBuf + m_buf_ofs, pBuf, len); + m_buf_ofs += len; + return true; + } + + uint get_size() const + { + return m_buf_ofs; + } +}; + +bool compress_image_to_jpeg_file_in_memory(void *pDstBuf, int &buf_size, int width, int height, int num_channels, const uint8 *pImage_data, const params &comp_params) +{ + if ((!pDstBuf) || (!buf_size)) + return false; + + memory_stream dst_stream(pDstBuf, buf_size); + + buf_size = 0; + + jpge::jpeg_encoder dst_image; + if (!dst_image.init(&dst_stream, width, height, num_channels, comp_params)) + return false; + + for (uint pass_index = 0; pass_index < dst_image.get_total_passes(); pass_index++) + { + for (int i = 0; i < height; i++) + { + const uint8* pScanline = pImage_data + i * width * num_channels; + if (!dst_image.process_scanline(pScanline)) + return false; + } + if (!dst_image.process_scanline(NULL)) + return false; + } + + dst_image.deinit(); + + buf_size = dst_stream.get_size(); + return true; +} + +} // namespace jpge diff --git a/ext/native/ext/jpge/jpge.h b/ext/native/ext/jpge/jpge.h new file mode 100644 index 0000000000..262bbfbb38 --- /dev/null +++ b/ext/native/ext/jpge/jpge.h @@ -0,0 +1,169 @@ +// jpge.h - C++ class for JPEG compression. +// Public domain, Rich Geldreich +// Alex Evans: Added RGBA support, linear memory allocator. +#ifndef JPEG_ENCODER_H +#define JPEG_ENCODER_H + +namespace jpge +{ + typedef unsigned char uint8; + typedef signed short int16; + typedef signed int int32; + typedef unsigned short uint16; + typedef unsigned int uint32; + typedef unsigned int uint; + + // JPEG chroma subsampling factors. Y_ONLY (grayscale images) and H2V2 (color images) are the most common. + enum subsampling_t { Y_ONLY = 0, H1V1 = 1, H2V1 = 2, H2V2 = 3 }; + + // JPEG compression parameters structure. + struct params + { + inline params() : m_quality(85), m_subsampling(H2V2), m_no_chroma_discrim_flag(false), m_two_pass_flag(false) { } + + inline bool check() const + { + if ((m_quality < 1) || (m_quality > 100)) return false; + if ((uint)m_subsampling > (uint)H2V2) return false; + return true; + } + + // Quality: 1-100, higher is better. Typical values are around 50-95. + int m_quality; + + // m_subsampling: + // 0 = Y (grayscale) only + // 1 = YCbCr, no subsampling (H1V1, YCbCr 1x1x1, 3 blocks per MCU) + // 2 = YCbCr, H2V1 subsampling (YCbCr 2x1x1, 4 blocks per MCU) + // 3 = YCbCr, H2V2 subsampling (YCbCr 4x1x1, 6 blocks per MCU-- very common) + subsampling_t m_subsampling; + + // Disables CbCr discrimination - only intended for testing. + // If true, the Y quantization table is also used for the CbCr channels. + bool m_no_chroma_discrim_flag; + + bool m_two_pass_flag; + }; + + // Writes JPEG image to a file. + // num_channels must be 1 (Y) or 3 (RGB), image pitch must be width*num_channels. + bool compress_image_to_jpeg_file(const char *pFilename, int width, int height, int num_channels, const uint8 *pImage_data, const params &comp_params = params()); + + // Writes JPEG image to memory buffer. + // On entry, buf_size is the size of the output buffer pointed at by pBuf, which should be at least ~1024 bytes. + // If return value is true, buf_size will be set to the size of the compressed data. + bool compress_image_to_jpeg_file_in_memory(void *pBuf, int &buf_size, int width, int height, int num_channels, const uint8 *pImage_data, const params &comp_params = params()); + + // Output stream abstract class - used by the jpeg_encoder class to write to the output stream. + // put_buf() is generally called with len==JPGE_OUT_BUF_SIZE bytes, but for headers it'll be called with smaller amounts. + class output_stream + { + public: + virtual ~output_stream() { }; + virtual bool put_buf(const void* Pbuf, int len) = 0; + template inline bool put_obj(const T& obj) { return put_buf(&obj, sizeof(T)); } + }; + + // Lower level jpeg_encoder class - useful if more control is needed than the above helper functions. + class jpeg_encoder + { + public: + jpeg_encoder(); + ~jpeg_encoder(); + + // Initializes the compressor. + // pStream: The stream object to use for writing compressed data. + // params - Compression parameters structure, defined above. + // width, height - Image dimensions. + // channels - May be 1, or 3. 1 indicates grayscale, 3 indicates RGB source data. + // Returns false on out of memory or if a stream write fails. + bool init(output_stream *pStream, int width, int height, int src_channels, const params &comp_params = params()); + + const params &get_params() const { return m_params; } + + // Deinitializes the compressor, freeing any allocated memory. May be called at any time. + void deinit(); + + uint get_total_passes() const { return m_params.m_two_pass_flag ? 2 : 1; } + inline uint get_cur_pass() { return m_pass_num; } + + // Call this method with each source scanline. + // width * src_channels bytes per scanline is expected (RGB or Y format). + // You must call with NULL after all scanlines are processed to finish compression. + // Returns false on out of memory or if a stream write fails. + bool process_scanline(const void* pScanline); + + private: + jpeg_encoder(const jpeg_encoder &); + jpeg_encoder &operator =(const jpeg_encoder &); + + typedef int32 sample_array_t; + + output_stream *m_pStream; + params m_params; + uint8 m_num_components; + uint8 m_comp_h_samp[3], m_comp_v_samp[3]; + int m_image_x, m_image_y, m_image_bpp, m_image_bpl; + int m_image_x_mcu, m_image_y_mcu; + int m_image_bpl_xlt, m_image_bpl_mcu; + int m_mcus_per_row; + int m_mcu_x, m_mcu_y; + uint8 *m_mcu_lines[16]; + uint8 m_mcu_y_ofs; + sample_array_t m_sample_array[64]; + int16 m_coefficient_array[64]; + int32 m_quantization_tables[2][64]; + uint m_huff_codes[4][256]; + uint8 m_huff_code_sizes[4][256]; + uint8 m_huff_bits[4][17]; + uint8 m_huff_val[4][256]; + uint32 m_huff_count[4][256]; + int m_last_dc_val[3]; + enum { JPGE_OUT_BUF_SIZE = 2048 }; + uint8 m_out_buf[JPGE_OUT_BUF_SIZE]; + uint8 *m_pOut_buf; + uint m_out_buf_left; + uint32 m_bit_buffer; + uint m_bits_in; + uint8 m_pass_num; + bool m_all_stream_writes_succeeded; + + void optimize_huffman_table(int table_num, int table_len); + void emit_byte(uint8 i); + void emit_word(uint i); + void emit_marker(int marker); + void emit_jfif_app0(); + void emit_dqt(); + void emit_sof(); + void emit_dht(uint8 *bits, uint8 *val, int index, bool ac_flag); + void emit_dhts(); + void emit_sos(); + void emit_markers(); + void compute_huffman_table(uint *codes, uint8 *code_sizes, uint8 *bits, uint8 *val); + void compute_quant_table(int32 *dst, int16 *src); + void adjust_quant_table(int32 *dst, int32 *src); + void first_pass_init(); + bool second_pass_init(); + bool jpg_open(int p_x_res, int p_y_res, int src_channels); + void load_block_8_8_grey(int x); + void load_block_8_8(int x, int y, int c); + void load_block_16_8(int x, int c); + void load_block_16_8_8(int x, int c); + void load_quantized_coefficients(int component_num); + void flush_output_buffer(); + void put_bits(uint bits, uint len); + void code_coefficients_pass_one(int component_num); + void code_coefficients_pass_two(int component_num); + void code_block(int component_num); + void process_mcu_row(); + bool terminate_pass_one(); + bool terminate_pass_two(); + bool process_end_of_image(); + void load_mcu(const void* src); + void clear(); + void init(); + }; + +} // namespace jpge + +#endif // JPEG_ENCODER diff --git a/ext/native/ext/jpge/publicdomain.txt b/ext/native/ext/jpge/publicdomain.txt new file mode 100644 index 0000000000..639860563a --- /dev/null +++ b/ext/native/ext/jpge/publicdomain.txt @@ -0,0 +1 @@ +This is https://code.google.com/p/jpeg-compressor/ , public domain code. \ No newline at end of file diff --git a/ext/native/ext/libpng17/CMakeLists.txt b/ext/native/ext/libpng17/CMakeLists.txt new file mode 100644 index 0000000000..d2829cd3fe --- /dev/null +++ b/ext/native/ext/libpng17/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.6) + +add_library(png17 + pngconf.h + pngdebug.h + png.c + png.h + pngerror.c + pngget.c + pnginfo.h + pnglibconf.h + pngmem.c + pngpread.c + pngpriv.h + pngread.c + pngrio.c + pngrtran.c + pngrutil.c + pngset.c + pngstruct.h + pngtest.c + pngtrans.c + pngwio.c + pngwrite.c + pngwtran.c + pngwutil.c) diff --git a/ext/native/ext/libpng17/arm/arm_init.c b/ext/native/ext/libpng17/arm/arm_init.c new file mode 100644 index 0000000000..a672eaebb5 --- /dev/null +++ b/ext/native/ext/libpng17/arm/arm_init.c @@ -0,0 +1,133 @@ + +/* arm_init.c - NEON optimised filter functions + * + * Copyright (c) 2014 Glenn Randers-Pehrson + * Written by Mans Rullgard, 2011. + * Last changed in libpng 1.6.10 [(PENDING RELEASE)] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ +/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are + * called. + */ +#define _POSIX_SOURCE 1 + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED +#if PNG_ARM_NEON_OPT > 0 +#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ +/* WARNING: it is strongly recommended that you do not build libpng with + * run-time checks for CPU features if at all possible. In the case of the ARM + * NEON instructions there is no processor-specific way of detecting the + * presence of the required support, therefore run-time detection is extremely + * OS specific. + * + * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing + * a fragment of C source code which defines the png_have_neon function. There + * are a number of implementations in contrib/arm-neon, but the only one that + * has partial support is contrib/arm-neon/linux.c - a generic Linux + * implementation which reads /proc/cpufino. + */ +#ifndef PNG_ARM_NEON_FILE +# ifdef __linux__ +# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" +# endif +#endif + +#ifdef PNG_ARM_NEON_FILE + +#include /* for sig_atomic_t */ +static int png_have_neon(png_structp png_ptr); +#include PNG_ARM_NEON_FILE + +#else /* PNG_ARM_NEON_FILE */ +# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks" +#endif /* PNG_ARM_NEON_FILE */ +#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ + +#ifndef PNG_ALIGNED_MEMORY_SUPPORTED +# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" +#endif + +void +png_init_filter_functions_neon(png_structp pp, unsigned int bpp) +{ + /* The switch statement is compiled in for ARM_NEON_API, the call to + * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined + * the check is only performed if the API has not set the NEON option on + * or off explicitly. In this case the check controls what happens. + * + * If the CHECK is not compiled in and the option is UNSET the behavior prior + * to 1.6.7 was to use the NEON code - this was a bug caused by having the + * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, + * as documented in png.h + */ +#ifdef PNG_ARM_NEON_API_SUPPORTED + switch ((pp->options >> PNG_ARM_NEON) & 3) + { + case PNG_OPTION_UNSET: + /* Allow the run-time check to execute if it has been enabled - + * thus both API and CHECK can be turned on. If it isn't supported + * this case will fall through to the 'default' below, which just + * returns. + */ +#endif /* PNG_ARM_NEON_API_SUPPORTED */ +#ifdef PNG_ARM_NEON_CHECK_SUPPORTED + { + static volatile sig_atomic_t no_neon = -1; /* not checked */ + + if (no_neon < 0) + no_neon = !png_have_neon(pp); + + if (no_neon) + return; + } +#ifdef PNG_ARM_NEON_API_SUPPORTED + break; +#endif +#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ + +#ifdef PNG_ARM_NEON_API_SUPPORTED + default: /* OFF or INVALID */ + return; + + case PNG_OPTION_ON: + /* Option turned on */ + break; + } +#endif + + /* IMPORTANT: any new external functions used here must be declared using + * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the + * 'prefix' option to configure works: + * + * ./configure --with-libpng-prefix=foobar_ + * + * Verify you have got this right by running the above command, doing a build + * and examining pngprefix.h; it must contain a #define for every external + * function you add. (Notice that this happens automatically for the + * initialization function.) + */ + 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_OPT > 0 */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/ext/native/ext/libpng17/arm/filter_neon.S b/ext/native/ext/libpng17/arm/filter_neon.S new file mode 100644 index 0000000000..40d97775d6 --- /dev/null +++ b/ext/native/ext/libpng17/arm/filter_neon.S @@ -0,0 +1,246 @@ + +/* filter_neon.S - NEON optimised filter functions + * + * Copyright (c) 2013 Glenn Randers-Pehrson + * Written by Mans Rullgard, 2011. + * Last changed in libpng 1.6.8 [December 19, 2013] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* This is required to get the symbol renames, which are #defines, and also + * includes the definition (or not) of PNG_ARM_NEON_OPT and + * PNG_ARM_NEON_IMPLEMENTATION. + */ +#define PNG_VERSION_INFO_ONLY +#include "../pngpriv.h" + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ +#endif + +/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for + * ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it + * only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h + * for the logic which sets PNG_USE_ARM_NEON_ASM: + */ +#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */ + +#ifdef PNG_READ_SUPPORTED +#if PNG_ARM_NEON_OPT > 0 + +#ifdef __ELF__ +# define ELF +#else +# define ELF @ +#endif + + .arch armv7-a + .fpu neon + +.macro func name, export=0 + .macro endfunc +ELF .size \name, . - \name + .endfunc + .purgem endfunc + .endm + .text + .if \export + .global \name + .endif +ELF .type \name, STT_FUNC + .func \name +\name: +.endm + +func png_read_filter_row_sub4_neon, export=1 + ldr r3, [r0, #4] @ rowbytes + vmov.i8 d3, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vadd.u8 d0, d3, d4 + vadd.u8 d1, d0, d5 + vadd.u8 d2, d1, d6 + vadd.u8 d3, d2, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r3, r3, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_sub3_neon, export=1 + ldr r3, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + mov r0, r1 + mov r2, #3 + mov r12, #12 + vld1.8 {q11}, [r0], r12 +1: + vext.8 d5, d22, d23, #3 + vadd.u8 d0, d3, d22 + vext.8 d6, d22, d23, #6 + vadd.u8 d1, d0, d5 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], r12 + vst1.32 {d0[0]}, [r1,:32], r2 + vadd.u8 d2, d1, d6 + vst1.32 {d1[0]}, [r1], r2 + vadd.u8 d3, d2, d7 + vst1.32 {d2[0]}, [r1], r2 + vst1.32 {d3[0]}, [r1], r2 + subs r3, r3, #12 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_up_neon, export=1 + ldr r3, [r0, #4] @ rowbytes +1: + vld1.8 {q0}, [r1,:128] + vld1.8 {q1}, [r2,:128]! + vadd.u8 q0, q0, q1 + vst1.8 {q0}, [r1,:128]! + subs r3, r3, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_avg4_neon, export=1 + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! + vhadd.u8 d0, d3, d16 + vadd.u8 d0, d0, d4 + vhadd.u8 d1, d0, d17 + vadd.u8 d1, d1, d5 + vhadd.u8 d2, d1, d18 + vadd.u8 d2, d2, d6 + vhadd.u8 d3, d2, d19 + vadd.u8 d3, d3, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r12, r12, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_avg3_neon, export=1 + push {r4,lr} + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + mov r0, r1 + mov r4, #3 + mov lr, #12 + vld1.8 {q11}, [r0], lr +1: + vld1.8 {q10}, [r2], lr + vext.8 d5, d22, d23, #3 + vhadd.u8 d0, d3, d20 + vext.8 d17, d20, d21, #3 + vadd.u8 d0, d0, d22 + vext.8 d6, d22, d23, #6 + vhadd.u8 d1, d0, d17 + vext.8 d18, d20, d21, #6 + vadd.u8 d1, d1, d5 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], lr + vst1.32 {d0[0]}, [r1,:32], r4 + vhadd.u8 d2, d1, d18 + vst1.32 {d1[0]}, [r1], r4 + vext.8 d19, d21, d21, #1 + vadd.u8 d2, d2, d6 + vhadd.u8 d3, d2, d19 + vst1.32 {d2[0]}, [r1], r4 + vadd.u8 d3, d3, d7 + vst1.32 {d3[0]}, [r1], r4 + subs r12, r12, #12 + bgt 1b + + pop {r4,pc} +endfunc + +.macro paeth rx, ra, rb, rc + vaddl.u8 q12, \ra, \rb @ a + b + vaddl.u8 q15, \rc, \rc @ 2*c + vabdl.u8 q13, \rb, \rc @ pa + vabdl.u8 q14, \ra, \rc @ pb + vabd.u16 q15, q12, q15 @ pc + vcle.u16 q12, q13, q14 @ pa <= pb + vcle.u16 q13, q13, q15 @ pa <= pc + vcle.u16 q14, q14, q15 @ pb <= pc + vand q12, q12, q13 @ pa <= pb && pa <= pc + vmovn.u16 d28, q14 + vmovn.u16 \rx, q12 + vbsl d28, \rb, \rc + vbsl \rx, \ra, d28 +.endm + +func png_read_filter_row_paeth4_neon, export=1 + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + vmov.i8 d20, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! + paeth d0, d3, d16, d20 + vadd.u8 d0, d0, d4 + paeth d1, d0, d17, d16 + vadd.u8 d1, d1, d5 + paeth d2, d1, d18, d17 + vadd.u8 d2, d2, d6 + paeth d3, d2, d19, d18 + vmov d20, d19 + vadd.u8 d3, d3, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r12, r12, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_paeth3_neon, export=1 + push {r4,lr} + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + vmov.i8 d4, #0 + mov r0, r1 + mov r4, #3 + mov lr, #12 + vld1.8 {q11}, [r0], lr +1: + vld1.8 {q10}, [r2], lr + paeth d0, d3, d20, d4 + vext.8 d5, d22, d23, #3 + vadd.u8 d0, d0, d22 + vext.8 d17, d20, d21, #3 + paeth d1, d0, d17, d20 + vst1.32 {d0[0]}, [r1,:32], r4 + vext.8 d6, d22, d23, #6 + vadd.u8 d1, d1, d5 + vext.8 d18, d20, d21, #6 + paeth d2, d1, d18, d17 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], lr + vst1.32 {d1[0]}, [r1], r4 + vadd.u8 d2, d2, d6 + vext.8 d19, d21, d21, #1 + paeth d3, d2, d19, d18 + vst1.32 {d2[0]}, [r1], r4 + vmov d4, d19 + vadd.u8 d3, d3, d7 + vst1.32 {d3[0]}, [r1], r4 + subs r12, r12, #12 + bgt 1b + + pop {r4,pc} +endfunc +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */ diff --git a/ext/native/ext/libpng17/arm/filter_neon_intrinsics.c b/ext/native/ext/libpng17/arm/filter_neon_intrinsics.c new file mode 100644 index 0000000000..e7a09f4364 --- /dev/null +++ b/ext/native/ext/libpng17/arm/filter_neon_intrinsics.c @@ -0,0 +1,372 @@ + +/* filter_neon_intrinsics.c - NEON optimised filter functions + * + * Copyright (c) 2013 Glenn Randers-Pehrson + * Written by James Yu , October 2013. + * Based on filter_neon.S, written by Mans Rullgard, 2011. + * + * Last changed in libpng 1.6.8 [December 19, 2013] + * + * 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" + +/* This code requires -mfpu=neon on the command line: */ +#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ + +#include + +/* libpng row pointers are not necessarily aligned to any particular boundary, + * however this code will only work with appropriate alignment. arm/arm_init.c + * checks for this (and will not compile unless it is done). This code uses + * variants of png_aligncast to avoid compiler warnings. + */ +#define png_ptr(type,pointer) png_aligncast(type *,pointer) +#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) + +/* The following relies on a variable 'temp_pointer' being declared with type + * 'type'. This is written this way just to hide the GCC strict aliasing + * warning; note that the code is safe because there never is an alias between + * the input and output pointers. + */ +#define png_ldr(type,pointer)\ + (temp_pointer = png_ptr(type,pointer), *temp_pointer) + +#ifdef PNG_READ_SUPPORTED +#if PNG_ARM_NEON_OPT > 0 + +void +png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint8x16_t qrp, qpp; + + qrp = vld1q_u8(rp); + qpp = vld1q_u8(pp); + qrp = vaddq_u8(qrp, qpp); + vst1q_u8(rp, qrp); + } +} + +void +png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp = vld1q_u8(rp); + uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); + uint8x8x2_t vrp = *vrpt; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + for (; rp < rp_stop;) + { + uint8x8_t vtmp1, vtmp2; + uint32x2_t *temp_pointer; + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); + vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); + vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); + + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); + vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t, &vtmp); + vrp = *vrpt; + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } + + PNG_UNUSED(prev_row) +} + +void +png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + for (; rp < rp_stop; rp += 16) + { + uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); + uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); + uint8x8x4_t vrp = *vrpt; + uint32x2x4_t *temp_pointer; + + vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); + vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); + vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); + vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + } + + PNG_UNUSED(prev_row) +} + +void +png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_const_bytep pp = prev_row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp; + uint8x8x2_t *vrpt; + uint8x8x2_t vrp; + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + vtmp = vld1q_u8(rp); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + for (; rp < rp_stop; pp += 12) + { + uint8x8_t vtmp1, vtmp2, vtmp3; + + uint8x8x2_t *vppt; + uint8x8x2_t vpp; + + uint32x2_t *temp_pointer; + + vtmp = vld1q_u8(pp); + vppt = png_ptr(uint8x8x2_t,&vtmp); + vpp = *vppt; + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); + vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); + vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); + vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); + + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); + vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); + + vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); + + vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); + vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } +} + +void +png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint32x2x4_t vtmp; + uint8x8x4_t *vrpt, *vppt; + uint8x8x4_t vrp, vpp; + uint32x2x4_t *temp_pointer; + + vtmp = vld4_u32(png_ptr(uint32_t,rp)); + vrpt = png_ptr(uint8x8x4_t,&vtmp); + vrp = *vrpt; + vtmp = vld4_u32(png_ptrc(uint32_t,pp)); + vppt = png_ptr(uint8x8x4_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); + vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); + vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); + vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); + vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); + vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); + + vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + } +} + +static uint8x8_t +paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) +{ + uint8x8_t d, e; + uint16x8_t p1, pa, pb, pc; + + p1 = vaddl_u8(a, b); /* a + b */ + pc = vaddl_u8(c, c); /* c * 2 */ + pa = vabdl_u8(b, c); /* pa */ + pb = vabdl_u8(a, c); /* pb */ + pc = vabdq_u16(p1, pc); /* pc */ + + p1 = vcleq_u16(pa, pb); /* pa <= pb */ + pa = vcleq_u16(pa, pc); /* pa <= pc */ + pb = vcleq_u16(pb, pc); /* pb <= pc */ + + p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ + + d = vmovn_u16(pb); + e = vmovn_u16(p1); + + d = vbsl_u8(d, b, c); + e = vbsl_u8(e, a, d); + + return e; +} + +void +png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_const_bytep pp = prev_row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp; + uint8x8x2_t *vrpt; + uint8x8x2_t vrp; + uint8x8_t vlast = vdup_n_u8(0); + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + vtmp = vld1q_u8(rp); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + for (; rp < rp_stop; pp += 12) + { + uint8x8x2_t *vppt; + uint8x8x2_t vpp; + uint8x8_t vtmp1, vtmp2, vtmp3; + uint32x2_t *temp_pointer; + + vtmp = vld1q_u8(pp); + vppt = png_ptr(uint8x8x2_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); + vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); + vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); + vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); + vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); + + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); + vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); + + vlast = vtmp2; + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } +} + +void +png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + uint8x8_t vlast = vdup_n_u8(0); + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint32x2x4_t vtmp; + uint8x8x4_t *vrpt, *vppt; + uint8x8x4_t vrp, vpp; + uint32x2x4_t *temp_pointer; + + vtmp = vld4_u32(png_ptr(uint32_t,rp)); + vrpt = png_ptr(uint8x8x4_t,&vtmp); + vrp = *vrpt; + vtmp = vld4_u32(png_ptrc(uint32_t,pp)); + vppt = png_ptr(uint8x8x4_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); + vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); + vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); + vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); + vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); + + vlast = vpp.val[3]; + + vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + } +} + +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ diff --git a/ext/native/ext/libpng17/png.c b/ext/native/ext/libpng17/png.c new file mode 100644 index 0000000000..5ce74f8417 --- /dev/null +++ b/ext/native/ext/libpng17/png.c @@ -0,0 +1,4409 @@ + +/* png.c - location for general purpose libpng functions + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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_7_0beta35 Your_png_h_is_not_version_1_7_0beta35; + +/* 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_structrp 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)(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_alloc_size_t num_bytes = size; + + if (png_ptr == NULL) + return NULL; + + if (items >= (~(png_alloc_size_t)0)/size) + { + png_warning (png_voidcast(png_structrp, png_ptr), + "Potential overflow in png_zalloc()"); + return NULL; + } + + num_bytes *= items; + return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); +} + +/* Function to free memory for zlib */ +void /* PRIVATE */ +png_zfree(voidpf png_ptr, voidpf ptr) +{ + png_free(png_voidcast(png_const_structrp,png_ptr), 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_structrp 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_structrp png_ptr, png_const_bytep ptr, png_size_t length) +{ + int need_crc = 1; + + if (PNG_CHUNK_ANCILLARY(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 in zlib.h 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 safe_length = (uInt)length; + if (safe_length == 0) + safe_length = (uInt)-1; /* evil, but safe */ + + crc = crc32(crc, ptr, safe_length); + + /* 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 += safe_length; + length -= safe_length; + } + 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_structrp png_ptr, png_const_charp user_png_ver) +{ + if (user_png_ver != NULL) + { + 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 and third digits (note that when we reach version + * 1.10 we will need to check the fourth symbol, namely user_png_ver[3]). + */ + 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[3] != png_libpng_ver[3])) || + (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_UNUSED(pos) + + png_warning(png_ptr, m); +#endif + +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags = 0; +#endif + + return 0; + } + } + + /* Success return. */ + return 1; +} + +/* Generic function to create a png_struct for either read or write - this + * contains the common initialization. + */ +PNG_FUNCTION(png_structp /* PRIVATE */, +png_create_png_struct,(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_struct create_struct; +# ifdef PNG_SETJMP_SUPPORTED + jmp_buf create_jmp_buf; +# endif + + /* This temporary stack-allocated structure is used to provide a place to + * build enough context to allow the user provided memory allocator (if any) + * to be called. + */ + memset(&create_struct, 0, (sizeof create_struct)); + + /* These limits are only used on read at present, and if READ is not turned + * on neither will USER_LIMITS be. The width/height and chunk malloc limits + * are constants, so if they cannot be set they don't get defined in + * png_struct, the user_chunk_cache limits is a down-counter, when it reaches + * 1 no more chunks will be handled. 0 means unlimited, consequently the + * limit is 1 more than the number of chunks that will be handled. + */ +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + create_struct.user_width_max = PNG_USER_WIDTH_MAX; + create_struct.user_height_max = PNG_USER_HEIGHT_MAX; + create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; +# endif +# ifdef PNG_USER_LIMITS_SUPPORTED + /* Must exist even if the initial value is constant */ + create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; +# endif + + /* The following two API calls simply set fields in png_struct, so it is safe + * to do them now even though error handling is not yet set up. + */ +# ifdef PNG_USER_MEM_SUPPORTED + png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn); +# else + PNG_UNUSED(mem_ptr) + PNG_UNUSED(malloc_fn) + PNG_UNUSED(free_fn) +# endif + + /* (*error_fn) can return control to the caller after the error_ptr is set, + * this will result in a memory leak unless the error_fn does something + * extremely sophisticated. The design lacks merit but is implicit in the + * API. + */ + png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn); + +# ifdef PNG_SETJMP_SUPPORTED + if (!setjmp(create_jmp_buf)) + { + /* Temporarily fake out the longjmp information until we have + * successfully completed this function. This only works if we have + * setjmp() support compiled in, but it is safe - this stuff should + * never happen. + */ + create_struct.jmp_buf_ptr = &create_jmp_buf; + create_struct.jmp_buf_size = 0; /*stack allocation*/ + create_struct.longjmp_fn = longjmp; +# else + { +# endif + /* Call the general version checker (shared with read and write code): + */ + if (png_user_version_check(&create_struct, user_png_ver)) + { + png_structrp png_ptr = png_voidcast(png_structrp, + png_malloc_warn(&create_struct, (sizeof *png_ptr))); + + if (png_ptr != NULL) + { + /* png_ptr->zstream holds a back-pointer to the png_struct, so + * this can only be done now: + */ + create_struct.zstream.zalloc = png_zalloc; + create_struct.zstream.zfree = png_zfree; + create_struct.zstream.opaque = png_ptr; + +# ifdef PNG_SETJMP_SUPPORTED + /* Eliminate the local error handling: */ + create_struct.jmp_buf_ptr = NULL; + create_struct.jmp_buf_size = 0; + create_struct.longjmp_fn = 0; +# endif + + *png_ptr = create_struct; + + /* This is the successful return point */ + return png_ptr; + } + } + } + + /* A longjmp because of a bug in the application storage allocator or a + * simple failure to allocate the png_struct. + */ + return NULL; +} + +/* Allocate the memory for an info_struct for the application. */ +PNG_FUNCTION(png_infop,PNGAPI +png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED) +{ + png_inforp info_ptr; + + png_debug(1, "in png_create_info_struct"); + + if (png_ptr == NULL) + return NULL; + + /* Use the internal API that does not (or at least should not) error out, so + * that this call always returns ok. The application typically sets up the + * error handling *after* creating the info_struct because this is the way it + * has always been done in 'example.c'. + */ + info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, + (sizeof *info_ptr))); + + if (info_ptr != NULL) + memset(info_ptr, 0, (sizeof *info_ptr)); + + 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. From libpng 1.6.0 this function is also used + * internally to implement the png_info release part of the 'struct' destroy + * APIs. This ensures that all possible approaches free the same data (all of + * it). + */ +void PNGAPI +png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) +{ + png_inforp 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) + { + /* Do this first in case of an error below; if the app implements its own + * memory management this can lead to png_free calling png_error, which + * will abort this routine and return control to the app error handler. + * An infinite loop may result if it then tries to free the same info + * ptr. + */ + *info_ptr_ptr = NULL; + + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + memset(info_ptr, 0, (sizeof *info_ptr)); + png_free(png_ptr, info_ptr); + } +} + +void PNGAPI +png_free_data(png_const_structrp png_ptr, png_inforp 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) + { + info_ptr->valid &= ~PNG_INFO_tRNS; + png_free(png_ptr, info_ptr->trans_alpha); + info_ptr->trans_alpha = NULL; + info_ptr->num_trans = 0; + } +#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) + { + unsigned int i; + for (i = 0; i < 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 profile 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 < info_ptr->splt_palettes_num; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, (int)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_STORE_UNKNOWN_CHUNKS_SUPPORTED + 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, (int)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_free(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) + { + png_uint_32 row; + for (row = 0; row < 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; +} +#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_const_structrp 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_structrp 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_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 extension.) + */ +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 + +# 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. + */ +int PNGAPI +png_convert_to_rfc1123_buffer(char out[29], 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 (out == NULL) + return 0; + + 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) + return 0; + + { + size_t pos = 0; + char number_buf[5]; /* enough for a four-digit year */ + +# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) +# define APPEND_NUMBER(format, value)\ + APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) +# define APPEND(ch) if (pos < 28) out[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 1; +} +# endif /* PNG_TIME_RFC1123_SUPPORTED */ + +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +png_const_charp PNGAPI +png_get_copyright(png_const_structrp 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.7.0beta35 - March 22, 2014" PNG_STRING_NEWLINE \ + "Copyright (c) 1998-2014 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.7.0beta35 - March 22, 2014\ + Copyright (c) 1998-2014 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_structrp 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_structrp 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_structrp 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_BUILD_GRAYSCALE_PALETTE_SUPPORTED +/* NOTE: this routine is not used internally! */ +/* 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_SET_UNKNOWN_CHUNKS_SUPPORTED +int PNGAPI +png_handle_as_unknown(png_const_structrp 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, this is no longer + * necessary because the 'set' routine handles duplicate entries correcty. + */ + do /* num_chunk_list > 0, so at least one */ + { + p -= 5; + + if (!memcmp(chunk_name, p, 4)) + return p[4]; + } + while (p > p_end); + + /* This means that known chunks should be processed and unknown chunks should + * be handled according to the value of png_ptr->unknown_default; this can be + * confusing because, as a result, there are two levels of defaulting for + * unknown chunks. + */ + return PNG_HANDLE_CHUNK_AS_DEFAULT; +} + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) +int /* PRIVATE */ +png_chunk_unknown_handling(png_const_structrp 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 /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ +#endif /* SET_UNKNOWN_CHUNKS */ + +/* 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) +/* Ensure that png_ptr->zstream.msg holds some appropriate error message string. + * If it doesn't 'ret' is used to set it to something appropriate, even in cases + * like Z_OK or Z_STREAM_END where the error code is apparently a success code. + */ +void /* PRIVATE */ +png_zstream_error(png_structrp png_ptr, int ret) +{ + /* Translate 'ret' into an appropriate error string, priority is given to the + * one in zstream if set. This always returns a string, even in cases like + * Z_OK or Z_STREAM_END where the error code is a success code. + */ + if (png_ptr->zstream.msg == NULL) switch (ret) + { + default: + case Z_OK: + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code"); + break; + + case Z_STREAM_END: + /* Normal exit */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); + break; + + case Z_NEED_DICT: + /* This means the deflate stream did not have a dictionary; this + * indicates a bogus PNG. + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary"); + break; + + case Z_ERRNO: + /* gz APIs only: should not happen */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error"); + break; + + case Z_STREAM_ERROR: + /* internal libpng error */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib"); + break; + + case Z_DATA_ERROR: + png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream"); + break; + + case Z_MEM_ERROR: + png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory"); + break; + + case Z_BUF_ERROR: + /* End of input or output; not a problem if the caller is doing + * incremental read or write. + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated"); + break; + + case Z_VERSION_ERROR: + png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version"); + break; + + case PNG_UNEXPECTED_ZLIB_RETURN: + /* Compile errors here mean that zlib now uses the value co-opted in + * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above + * and change pngpriv.h. Note that this message is "... return", + * whereas the default/Z_OK one is "... return code". + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return"); + break; + } +} + +/* 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_GAMMA_SUPPORTED /* always set if COLORSPACE */ +static int +png_colorspace_check_gamma(png_const_structrp png_ptr, + png_colorspacerp colorspace, png_fixed_point gAMA, int from) + /* This is called to check a new gamma value against an existing one. The + * routine returns false if the new gamma value should not be written. + * + * 'from' says where the new gamma value comes from: + * + * 0: the new gamma value is the libpng estimate for an ICC profile + * 1: the new gamma value comes from a gAMA chunk + * 2: the new gamma value comes from an sRGB chunk + */ +{ + png_fixed_point gtest; + + if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && + (!png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) || + png_gamma_significant(gtest))) + { + /* Either this is an sRGB image, in which case the calculated gamma + * approximation should match, or this is an image with a profile and the + * value libpng calculates for the gamma of the profile does not match the + * value recorded in the file. The former, sRGB, case is an error, the + * latter is just a warning. + */ + if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) + { + png_chunk_report(png_ptr, "gamma value does not match sRGB", + PNG_CHUNK_ERROR); + /* Do not overwrite an sRGB value */ + return from == 2; + } + + else /* sRGB tag not involved */ + { + png_chunk_report(png_ptr, "gamma value does not match libpng estimate", + PNG_CHUNK_WARNING); + return from == 1; + } + } + + return 1; +} + +void /* PRIVATE */ +png_colorspace_set_gamma(png_const_structrp png_ptr, + png_colorspacerp colorspace, png_fixed_point gAMA) +{ + /* 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 gamma values (and will produce + * displays that are all black or all white.) + * + * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk + * handling code, which only required the value to be >0. + */ + png_const_charp errmsg; + + if (gAMA < 16 || gAMA > 625000000) + errmsg = "gamma value out of range"; + +# ifdef PNG_READ_gAMA_SUPPORTED + /* Allow the application to set the gamma value more than once */ + else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) + errmsg = "duplicate"; +# endif + + /* Do nothing if the colorspace is already invalid */ + else if (colorspace->flags & PNG_COLORSPACE_INVALID) + return; + + else + { + if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, 1/*from gAMA*/)) + { + /* Store this gamma value. */ + colorspace->gamma = gAMA; + colorspace->flags |= + (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); + } + + /* At present if the check_gamma test fails the gamma of the colorspace is + * not updated however the colorspace is not invalidated. This + * corresponds to the case where the existing gamma comes from an sRGB + * chunk or profile. An error message has already been output. + */ + return; + } + + /* Error exit - errmsg has been set. */ + colorspace->flags |= PNG_COLORSPACE_INVALID; + png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); +} + +void /* PRIVATE */ +png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) +{ + if (info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) + { + /* Everything is invalid */ + info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| + PNG_INFO_iCCP); + +# ifdef PNG_COLORSPACE_SUPPORTED + /* Clean up the iCCP profile now if it won't be used. */ + png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); +# else + PNG_UNUSED(png_ptr) +# endif + } + + else + { +# ifdef PNG_COLORSPACE_SUPPORTED + /* Leave the INFO_iCCP flag set if the pngset.c code has already set + * it; this allows a PNG to contain a profile which matches sRGB and + * yet still have that profile retrievable by the application. + */ + if (info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) + info_ptr->valid |= PNG_INFO_sRGB; + + else + info_ptr->valid &= ~PNG_INFO_sRGB; + + if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) + info_ptr->valid |= PNG_INFO_cHRM; + + else + info_ptr->valid &= ~PNG_INFO_cHRM; +# endif + + if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) + info_ptr->valid |= PNG_INFO_gAMA; + + else + info_ptr->valid &= ~PNG_INFO_gAMA; + } +} + +#ifdef PNG_READ_SUPPORTED +void /* PRIVATE */ +png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) +{ + if (info_ptr == NULL) /* reduce code size; check here not in the caller */ + return; + + info_ptr->colorspace = png_ptr->colorspace; + png_colorspace_sync_info(png_ptr, info_ptr); +} +#endif +#endif + +#ifdef PNG_COLORSPACE_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. + */ +static int +png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) +{ + png_int_32 d, dwhite, whiteX, whiteY; + + d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z; + if (!png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d)) return 1; + dwhite = d; + whiteX = XYZ->red_X; + whiteY = XYZ->red_Y; + + d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z; + if (!png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d)) return 1; + dwhite += d; + whiteX += XYZ->green_X; + whiteY += XYZ->green_Y; + + d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z; + if (!png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d)) return 1; + dwhite += d; + whiteX += XYZ->blue_X; + whiteY += XYZ->blue_Y; + + /* The reference white is simply the sum 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; +} + +static int +png_XYZ_from_xy(png_XYZ *XYZ, const 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 slightly 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->red_X, xy->redx, PNG_FP_1, red_inverse)) return 1; + if (!png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse)) return 1; + if (!png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, + red_inverse)) + return 1; + + if (!png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse)) + return 1; + if (!png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse)) + return 1; + if (!png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, + green_inverse)) + return 1; + + if (!png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1)) return 1; + if (!png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1)) return 1; + if (!png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, + PNG_FP_1)) + return 1; + + return 0; /*success*/ +} + +static int +png_XYZ_normalize(png_XYZ *XYZ) +{ + png_int_32 Y; + + if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 || + XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 || + XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0) + return 1; + + /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. + * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore + * relying on addition of two positive values producing a negative one is not + * safe. + */ + Y = XYZ->red_Y; + if (0x7fffffff - Y < XYZ->green_X) return 1; + Y += XYZ->green_Y; + if (0x7fffffff - Y < XYZ->blue_X) return 1; + Y += XYZ->blue_Y; + + if (Y != PNG_FP_1) + { + if (!png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y)) return 1; + if (!png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y)) return 1; + if (!png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y)) return 1; + + if (!png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y)) return 1; + if (!png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y)) return 1; + if (!png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y)) return 1; + + if (!png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y)) return 1; + if (!png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y)) return 1; + if (!png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y)) return 1; + } + + return 0; +} + +static int +png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) +{ + /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ + return !(PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || + PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || + PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || + PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || + PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || + PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || + PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || + PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)); +} + +/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM + * chunk chromaticities. Earlier checks used to simply look for the overflow + * condition (where the determinant of the matrix to solve for XYZ ends up zero + * because the chromaticity values are not all distinct.) Despite this it is + * theoretically possible to produce chromaticities that are apparently valid + * but that rapidly degrade to invalid, potentially crashing, sets because of + * arithmetic inaccuracies when calculations are performed on them. The new + * check is to round-trip xy -> XYZ -> xy and then check that the result is + * within a small percentage of the original. + */ +static int +png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) +{ + int result; + png_xy xy_test; + + /* As a side-effect this routine also returns the XYZ endpoints. */ + result = png_XYZ_from_xy(XYZ, xy); + if (result != 0) return result; + + result = png_xy_from_XYZ(&xy_test, XYZ); + if (result != 0) return result; + + if (png_colorspace_endpoints_match(xy, &xy_test, + 5/*actually, the math is pretty accurate*/)) + return 0; + + /* Too much slip */ + return 1; +} + +/* This is the check going the other way. The XYZ is modified to normalize it + * (another side-effect) and the xy chromaticities are returned. + */ +static int +png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) +{ + int result; + png_XYZ XYZtemp; + + result = png_XYZ_normalize(XYZ); + if (result != 0) return result; + + result = png_xy_from_XYZ(xy, XYZ); + if (result != 0) return result; + + XYZtemp = *XYZ; + return png_colorspace_check_xy(&XYZtemp, xy); +} + +/* Used to check for an endpoint match against sRGB */ +static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ +{ + /* color x y */ + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000, + /* white */ 31270, 32900 +}; + +static int +png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, + png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, + int preferred) +{ + if (colorspace->flags & PNG_COLORSPACE_INVALID) + return 0; + + /* The consistency check is performed on the chromaticities; this factors out + * variations because of the normalization (or not) of the end point Y + * values. + */ + if (preferred < 2 && (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS)) + { + /* The end points must be reasonably close to any we already have. The + * following allows an error of up to +/-.001 + */ + if (!png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, 100)) + { + colorspace->flags |= PNG_COLORSPACE_INVALID; + png_benign_error(png_ptr, "inconsistent chromaticities"); + return 0; /* failed */ + } + + /* Only overwrite with preferred values */ + if (preferred == 0) + return 1; /* ok, but no change */ + } + + colorspace->end_points_xy = *xy; + colorspace->end_points_XYZ = *XYZ; + colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; + + /* The end points are normally quoted to two decimal digits, so allow +/-0.01 + * on this test. + */ + if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000)) + colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; + + else + colorspace->flags &= PNG_COLORSPACE_CANCEL( + PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); + + return 2; /* ok and changed */ +} + +int /* PRIVATE */ +png_colorspace_set_chromaticities(png_const_structrp png_ptr, + png_colorspacerp colorspace, const png_xy *xy, int preferred) +{ + /* We must check the end points to ensure they are reasonable - in the past + * color management systems have crashed as a result of getting bogus + * colorant values, while this isn't the fault of libpng it is the + * responsibility of libpng because PNG carries the bomb and libpng is in a + * position to protect against it. + */ + png_XYZ XYZ; + + switch (png_colorspace_check_xy(&XYZ, xy)) + { + case 0: /* success */ + return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, + preferred); + + case 1: + /* We can't invert the chromaticities so we can't produce value XYZ + * values. Likely as not a color management system will fail too. + */ + colorspace->flags |= PNG_COLORSPACE_INVALID; + png_benign_error(png_ptr, "invalid chromaticities"); + 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. + */ + colorspace->flags |= PNG_COLORSPACE_INVALID; + png_error(png_ptr, "internal error checking chromaticities"); + break; + } + + return 0; /* failed */ +} + +int /* PRIVATE */ +png_colorspace_set_endpoints(png_const_structrp png_ptr, + png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) +{ + png_XYZ XYZ = *XYZ_in; + png_xy xy; + + switch (png_colorspace_check_XYZ(&xy, &XYZ)) + { + case 0: + return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, + preferred); + + case 1: + /* End points are invalid. */ + colorspace->flags |= PNG_COLORSPACE_INVALID; + png_benign_error(png_ptr, "invalid end points"); + break; + + default: + colorspace->flags |= PNG_COLORSPACE_INVALID; + png_error(png_ptr, "internal error checking chromaticities"); + break; + } + + return 0; /* failed */ +} + +#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) +/* Error message generation */ +static char +png_icc_tag_char(png_uint_32 byte) +{ + byte &= 0xff; + if (byte >= 32 && byte <= 126) + return (char)byte; + else + return '?'; +} + +static void +png_icc_tag_name(char *name, png_uint_32 tag) +{ + name[0] = '\''; + name[1] = png_icc_tag_char(tag >> 24); + name[2] = png_icc_tag_char(tag >> 16); + name[3] = png_icc_tag_char(tag >> 8); + name[4] = png_icc_tag_char(tag ); + name[5] = '\''; +} + +static int +is_ICC_signature_char(png_alloc_size_t it) +{ + return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || + (it >= 97 && it <= 122); +} + +static int is_ICC_signature(png_alloc_size_t it) +{ + return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && + is_ICC_signature_char((it >> 16) & 0xff) && + is_ICC_signature_char((it >> 8) & 0xff) && + is_ICC_signature_char(it & 0xff); +} + +static int +png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, + png_const_charp name, png_alloc_size_t value, png_const_charp reason) +{ + size_t pos; + char message[196]; /* see below for calculation */ + + if (colorspace != NULL) + colorspace->flags |= PNG_COLORSPACE_INVALID; + + pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ + pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ + pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ + if (is_ICC_signature(value)) + { + /* So 'value' is at most 4 bytes and the following cast is safe */ + png_icc_tag_name(message+pos, (png_uint_32)value); + pos += 6; /* total +8; less than the else clause */ + message[pos++] = ':'; + message[pos++] = ' '; + } +# ifdef PNG_WARNINGS_SUPPORTED + else + { + char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ + + pos = png_safecat(message, (sizeof message), pos, + png_format_number(number, number+(sizeof number), + PNG_NUMBER_FORMAT_x, value)); + pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ + } +# endif + /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ + pos = png_safecat(message, (sizeof message), pos, reason); + PNG_UNUSED(pos) + + /* This is recoverable, but make it unconditionally an app_error on write to + * avoid writing invalid ICC profiles into PNG files. (I.e. we handle them + * on read, with a warning, but on write unless the app turns off + * application errors the PNG won't be written.) + */ + png_chunk_report(png_ptr, message, + (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); + + return 0; +} +#endif /* sRGB || iCCP */ + +#ifdef PNG_sRGB_SUPPORTED +int /* PRIVATE */ +png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, + int intent) +{ + /* sRGB sets known gamma, end points and (from the chunk) intent. */ + /* IMPORTANT: these are not necessarily the values found in an ICC profile + * because ICC profiles store values adapted to a D50 environment; it is + * expected that the ICC profile mediaWhitePointTag will be D50, see the + * checks and code elsewhere to understand this better. + * + * These XYZ values, which are accurate to 5dp, produce rgb to gray + * coefficients of (6968,23435,2366), which are reduced (because they add up + * to 32769 not 32768) to (6968,23434,2366). These are the values that + * libpng has traditionally used (and are the best values given the 15bit + * algorithm used by the rgb to gray code.) + */ + static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ + { + /* color X Y Z */ + /* red */ 41239, 21264, 1933, + /* green */ 35758, 71517, 11919, + /* blue */ 18048, 7219, 95053 + }; + + /* Do nothing if the colorspace is already invalidated. */ + if (colorspace->flags & PNG_COLORSPACE_INVALID) + return 0; + + /* Check the intent, then check for existing settings. It is valid for the + * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must + * be consistent with the correct values. If, however, this function is + * called below because an iCCP chunk matches sRGB then it is quite + * conceivable that an older app recorded incorrect gAMA and cHRM because of + * an incorrect calculation based on the values in the profile - this does + * *not* invalidate the profile (though it still produces an error, which can + * be ignored.) + */ + if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) + return png_icc_profile_error(png_ptr, colorspace, "sRGB", + (unsigned)intent, "invalid sRGB rendering intent"); + + if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && + colorspace->rendering_intent != intent) + return png_icc_profile_error(png_ptr, colorspace, "sRGB", + (unsigned)intent, "inconsistent rendering intents"); + + if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) + { + png_benign_error(png_ptr, "duplicate sRGB information ignored"); + return 0; + } + + /* If the standard sRGB cHRM chunk does not match the one from the PNG file + * warn but overwrite the value with the correct one. + */ + if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && + !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, + 100)) + png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", + PNG_CHUNK_ERROR); + + /* This check is just done for the error reporting - the routine always + * returns true when the 'from' argument corresponds to sRGB (2). + */ + (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, + 2/*from sRGB*/); + + /* intent: bugs in GCC force 'int' to be used as the parameter type. */ + colorspace->rendering_intent = (png_uint_16)intent; + colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; + + /* endpoints */ + colorspace->end_points_xy = sRGB_xy; + colorspace->end_points_XYZ = sRGB_XYZ; + colorspace->flags |= + (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); + + /* gamma */ + colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; + colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; + + /* Finally record that we have an sRGB profile */ + colorspace->flags |= + (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); + + return 1; /* set */ +} +#endif /* sRGB */ + +#ifdef PNG_iCCP_SUPPORTED +/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value + * is XYZ(0.9642,1.0,0.8249), which scales to: + * + * (63189.8112, 65536, 54060.6464) + */ +static const png_byte D50_nCIEXYZ[12] = + { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; + +int /* PRIVATE */ +png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, + png_const_charp name, png_uint_32 profile_length) +{ + if (profile_length < 132) + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, + "too short"); + + if (profile_length & 3) + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, + "invalid length"); + + return 1; +} + +int /* PRIVATE */ +png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, + png_const_charp name, png_uint_32 profile_length, + png_const_bytep profile/* first 132 bytes only */, int color_type) +{ + png_uint_32 temp; + + /* Length check; this cannot be ignored in this code because profile_length + * is used later to check the tag table, so even if the profile seems over + * long profile_length from the caller must be correct. The caller can fix + * this up on read or write by just passing in the profile header length. + */ + temp = png_get_uint_32(profile); + if (temp != profile_length) + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "length does not match profile"); + + temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ + if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ + profile_length < 132+12*temp) /* truncated tag table */ + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "tag count too large"); + + /* The 'intent' must be valid or we can't store it, ICC limits the intent to + * 16 bits. + */ + temp = png_get_uint_32(profile+64); + if (temp >= 0xffff) /* The ICC limit */ + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "invalid rendering intent"); + + /* This is just a warning because the profile may be valid in future + * versions. + */ + if (temp >= PNG_sRGB_INTENT_LAST) + (void)png_icc_profile_error(png_ptr, NULL, name, temp, + "intent outside defined range"); + + /* At this point the tag table can't be checked because it hasn't necessarily + * been loaded; however, various header fields can be checked. These checks + * are for values permitted by the PNG spec in an ICC profile; the PNG spec + * restricts the profiles that can be passed in an iCCP chunk (they must be + * appropriate to processing PNG data!) + */ + + /* Data checks (could be skipped). These checks must be independent of the + * version number; however, the version number doesn't accomodate changes in + * the header fields (just the known tags and the interpretation of the + * data.) + */ + temp = png_get_uint_32(profile+36); /* signature 'ascp' */ + if (temp != 0x61637370) + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "invalid signature"); + + /* Currently the PCS illuminant/adopted white point (the computational + * white point) are required to be D50, + * however the profile contains a record of the illuminant so perhaps ICC + * expects to be able to change this in the future (despite the rationale in + * the introduction for using a fixed PCS adopted white.) Consequently the + * following is just a warning. + */ + if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) + (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, + "PCS illuminant is not D50"); + + /* The PNG spec requires this: + * "If the iCCP chunk is present, the image samples conform to the colour + * space represented by the embedded ICC profile as defined by the + * International Color Consortium [ICC]. The colour space of the ICC profile + * shall be an RGB colour space for colour images (PNG colour types 2, 3, and + * 6), or a greyscale colour space for greyscale images (PNG colour types 0 + * and 4)." + * + * This checking code ensures the embedded profile (on either read or write) + * conforms to the specification requirements. Notice that an ICC 'gray' + * color-space profile contains the information to transform the monochrome + * data to XYZ or L*a*b (according to which PCS the profile uses) and this + * should be used in preference to the standard libpng K channel replication + * into R, G and B channels. + * + * Previously it was suggested that an RGB profile on grayscale data could be + * handled. However it it is clear that using an RGB profile in this context + * must be an error - there is no specification of what it means. Thus it is + * almost certainly more correct to ignore the profile. + */ + temp = png_get_uint_32(profile+16); /* data colour space field */ + switch (temp) + { + case 0x52474220: /* 'RGB ' */ + if (!(color_type & PNG_COLOR_MASK_COLOR)) + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "RGB color space not permitted on grayscale PNG"); + break; + + case 0x47524159: /* 'GRAY' */ + if (color_type & PNG_COLOR_MASK_COLOR) + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "Gray color space not permitted on RGB PNG"); + break; + + default: + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "invalid ICC profile color space"); + } + + /* It is up to the application to check that the profile class matches the + * application requirements; the spec provides no guidance, but it's pretty + * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer + * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these + * cases. Issue an error for device link or abstract profiles - these don't + * contain the records necessary to transform the color-space to anything + * other than the target device (and not even that for an abstract profile). + * Profiles of these classes may not be embedded in images. + */ + temp = png_get_uint_32(profile+12); /* profile/device class */ + switch (temp) + { + case 0x73636E72: /* 'scnr' */ + case 0x6D6E7472: /* 'mntr' */ + case 0x70727472: /* 'prtr' */ + case 0x73706163: /* 'spac' */ + /* All supported */ + break; + + case 0x61627374: /* 'abst' */ + /* May not be embedded in an image */ + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "invalid embedded Abstract ICC profile"); + + case 0x6C696E6B: /* 'link' */ + /* DeviceLink profiles cannnot be interpreted in a non-device specific + * fashion, if an app uses the AToB0Tag in the profile the results are + * undefined unless the result is sent to the intended device, + * therefore a DeviceLink profile should not be found embedded in a + * PNG. + */ + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "unexpected DeviceLink ICC profile class"); + + case 0x6E6D636C: /* 'nmcl' */ + /* A NamedColor profile is also device specific, however it doesn't + * contain an AToB0 tag that is open to misintrepretation. Almost + * certainly it will fail the tests below. + */ + (void)png_icc_profile_error(png_ptr, NULL, name, temp, + "unexpected NamedColor ICC profile class"); + break; + + default: + /* To allow for future enhancements to the profile accept unrecognized + * profile classes with a warning, these then hit the test below on the + * tag content to ensure they are backward compatible with one of the + * understood profiles. + */ + (void)png_icc_profile_error(png_ptr, NULL, name, temp, + "unrecognized ICC profile class"); + break; + } + + /* For any profile other than a device link one the PCS must be encoded + * either in XYZ or Lab. + */ + temp = png_get_uint_32(profile+20); + switch (temp) + { + case 0x58595A20: /* 'XYZ ' */ + case 0x4C616220: /* 'Lab ' */ + break; + + default: + return png_icc_profile_error(png_ptr, colorspace, name, temp, + "unexpected ICC PCS encoding"); + } + + return 1; +} + +int /* PRIVATE */ +png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, + png_const_charp name, png_uint_32 profile_length, + png_const_bytep profile /* header plus whole tag table */) +{ + png_uint_32 tag_count = png_get_uint_32(profile+128); + png_uint_32 itag; + png_const_bytep tag = profile+132; /* The first tag */ + + /* First scan all the tags in the table and add bits to the icc_info value + * (temporarily in 'tags'). + */ + for (itag=0; itag < tag_count; ++itag, tag += 12) + { + png_uint_32 tag_id = png_get_uint_32(tag+0); + png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ + png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ + + /* The ICC specification does not exclude zero length tags, therefore the + * start might actually be anywhere if there is no data, but this would be + * a clear abuse of the intent of the standard so the start is checked for + * being in range. All defined tag types have an 8 byte header - a 4 byte + * type signature then 0. + */ + if ((tag_start & 3) != 0) + { + /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is + * only a warning here because libpng does not care about the + * alignment. + */ + (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, + "ICC profile tag start not a multiple of 4"); + } + + /* This is a hard error; potentially it can cause read outside the + * profile. + */ + if (tag_start > profile_length || tag_length > profile_length - tag_start) + return png_icc_profile_error(png_ptr, colorspace, name, tag_id, + "ICC profile tag outside profile"); + } + + return 1; /* success, maybe with warnings */ +} + +#ifdef PNG_sRGB_SUPPORTED +/* Information about the known ICC sRGB profiles */ +static const struct +{ + png_uint_32 adler, crc, length; + png_uint_32 md5[4]; + png_byte have_md5; + png_byte is_broken; + png_uint_16 intent; + +# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) +# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ + { adler, crc, length, md5, broke, intent }, + +} png_sRGB_checks[] = +{ + /* This data comes from contrib/tools/checksum-icc run on downloads of + * all four ICC sRGB profiles from www.color.org. + */ + /* adler32, crc32, MD5[4], intent, date, length, file-name */ + PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, + PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, + "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") + + /* ICC sRGB v2 perceptual no black-compensation: */ + PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, + PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, + "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") + + PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, + PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, + "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") + + /* ICC sRGB v4 perceptual */ + PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, + PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, + "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") + + /* The following profiles have no known MD5 checksum. If there is a match + * on the (empty) MD5 the other fields are used to attempt a match and + * a warning is produced. The first two of these profiles have a 'cprt' tag + * which suggests that they were also made by Hewlett Packard. + */ + PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, + "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") + + /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not + * match the D50 PCS illuminant in the header (it is in fact the D65 values, + * so the white point is recorded as the un-adapted value.) The profiles + * below only differ in one byte - the intent - and are basically the same as + * the previous profile except for the mediaWhitePointTag error and a missing + * chromaticAdaptationTag. + */ + PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, + "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") + + PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, + "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") +}; + +static int +png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, + png_const_bytep profile, uLong adler) +{ + /* The quick check is to verify just the MD5 signature and trust the + * rest of the data. Because the profile has already been verified for + * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' + * field too, so if the profile has been edited with an intent not defined + * by sRGB (but maybe defined by a later ICC specification) the read of + * the profile will fail at that point. + */ + png_uint_32 length = 0; + png_uint_32 intent = 0x10000; /* invalid */ +#if PNG_sRGB_PROFILE_CHECKS > 1 + uLong crc = 0; /* the value for 0 length data */ +#endif + unsigned int i; + + for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) + { + if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && + png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && + png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && + png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) + { + /* This may be one of the old HP profiles without an MD5, in that + * case we can only use the length and Adler32 (note that these + * are not used by default if there is an MD5!) + */ +# if PNG_sRGB_PROFILE_CHECKS == 0 + if (png_sRGB_checks[i].have_md5) + return 1+png_sRGB_checks[i].is_broken; +# endif + + /* Profile is unsigned or more checks have been configured in. */ + if (length == 0) + { + length = png_get_uint_32(profile); + intent = png_get_uint_32(profile+64); + } + + /* Length *and* intent must match */ + if (length == png_sRGB_checks[i].length && + intent == png_sRGB_checks[i].intent) + { + /* Now calculate the adler32 if not done already. */ + if (adler == 0) + { + adler = adler32(0, NULL, 0); + adler = adler32(adler, profile, length); + } + + if (adler == png_sRGB_checks[i].adler) + { + /* These basic checks suggest that the data has not been + * modified, but if the check level is more than 1 perform + * our own crc32 checksum on the data. + */ +# if PNG_sRGB_PROFILE_CHECKS > 1 + if (crc == 0) + { + crc = crc32(0, NULL, 0); + crc = crc32(crc, profile, length); + } + + /* So this check must pass for the 'return' below to happen. + */ + if (crc == png_sRGB_checks[i].crc) +# endif + { + if (png_sRGB_checks[i].is_broken) + { + /* These profiles are known to have bad data that may cause + * problems if they are used, therefore attempt to + * discourage their use, skip the 'have_md5' warning below, + * which is made irrelevant by this error. + */ + png_chunk_report(png_ptr, "known incorrect sRGB profile", + PNG_CHUNK_ERROR); + } + + /* Warn that this being done; this isn't even an error since + * the profile is perfectly valid, but it would be nice if + * people used the up-to-date ones. + */ + else if (!png_sRGB_checks[i].have_md5) + { + png_chunk_report(png_ptr, + "out-of-date sRGB profile with no signature", + PNG_CHUNK_WARNING); + } + + return 1+png_sRGB_checks[i].is_broken; + } + } + } + +# if PNG_sRGB_PROFILE_CHECKS > 0 + /* The signature matched, but the profile had been changed in some + * way. This probably indicates a data error or uninformed hacking. + * Fall through to "no match". + */ + png_chunk_report(png_ptr, + "Not recognizing known sRGB profile that has been edited", + PNG_CHUNK_WARNING); +# endif + } + } + + return 0; /* no match */ +} +#endif + +#ifdef PNG_sRGB_SUPPORTED +void /* PRIVATE */ +png_icc_set_sRGB(png_const_structrp png_ptr, + png_colorspacerp colorspace, png_const_bytep profile, uLong adler) +{ + /* Is this profile one of the known ICC sRGB profiles? If it is, just set + * the sRGB information. + */ + if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler)) + (void)png_colorspace_set_sRGB(png_ptr, colorspace, + (int)/*already checked*/png_get_uint_32(profile+64)); +} +#endif /* PNG_READ_sRGB_SUPPORTED */ + +int /* PRIVATE */ +png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, + png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, + int color_type) +{ + if (colorspace->flags & PNG_COLORSPACE_INVALID) + return 0; + + if (png_icc_check_length(png_ptr, colorspace, name, profile_length) && + png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, + color_type) && + png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, + profile)) + { +# ifdef PNG_sRGB_SUPPORTED + /* If no sRGB support, don't try storing sRGB information */ + png_icc_set_sRGB(png_ptr, colorspace, profile, 0); +# endif + return 1; + } + + /* Failure case */ + return 0; +} +#endif /* iCCP */ + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +void /* PRIVATE */ +png_colorspace_set_rgb_coefficients(png_structrp png_ptr) +{ + /* Set the rgb_to_gray coefficients from the colorspace. */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_RGB_TO_GRAY_SET) == 0 && + (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + { + /* png_set_background has not been called, get the coefficients from the Y + * values of the colorspace colorants. + */ + png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y; + png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y; + png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y; + png_fixed_point total = r+g+b; + + if (total > 0 && + r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && + g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && + b >= 0 && png_muldiv(&b, b, 32768, total) && 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"); + + else + { + 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 + +#endif /* COLORSPACE */ + +void /* PRIVATE */ +png_check_IHDR(png_const_structrp 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; + } + else if (width > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image width in IHDR"); + error = 1; + } + else + { +# 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; + } + } + + if (height == 0) + { + png_warning(png_ptr, "Image height is zero in IHDR"); + error = 1; + } + else if (height > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image height in IHDR"); + error = 1; + } + else + { +# 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; + } + } + + /* 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_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 != 0) 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_const_structrp 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_const_structrp 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 /* SCAL */ + +#if !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && (\ + defined(PNG_FLOATING_POINT_SUPPORTED) && \ + (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ + defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ + (defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) &&\ + defined(PNG_sCAL_SUPPORTED))) +png_fixed_point +png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) +{ + if (fp < 0) + { + if (fp > -21474.836485) + return (png_fixed_point)(100000*fp - .5); + } + + else + { + if (fp < 21474.836475) + return (png_fixed_point)(100000*fp + .5); + } + + /* Overflow */ + png_fixed_error(png_ptr, text); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(text) +# endif +} +#endif + +#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_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 != 0) + 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_const_structrp 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_GAMMA_SUPPORTED /* more fixed point functions for gamma */ +/* 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 */ +} + +/* 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; +} +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* A local convenience routine. */ +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED +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 */ +} +#endif + +/* 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_READ_GAMMA_SUPPORTED /* gamma table code */ +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* Fixed point gamma. + * + * The code to calculate the tables used below can be found in the shell script + * contrib/tools/intgamma.sh + * + * 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. + * + * 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 const png_uint_32 +png_8bit_l2[128] = +{ + 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 + +#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 +}; + +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 -1 for the overflow (log 0) case, - so the result is + * always at most 19 bits. + */ + if ((x &= 0xff) == 0) + return -1; + + 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 + */ +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 -1; + + 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 accuracty 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 const png_uint_32 +png_32bit_exp[16] = +{ + /* 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 +}; + +/* Adjustment table; provided to explain the numbers in the code below. */ +#if 0 +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 + +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; +} + +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); +} + +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_structrp 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); +} + +#define PNG_GAMMA_TABLE_8 0 /* 8-bit entries in png_byte */ +#define PNG_GAMMA_TABLE_8_IN_16 1 /* 8-bit entries * 257 in png_uint_16 */ +#define PNG_GAMMA_TABLE_16 2 /* 16-bit entries in png_uint_16 */ + +typedef struct +{ + png_fixed_point gamma; + png_uint_32 mult; + unsigned int add; + unsigned int shift; /* input value is (i * mult + add) >> shift */ + int output; /* One of the above values */ + int adjust; /* Divide or multiple output by 257 */ + png_voidp table; /* Lookup table */ +} gamma_table_data; + +static unsigned int +write_gamma_table_entry(const gamma_table_data *data, png_uint_32 i) + /* Calculate and write a single entry into table[i], the value of the entry + * written is returned. + */ +{ + png_uint_32 in = (i * data->mult + data->add) >> data->shift; + unsigned int out; + + /* If the output is TABLE_8 with no adjust, or the output is not with an + * adjust, use 8-bit correction. + */ + if ((data->output == PNG_GAMMA_TABLE_8) != (data->adjust != 0)) + { + out = png_gamma_8bit_correct((unsigned int)in, data->gamma); + + if (data->adjust != 0) + out *= 257U; + } + + else /* 16-bit correction */ + { + out = png_gamma_16bit_correct((unsigned int)in, data->gamma); + + if (data->adjust != 0) + out = PNG_DIV257(out); + } + + if (data->output == PNG_GAMMA_TABLE_8) + ((png_bytep)data->table)[i] = (png_byte)out; + + else + ((png_uint_16p)data->table)[i] = (png_uint_16)out; + + return out; +} + +static void +write_gamma_table(const gamma_table_data *data, png_uint_32 lo, + unsigned int loval, png_uint_32 hi, unsigned int hival) + /* Fill in gamma table entries between lo and hi, exclusive. The entries at + * table[lo] and table[hi] have already been written, the intervening entries + * are written. + */ +{ + if (hi > lo+1) /* Else nothing to fill in */ + { + if (hival == loval) + { + /* All intervening entries must be the same. */ + if (data->output == PNG_GAMMA_TABLE_8) + { + png_bytep table8 = ((png_bytep)data->table); + + while (++lo < hi) + table8[lo] = (png_byte)loval; + } + + else + { + png_uint_16p table16 = ((png_uint_16p)data->table); + + while (++lo < hi) + table16[lo] = (png_uint_16)loval; + } + } + + else + { + png_uint_32 mid = (lo+hi) >> 1; + unsigned int midval = write_gamma_table_entry(data, mid); + + /* The algorithm used is to divide the entries to be written in half + * and fill in the middle. For all practical tables with significant + * gamma this will result in a performance gain because the expensive + * gamma correction arithmetic is avoided for some entries. + */ + write_gamma_table(data, lo, loval, mid, midval); + write_gamma_table(data, mid, midval, hi, hival); + } + } +} + +static void * +png_build_gamma_table(png_structrp png_ptr, png_fixed_point gamma_val, + int output/*as above*/, int input_depth, int use_shift) + /* Build a gamma lookup table to encode input_depth bit input values. + * The table will have 2^input_depth entries plus an extra one if use_shift + * is specified. With shift the table is accessed: + * + * table[(original-value + rounding) >> shift] + * + * And an extra entry exists to accomodate overflow of original-value on + * rounding. If use_shift is not specified the table is accessed with an + * input_depth bit value and the original values must have been correctly + * scaled to this range (not using a shift!) + * + * Each table entry contains input-value^gamma_val rounded to the output + * precision. This is 8 bit precision unless output is specified as + * PNG_GAMMA_TABLE_16, in which case it is 16-bit precision. For + * PNG_GAMMA_TABLE_8_IN_16 the 8-bit value is scaled to 16-bits by + * multiplying by 257. + */ +{ + png_uint_32 size; + unsigned int hival; + gamma_table_data data; + + /* If use_shift is true or if the input or output is not 8-bit the gamma + * correction will use the 16-bit correction code. This requires a value in + * the range 0..65535. For use_shift the value is simply: + * + * input << shift + * + * For the scaling case the value is: + * + * round(input * 65535 / ((1<> shift; + * + * With 'mult' and 'add' chosen to minimize the error for all input values + * in the range 0..((1< PNG_GAMMA_TABLE_8; + + if (use_shift != 0) + { + /* The multiplier does the shift: */ + data.mult = 1U << (8-input_depth); + data.add = 0; + data.shift = 0; + if (input_depth < 8) ++size; + } + + else + { + data.mult = multadd255[input_depth-1].mult; + data.add = multadd255[input_depth-1].add; + data.shift = multadd255[input_depth-1].shift; + } + } + + else + { + /* 16-bit correction is used for cases where input or output require more + * than 8 bits. + */ + data.adjust = output == PNG_GAMMA_TABLE_8; + + if (use_shift != 0) + { + data.mult = 1U << (16-input_depth); + data.add = 0; + data.shift = 0; + if (input_depth < 16) ++size; + } + + else + { + data.mult = multadd65535[input_depth-1].mult; + data.add = multadd65535[input_depth-1].add; + data.shift = multadd65535[input_depth-1].shift; + } + } + + if (output == PNG_GAMMA_TABLE_8) + { + data.table = png_malloc(png_ptr, size * sizeof (png_byte)); + ((png_bytep)data.table)[0] = 0; + hival = ((png_bytep)data.table)[size-1] = 255; + } + + else + { + /* Output is 16 bits, although it may only have 8 bits of precision */ + data.table = png_malloc(png_ptr, size * sizeof (png_uint_16)); + ((png_uint_16p)data.table)[0] = 0; + hival = ((png_uint_16p)data.table)[size-1] = 65535; + } + + if (png_gamma_significant(gamma_val)) + write_gamma_table(&data, 0, 0, size-1, hival); + + else /* gamma_val not significant */ + { + if (output == PNG_GAMMA_TABLE_8) + { + png_uint_32 i; + png_bytep table8 = ((png_bytep)data.table); + + if (data.adjust) + for (i=1; i> + data.shift); + + else + for (i=1; i> data.shift); + } + + else + { + png_uint_32 i; + png_uint_16p table16 = ((png_uint_16p)data.table); + + if (data.adjust) + for (i=1; i> + data.shift) * 257U); + + else + for (i=1; i> + data.shift); + } + } + + return data.table; +} + +/* Used from png_read_destroy and below to release the memory used by the gamma + * tables. + */ +void /* PRIVATE */ +png_destroy_gamma_table(png_structrp png_ptr) +{ + png_free(png_ptr, png_ptr->gamma_table); + png_ptr->gamma_table = NULL; + + 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; + + png_free(png_ptr, png_ptr->gamma_16_from_1); + png_ptr->gamma_16_from_1 = NULL; + 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_tables(png_structrp 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_ptr->gamma_table = png_voidcast(png_bytep, png_build_gamma_table( + png_ptr, png_ptr->screen_gamma > 0 ? + png_reciprocal2(png_ptr->colorspace.gamma, png_ptr->screen_gamma) : + PNG_FP_1, PNG_GAMMA_TABLE_8, 8/*input depth*/, 0/*scale*/)); + +#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)) + { + /* This sets the accuracy of 8-bit composition and the 8-bit RGB to gray + * conversion - PNG_MAX_GAMMA_8 (the number of bits in the sixteen bit + * value that are considered significant.) + */ + png_ptr->gamma_to_1 = png_voidcast(png_uint_16p, png_build_gamma_table( + png_ptr, png_reciprocal(png_ptr->colorspace.gamma), + PNG_GAMMA_TABLE_16, 8/*input depth*/, 0/*scale*/)); + + png_ptr->gamma_from_1 = png_voidcast(png_bytep, png_build_gamma_table( + png_ptr, png_ptr->screen_gamma > 0 ? + png_reciprocal(png_ptr->screen_gamma) : + png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */, + PNG_GAMMA_TABLE_8, PNG_MAX_GAMMA_8/*input depth*/, 1/*shift*/)); + + png_ptr->gamma_shift = 16-PNG_MAX_GAMMA_8; + } +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } + else + { + png_byte shift, sig_bit; + int table_type; + +# ifdef PNG_16BIT_SUPPORTED + table_type = PNG_GAMMA_TABLE_16; +# else + table_type = PNG_GAMMA_TABLE_8_IN_16; +# endif + + 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; + + 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. + */ + if (shift < (16U - PNG_MAX_GAMMA_8)) + shift = (16U - PNG_MAX_GAMMA_8); + + table_type = PNG_GAMMA_TABLE_8_IN_16; + } + + png_ptr->gamma_shift = shift; + + png_ptr->gamma_16_table = png_voidcast(png_uint_16p, png_build_gamma_table( + png_ptr, png_ptr->screen_gamma > 0 ? png_reciprocal2( + png_ptr->colorspace.gamma, png_ptr->screen_gamma) : PNG_FP_1, + table_type, (16-shift)/*input depth*/, 1/*shift*/)); + +#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_ptr->gamma_16_to_1 = png_voidcast(png_uint_16p, + png_build_gamma_table(png_ptr, + png_reciprocal(png_ptr->colorspace.gamma), PNG_GAMMA_TABLE_16, + (16-shift)/*input depth*/, 1/*shift*/)); + + /* 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_ptr->gamma_16_from_1 = png_voidcast(png_uint_16p, + png_build_gamma_table(png_ptr, png_ptr->screen_gamma > 0 ? + png_reciprocal(png_ptr->screen_gamma) : + png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */, + PNG_GAMMA_TABLE_16, (16-shift)/*input depth*/, 1/*shift*/)); + } +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } +} +#endif /* READ_GAMMA */ + +/* HARDWARE OPTION SUPPORT */ +#ifdef PNG_SET_OPTION_SUPPORTED +int PNGAPI +png_set_option(png_structrp png_ptr, int option, int onoff) +{ + if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && + (option & 1) == 0) + { + int mask = 3 << option; + int setting = (2 + (onoff != 0)) << option; + int current = png_ptr->options; + + png_ptr->options = (png_byte)((current & ~mask) | setting); + + return (current & mask) >> option; + } + + return PNG_OPTION_INVALID; +} +#endif + +/* sRGB support */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +/* sRGB conversion tables; these are machine generated with the code in + * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the + * specification (see the article at http://en.wikipedia.org/wiki/SRGB) + * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. + * The sRGB to linear table is exact (to the nearest 16 bit linear fraction). + * The inverse (linear to sRGB) table has accuracies as follows: + * + * For all possible (255*65535+1) input values: + * + * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact + * + * For the input values corresponding to the 65536 16-bit values: + * + * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact + * + * In all cases the inexact readings are off by one. + */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* The convert-to-sRGB table is only currently required for read. */ +const png_uint_16 png_sRGB_table[256] = +{ + 0,20,40,60,80,99,119,139, + 159,179,199,219,241,264,288,313, + 340,367,396,427,458,491,526,562, + 599,637,677,718,761,805,851,898, + 947,997,1048,1101,1156,1212,1270,1330, + 1391,1453,1517,1583,1651,1720,1790,1863, + 1937,2013,2090,2170,2250,2333,2418,2504, + 2592,2681,2773,2866,2961,3058,3157,3258, + 3360,3464,3570,3678,3788,3900,4014,4129, + 4247,4366,4488,4611,4736,4864,4993,5124, + 5257,5392,5530,5669,5810,5953,6099,6246, + 6395,6547,6700,6856,7014,7174,7335,7500, + 7666,7834,8004,8177,8352,8528,8708,8889, + 9072,9258,9445,9635,9828,10022,10219,10417, + 10619,10822,11028,11235,11446,11658,11873,12090, + 12309,12530,12754,12980,13209,13440,13673,13909, + 14146,14387,14629,14874,15122,15371,15623,15878, + 16135,16394,16656,16920,17187,17456,17727,18001, + 18277,18556,18837,19121,19407,19696,19987,20281, + 20577,20876,21177,21481,21787,22096,22407,22721, + 23038,23357,23678,24002,24329,24658,24990,25325, + 25662,26001,26344,26688,27036,27386,27739,28094, + 28452,28813,29176,29542,29911,30282,30656,31033, + 31412,31794,32179,32567,32957,33350,33745,34143, + 34544,34948,35355,35764,36176,36591,37008,37429, + 37852,38278,38706,39138,39572,40009,40449,40891, + 41337,41785,42236,42690,43147,43606,44069,44534, + 45002,45473,45947,46423,46903,47385,47871,48359, + 48850,49344,49841,50341,50844,51349,51858,52369, + 52884,53401,53921,54445,54971,55500,56032,56567, + 57105,57646,58190,58737,59287,59840,60396,60955, + 61517,62082,62650,63221,63795,64372,64952,65535 +}; + +#endif /* simplified read only */ + +/* The base/delta tables are required for both read and write (but currently + * only the simplified versions.) + */ +const png_uint_16 png_sRGB_base[512] = +{ + 128,1782,3383,4644,5675,6564,7357,8074, + 8732,9346,9921,10463,10977,11466,11935,12384, + 12816,13233,13634,14024,14402,14769,15125,15473, + 15812,16142,16466,16781,17090,17393,17690,17981, + 18266,18546,18822,19093,19359,19621,19879,20133, + 20383,20630,20873,21113,21349,21583,21813,22041, + 22265,22487,22707,22923,23138,23350,23559,23767, + 23972,24175,24376,24575,24772,24967,25160,25352, + 25542,25730,25916,26101,26284,26465,26645,26823, + 27000,27176,27350,27523,27695,27865,28034,28201, + 28368,28533,28697,28860,29021,29182,29341,29500, + 29657,29813,29969,30123,30276,30429,30580,30730, + 30880,31028,31176,31323,31469,31614,31758,31902, + 32045,32186,32327,32468,32607,32746,32884,33021, + 33158,33294,33429,33564,33697,33831,33963,34095, + 34226,34357,34486,34616,34744,34873,35000,35127, + 35253,35379,35504,35629,35753,35876,35999,36122, + 36244,36365,36486,36606,36726,36845,36964,37083, + 37201,37318,37435,37551,37668,37783,37898,38013, + 38127,38241,38354,38467,38580,38692,38803,38915, + 39026,39136,39246,39356,39465,39574,39682,39790, + 39898,40005,40112,40219,40325,40431,40537,40642, + 40747,40851,40955,41059,41163,41266,41369,41471, + 41573,41675,41777,41878,41979,42079,42179,42279, + 42379,42478,42577,42676,42775,42873,42971,43068, + 43165,43262,43359,43456,43552,43648,43743,43839, + 43934,44028,44123,44217,44311,44405,44499,44592, + 44685,44778,44870,44962,45054,45146,45238,45329, + 45420,45511,45601,45692,45782,45872,45961,46051, + 46140,46229,46318,46406,46494,46583,46670,46758, + 46846,46933,47020,47107,47193,47280,47366,47452, + 47538,47623,47709,47794,47879,47964,48048,48133, + 48217,48301,48385,48468,48552,48635,48718,48801, + 48884,48966,49048,49131,49213,49294,49376,49458, + 49539,49620,49701,49782,49862,49943,50023,50103, + 50183,50263,50342,50422,50501,50580,50659,50738, + 50816,50895,50973,51051,51129,51207,51285,51362, + 51439,51517,51594,51671,51747,51824,51900,51977, + 52053,52129,52205,52280,52356,52432,52507,52582, + 52657,52732,52807,52881,52956,53030,53104,53178, + 53252,53326,53400,53473,53546,53620,53693,53766, + 53839,53911,53984,54056,54129,54201,54273,54345, + 54417,54489,54560,54632,54703,54774,54845,54916, + 54987,55058,55129,55199,55269,55340,55410,55480, + 55550,55620,55689,55759,55828,55898,55967,56036, + 56105,56174,56243,56311,56380,56448,56517,56585, + 56653,56721,56789,56857,56924,56992,57059,57127, + 57194,57261,57328,57395,57462,57529,57595,57662, + 57728,57795,57861,57927,57993,58059,58125,58191, + 58256,58322,58387,58453,58518,58583,58648,58713, + 58778,58843,58908,58972,59037,59101,59165,59230, + 59294,59358,59422,59486,59549,59613,59677,59740, + 59804,59867,59930,59993,60056,60119,60182,60245, + 60308,60370,60433,60495,60558,60620,60682,60744, + 60806,60868,60930,60992,61054,61115,61177,61238, + 61300,61361,61422,61483,61544,61605,61666,61727, + 61788,61848,61909,61969,62030,62090,62150,62211, + 62271,62331,62391,62450,62510,62570,62630,62689, + 62749,62808,62867,62927,62986,63045,63104,63163, + 63222,63281,63340,63398,63457,63515,63574,63632, + 63691,63749,63807,63865,63923,63981,64039,64097, + 64155,64212,64270,64328,64385,64443,64500,64557, + 64614,64672,64729,64786,64843,64900,64956,65013, + 65070,65126,65183,65239,65296,65352,65409,65465 +}; + +const png_byte png_sRGB_delta[512] = +{ + 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, + 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, + 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, + 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, + 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, + 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, + 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, + 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,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,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; +#endif /* SIMPLIFIED READ/WRITE sRGB support */ + +/* SIMPLIFIED READ/WRITE SUPPORT */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +static int +png_image_free_function(png_voidp argument) +{ + png_imagep image = png_voidcast(png_imagep, argument); + png_controlp cp = image->opaque; + png_control c; + + /* Double check that we have a png_ptr - it should be impossible to get here + * without one. + */ + if (cp->png_ptr == NULL) + return 0; + + /* First free any data held in the control structure. */ +# ifdef PNG_STDIO_SUPPORTED + if (cp->owned_file) + { + FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr); + cp->owned_file = 0; + + /* Ignore errors here. */ + if (fp != NULL) + { + cp->png_ptr->io_ptr = NULL; + (void)fclose(fp); + } + } +# endif + + /* Copy the control structure so that the original, allocated, version can be + * safely freed. Notice that a png_error here stops the remainder of the + * cleanup, but this is probably fine because that would indicate bad memory + * problems anyway. + */ + c = *cp; + image->opaque = &c; + png_free(c.png_ptr, cp); + + /* Then the structures, calling the correct API. */ + if (c.for_write) + { +# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED + png_destroy_write_struct(&c.png_ptr, &c.info_ptr); +# else + png_error(c.png_ptr, "simplified write not supported"); +# endif + } + else + { +# ifdef PNG_SIMPLIFIED_READ_SUPPORTED + png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); +# else + png_error(c.png_ptr, "simplified read not supported"); +# endif + } + + /* Success. */ + return 1; +} + +void PNGAPI +png_image_free(png_imagep image) +{ + /* Safely call the real function, but only if doing so is safe at this point + * (if not inside an error handling context). Otherwise assume + * png_safe_execute will call this API after the return. + */ + if (image != NULL && image->opaque != NULL && + image->opaque->error_buf == NULL) + { + /* Ignore errors here: */ + (void)png_safe_execute(image, png_image_free_function, image); + image->opaque = NULL; + } +} + +int /* PRIVATE */ +png_image_error(png_imagep image, png_const_charp error_message) +{ + /* Utility to log an error. */ + png_safecat(image->message, (sizeof image->message), 0, error_message); + image->warning_or_error |= PNG_IMAGE_ERROR; + png_image_free(image); + return 0; +} + +#endif /* SIMPLIFIED READ/WRITE */ +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff --git a/ext/native/ext/libpng17/png.h b/ext/native/ext/libpng17/png.h new file mode 100644 index 0000000000..775fe83a62 --- /dev/null +++ b/ext/native/ext/libpng17/png.h @@ -0,0 +1,3351 @@ + +/* png.h - header file for PNG reference library + * + * libpng version 1.7.0beta35 - March 17, 2014 + * Copyright (c) 1998-2013 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.7.0beta35 - March 17, 2014: 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.6.0beta01-37 16 10600 16.so.16.0[.0] + * 1.7.0alpha01-10 17 10700 17.so.17.0[.0] + * 1.7.0beta01-35 17 10700 17.so.17.0[.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 "rcNN". + * + * 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, ; 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. Please keep the list sorted. + * + * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk + * type. In fact the specification does not express chunk types this way, + * however using a 32-bit value means that the chunk type can be read from the + * stream using exactly the same code as used for a 32-bit unsigned value and + * can be examined far more efficiently (using one arithmetic compare). + * + * Prior to 1.5.6 the chunk type constants were expressed as C strings. The + * libpng API still uses strings for 'unknown' chunks and a macro, + * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice + * that for portable code numeric values must still be used; the string "IHDR" + * is not portable and neither is PNG_U32('I', 'H', 'D', 'R'). + * + * In 1.7.0 the definitions were made public in png.h to avoid having to + * duplicate the same definitions in application code. + * + * SOURCE: http://www.libpng.org/pub/png/spec/register/ + * "Register of PNG Public Chunks and Keywords, version 1.4.6" + * "Extensions to the PNG Specification, version 1.4.0" + */ +#define png_IDAT PNG_U32( 73, 68, 65, 84) +#define png_IEND PNG_U32( 73, 69, 78, 68) +#define png_IHDR PNG_U32( 73, 72, 68, 82) +#define png_PLTE PNG_U32( 80, 76, 84, 69) +#define png_bKGD PNG_U32( 98, 75, 71, 68) +#define png_cHRM PNG_U32( 99, 72, 82, 77) +#define png_dSIG PNG_U32(100, 83, 73, 71) /* separate spec */ +#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ +#define png_gAMA PNG_U32(103, 65, 77, 65) +#define png_gIFg PNG_U32(103, 73, 70, 103) +#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */ +#define png_gIFx PNG_U32(103, 73, 70, 120) +#define png_hIST PNG_U32(104, 73, 83, 84) +#define png_iCCP PNG_U32(105, 67, 67, 80) +#define png_iTXt PNG_U32(105, 84, 88, 116) +#define png_oFFs PNG_U32(111, 70, 70, 115) +#define png_pCAL PNG_U32(112, 67, 65, 76) +#define png_pHYs PNG_U32(112, 72, 89, 115) +#define png_sBIT PNG_U32(115, 66, 73, 84) +#define png_sCAL PNG_U32(115, 67, 65, 76) +#define png_sPLT PNG_U32(115, 80, 76, 84) +#define png_sRGB PNG_U32(115, 82, 71, 66) +#define png_sTER PNG_U32(115, 84, 69, 82) +#define png_tEXt PNG_U32(116, 69, 88, 116) +#define png_tIME PNG_U32(116, 73, 77, 69) +#define png_tRNS PNG_U32(116, 82, 78, 83) +#define png_zTXt PNG_U32(122, 84, 88, 116) + +/* The following will work on (signed char*) strings, whereas the PNG_U32 macro + * used directory would fail on top-bit-set values because of the sign + * extension. + */ +#define PNG_CHUNK_FROM_STRING(s)\ + PNG_U32(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_ANCILLARY(c) (1 & ((c) >> 29)) +#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(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)) + +/* Section 2: 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. + */ + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Section 3: 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_7_0beta35; + +/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. + * + * png_struct is the cache of information used while reading or writing a single + * PNG file. One of these is always required, although the simplified API + * (below) hides the creation and destruction of it. + */ +typedef struct png_struct_def png_struct; +typedef const png_struct * png_const_structp; +typedef png_struct * png_structp; +typedef png_struct * * png_structpp; + +/* png_info contains information read from or to be written to a PNG file. One + * or more of these must exist while reading or creating a PNG file. The + * information is not used by libpng during read but is used to control what + * gets written when a PNG file is created. "png_get_" function calls read + * information during read and "png_set_" functions calls write information + * when creating a PNG. + * 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 * png_infop; +typedef const png_info * png_const_infop; +typedef png_info * * png_infopp; + +/* Types with names ending 'p' are pointer types. The corresponding types with + * names ending 'rp' are identical pointer types except that the pointer is + * marked 'restrict', which means that it is the only pointer to the object + * passed to the function. Applications should not use the 'restrict' types; + * it is always valid to pass 'p' to a pointer with a function argument of the + * corresponding 'rp' type. Different compilers have different rules with + * regard to type matching in the presence of 'restrict'. For backward + * compatibility libpng callbacks never have 'restrict' in their parameters and, + * consequentially, writing portable application code is extremely difficult if + * an attempt is made to use 'restrict'. + */ +typedef png_struct * PNG_RESTRICT png_structrp; +typedef const png_struct * PNG_RESTRICT png_const_structrp; +typedef png_info * PNG_RESTRICT png_inforp; +typedef const png_info * PNG_RESTRICT png_const_inforp; + +/* 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 * png_colorp; +typedef const png_color * png_const_colorp; +typedef png_color * * 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 * png_color_16p; +typedef const png_color_16 * png_const_color_16p; +typedef png_color_16 * * 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 * png_color_8p; +typedef const png_color_8 * png_const_color_8p; +typedef png_color_8 * * 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 * png_sPLT_entryp; +typedef const png_sPLT_entry * png_const_sPLT_entryp; +typedef png_sPLT_entry * * 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 * png_sPLT_tp; +typedef const png_sPLT_t * png_const_sPLT_tp; +typedef png_sPLT_t * * 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 */ + size_t text_length; /* length of the text string */ + 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 * png_textp; +typedef const png_text * png_const_textp; +typedef png_text * * 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 * png_timep; +typedef const png_time * png_const_timep; +typedef png_time * * png_timepp; + +#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ + defined(PNG_USER_CHUNKS_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. + * + * The data in the structure is set by libpng on read and used on write. + */ +typedef struct png_unknown_chunk_t +{ + png_byte name[5]; /* Textual chunk name with '\0' terminator */ + png_byte *data; /* Data, should not be modified on read! */ + size_t size; + + /* On write 'location' must be set using the flag values listed below. + * Notice that on read it is set by libpng however the values stored have + * more bits set than are listed below. Always treat the value as a + * bitmask. On write set only one bit - setting multiple bits may cause the + * chunk to be written in multiple places. + */ + png_byte location; /* mode of operation at read time */ +} +png_unknown_chunk; + +typedef png_unknown_chunk * png_unknown_chunkp; +typedef const png_unknown_chunk * png_const_unknown_chunkp; +typedef png_unknown_chunk * * png_unknown_chunkpp; +#endif + +/* Flag values for the unknown chunk location byte. */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_AFTER_IDAT 0x08 + +/* 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 ((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 */ + 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 * png_row_infop; +typedef png_row_info * * png_row_infopp; + +/* 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, 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 +/* not used anywhere */ +/* 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)); + +/* Section 4: 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_structrp 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, size_t start, + 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, size_t, png_get_compression_buffer_size, + (png_const_structrp png_ptr)); + +PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, + 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_structrp 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_const_structrp png_ptr, int val), + PNG_NORETURN); + +#ifdef PNG_READ_SUPPORTED +/* Reset the compression stream -- Removed from libpng-1.7.0 */ +PNG_REMOVED(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED) +#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_structrp png_ptr)); + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep + chunk_name, png_const_bytep data, size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp 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_structrp png_ptr, + png_const_bytep data, size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); + +/* Allocate and initialize the info structure */ +PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), + PNG_ALLOCATED); + +/* Removed from libpng-1.7.0 */ +PNG_REMOVED(19, void, png_info_init_3, (png_infopp info_ptr, + size_t png_info_struct_size), PNG_DEPRECATED) + +/* Writes all the PNG information before the image. */ +PNG_EXPORT(20, void, png_write_info_before_PLTE, + (png_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(21, void, png_write_info, + (png_structrp png_ptr, png_const_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. */ +PNG_EXPORT(22, void, png_read_info, + (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED + /* Convert to a US string format: there is no localization support in this + * routine. The original implementation used a 29 character buffer in + * png_struct, this has been removed (in libpng 1.7.0). + */ +PNG_REMOVED(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, + png_const_timep ptime),PNG_DEPRECATED) +PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], + 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, + const struct tm * 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_structrp png_ptr)); +PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); +PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); +PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp 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_structrp 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_structrp 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_structrp 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_structrp png_ptr, + int error_action, double red, double green)) +PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp 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_structrp + 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 to the calling application when an alpha channel, + * or a 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, and the color channels are unassociated + * (not premultiplied). 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. + * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes + * (the latter being the two common names for associated alpha color channels). + * + * For the 'OPTIMIZED' 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_structrp png_ptr, int mode, + double output_gamma)) +PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, + int mode, png_fixed_point output_gamma)) +#endif + +#if defined(PNG_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. + */ +#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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp png_ptr, + double screen_gamma, double override_file_gamma)) +PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp 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_structrp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); +#endif + +/* Optional update palette with requested transformations */ +PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); + +/* Optional call to update the users info structure */ +PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, + png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. */ +PNG_EXPORT(55, void, png_read_rows, (png_structrp 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_structrp 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_structrp png_ptr, png_bytepp image)); +#endif + +/* Write a row of image data */ +PNG_EXPORT(58, void, png_write_row, (png_structrp 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_structrp png_ptr, png_bytepp row, + png_uint_32 num_rows)); + +/* Write the image data */ +PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); + +/* Write the end of the PNG file. */ +PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, + png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. */ +PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +/* Free any memory associated with the png_info_struct */ +PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp 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_structrp 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_structrp png_ptr, int method, + int filters)); + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines match the values in the PNG specification. + */ +#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 + +/* The above values are valid arguments to png_set_filter() if only a single + * filter is to be used. If multiple filters are to be allowed (the default is + * to allow any of them) then a combination of the following masks must be used + * and the low three bits of the argument to png_set_filter must be 0. + * + * The resultant argument fits in a single byte. + */ +#define PNG_FILTER_NONE (0x08 << PNG_FILTER_VALUE_NONE) +#define PNG_FILTER_SUB (0x08 << PNG_FILTER_VALUE_SUB) +#define PNG_FILTER_UP (0x08 << PNG_FILTER_VALUE_UP) +#define PNG_FILTER_AVG (0x08 << PNG_FILTER_VALUE_AVG) +#define PNG_FILTER_PAETH (0x08 << PNG_FILTER_VALUE_PAETH) + +/* Then two convenience values. PNG_NO_FILTERS is the same as + * PNG_FILTER_VALUE_NONE, but this is harmless because they mean the same thing. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +#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_structrp 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_structrp 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_structrp png_ptr, + int level)); + +PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp 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_structrp png_ptr, + int window_bits)); + +PNG_EXPORT(73, void, png_set_compression_method, (png_structrp 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_structrp png_ptr, + int level)); + +PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp 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_structrp png_ptr, int window_bits)); + +PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_const_structrp png_ptr)); + +PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, + png_read_status_ptr read_row_fn)); + +PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp 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_structrp 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_structrp png_ptr)); +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp 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_structrp 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_structrp 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_structrp 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_structrp)); +PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +/* This callback is called only for *unknown* chunks. If + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known + * chunks to be treated as unknown, however in this case the callback must do + * any processing required by the chunk (e.g. by calling the appropriate + * png_set_ APIs.) + * + * There is no write support - on write, by default, all the chunks in the + * 'unknown' list are written in the specified position. + * + * The integer return from the callback function is interpreted thus: + * + * negative: An error occured, png_chunk_error will be called. + * zero: The chunk was not handled, the default unknown handling is used + * (even if this was a chunk that would otherwise be known.) + * NOTE: prior to libpng 1.7 handling values of + * PNG_HANDLE_CHUNK_AS_DEFAULT and PNG_HANDLE_CHUNK_NEVER were + * converted to PNG_HANDLE_CHUNK_IF_SAFE (libpng 1.6.0 warns if this + * happens) so it was not possible to discard unknown chunk data if a + * user callback was installed. + * positive: The chunk was handled, libpng will ignore/discard it. + */ +PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp 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_structrp 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_structrp png_ptr)); + +/* Function to be called when data becomes available */ +PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, + png_inforp info_ptr, png_bytep buffer, 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, size_t, png_process_data_pause, (png_structrp, 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_structrp)); + +#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_const_structrp 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_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); +/* Added at libpng version 1.4.0 */ +PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp 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_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Frees a pointer allocated by png_malloc() */ +PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); + +/* Free data that was allocated internally */ +PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 free_me, int num)); + +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application; this works on the png_info structure passed + * in, it does not change the state for other png_info structures. + * + * It is unlikely that this function works correctly as of 1.6.0 and using it + * may result either in memory leaks or double free of allocated data. It was + * removed in libpng 1.7.0. + */ +PNG_REMOVED(99, void, png_data_freer, (png_const_structrp png_ptr, + png_inforp info_ptr, int freer, png_uint_32 mask), PNG_DEPRECATED) + +/* Flags for png_free_data */ +#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 +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_FREE_UNKN 0x0200 +#endif +/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */ +#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 + /* These were deprecated in libpng 1.6.0 and have been removed from libpng + * 1.7.0; the functionality should be accessed by calling malloc or free + * directly or, if png_error handling is required, calling png_malloc. + */ +PNG_REMOVED(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED) +PNG_REMOVED(101, void, png_free_default, (png_const_structrp png_ptr, + png_voidp ptr), PNG_DEPRECATED) +#endif + +#ifdef PNG_ERROR_TEXT_SUPPORTED +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(102, void, png_error, (png_const_structrp 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_const_structrp 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_const_structrp png_ptr), PNG_NORETURN); +# define png_error(s1,s2) png_err(s1) +# define png_chunk_error(s1,s2) png_err(s1) +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +PNG_EXPORT(105, void, png_warning, (png_const_structrp 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_const_structrp png_ptr, + png_const_charp warning_message)); +#else +# define png_warning(s1,s2) ((void)(s1)) +# define png_chunk_warning(s1,s2) ((void)(s1)) +#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. */ +PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); + +#ifdef PNG_READ_SUPPORTED +/* Same, chunk name is prepended to message (only during read) */ +PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); +#endif + +PNG_EXPORT(109, void, png_set_benign_errors, + (png_structrp 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_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +PNG_EXPORT(111, size_t, png_get_rowbytes, (png_const_structrp png_ptr, + png_const_inforp 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_structrp png_ptr, + png_const_inforp 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_const_structrp png_ptr, + png_inforp info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image height in pixels. */ +PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image bit_depth. */ +PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image color_type. */ +PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image filter_type. */ +PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image interlace_type. */ +PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image compression_type. */ +PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, + png_const_inforp 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_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, + (png_const_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +#ifdef PNG_READ_SUPPORTED +/* Returns pointer to signature string read from PNG header */ +PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, + png_inforp info_ptr, png_color_16p *background)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_color_16p background)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, + png_const_inforp 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_const_structrp png_ptr, + png_const_inforp 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(134, png_uint_32, png_get_cHRM_fixed, + (png_const_structrp png_ptr, png_const_inforp 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(231, png_uint_32, png_get_cHRM_XYZ_fixed, + (png_const_structrp png_ptr, png_const_inforp 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_const_structrp png_ptr, + png_inforp 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_const_structrp png_ptr, + png_inforp 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_const_structrp png_ptr, + png_inforp 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_const_structrp png_ptr, + png_inforp 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_structrp png_ptr, + png_const_inforp info_ptr, double *file_gamma)) +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_file_gamma)) +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, + png_inforp info_ptr, double file_gamma)) +PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_file_gamma)) +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_16p *hist)); +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_uint_16p hist)); +#endif + +PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, + png_const_inforp 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_const_structrp png_ptr, + png_inforp 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_structrp png_ptr, + png_const_inforp 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_const_structrp png_ptr, + png_inforp 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_structrp png_ptr, + png_inforp 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_const_structrp png_ptr, + png_inforp 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_structrp png_ptr, + png_const_inforp 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_const_structrp png_ptr, + png_inforp 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_structrp png_ptr, + png_inforp info_ptr, png_colorp *palette, int *num_palette)); + +PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, + png_inforp info_ptr, png_const_colorp palette, int num_palette)); + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_color_8p *sig_bit)); +#endif + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_color_8p sig_bit)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *file_srgb_intent)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, + png_inforp info_ptr, int srgb_intent)); +PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, + png_inforp info_ptr, int srgb_intent)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, + png_inforp 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_const_structrp png_ptr, + png_inforp 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, int, png_get_sPLT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_sPLT_tpp entries)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(161, void, png_set_sPLT, (png_structrp png_ptr, + png_inforp 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, int, png_get_text, (png_const_structrp png_ptr, + png_inforp 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_structrp png_ptr, + png_inforp 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_structrp png_ptr, + png_inforp info_ptr, png_timep *mod_time)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_timep mod_time)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, + png_inforp 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_structrp png_ptr, + png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); +#endif + +#ifdef PNG_sCAL_SUPPORTED +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* NOTE: these API are currently implemented using floating point arithmetic, + * consequently they 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_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *unit, double *width, double *height)) +PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, + (png_const_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp info_ptr, int *unit, + png_charpp swidth, png_charpp sheight)); + +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* This also requires internal floating point arithmetic support - i.e. it + * requires a full math library, not just floating point handling. + */ +PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, double width, double height)) +#endif +PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, png_fixed_point width, + png_fixed_point height)) +PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, + png_const_charp swidth, png_const_charp sheight)); +#endif /* PNG_sCAL_SUPPORTED */ + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +/* Provide the default handling for all unknown chunks or, optionally, for + * specific unknown chunks. + * + * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was + * ignored and the default was used, the per-chunk setting only had an effect on + * write. If you wish to have chunk-specific handling on read in code that must + * work on earlier versions you must use a user chunk callback to implement the + * desired handling (keep or discard.) + * + * NOTE: prior to 1.7.0 when a user callback returned '0', indicating that the + * chunk had not been handled, libpng would preserve it regardless of the + * default or per-chunk settings. For compatibility with earlier versions + * simply return '1' (handled) from the callback to discard the chunk. + * + * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The + * parameter is interpreted as follows: + * + * READ: + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Known chunks: do normal libpng processing, do not keep the chunk (but + * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + * Unknown chunks: for a specific chunk use the global default, when used + * as the default discard the chunk data. + * PNG_HANDLE_CHUNK_NEVER: + * Discard the chunk data. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Keep the chunk data if the chunk is not critical else raise a chunk + * error. + * PNG_HANDLE_CHUNK_ALWAYS: + * Keep the chunk data. + * + * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, + * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent + * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks + * it simply resets the behavior to the libpng default. + * + * The per-chunk handling is always used when there is a png_user_chunk_ptr + * callback and the callback returns 0; the chunk is then always stored *unless* + * it is critical and the per-chunk setting is other than ALWAYS. Notice that + * the global default is *not* used in this case. (In effect the per-chunk + * value is incremented to at least IF_SAFE.) + * + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: + * If this is *not* set known chunks will always be handled by libpng and + * will never be stored in the unknown chunk list. Known chunks listed to + * png_set_keep_unknown_chunks will have no effect. If it is set then known + * chunks listed with a keep other than AS_DEFAULT will *never* be processed + * by libpng, in addition critical chunks must either be processed by the + * callback or saved. + * + * 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! + * + * WRITE: + * When writing chunks the options only apply to the chunks specified by + * png_set_unknown_chunks (below), libpng will *always* write known chunks + * required by png_set_ calls and will always write the core critical chunks + * (as required for PLTE). + * + * Each chunk in the png_set_unknown_chunks list is looked up in the + * png_set_keep_unknown_chunks list to find the keep setting, this is then + * interpreted as follows: + * + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Write safe-to-copy chunks and write other chunks if the global + * default is set to _ALWAYS, otherwise don't write this chunk. + * PNG_HANDLE_CHUNK_NEVER: + * Do not write the chunk. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Write the chunk if it is safe-to-copy, otherwise do not write it. + * PNG_HANDLE_CHUNK_ALWAYS: + * Write the chunk. + * + * Note that the default behavior is effectively the opposite of the read case - + * in read unknown chunks are not stored by default, in write they are written + * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different + * - on write the safe-to-copy bit is checked, on read the critical bit is + * checked and on read if the chunk is critical an error will be raised. + * + * num_chunks: + * =========== + * If num_chunks is positive, then the "keep" parameter specifies the manner + * for handling only those chunks appearing in the chunk_list array, + * otherwise the chunk list array is ignored. + * + * If num_chunks is 0 the "keep" parameter specifies the default behavior for + * unknown chunks, as described above. + * + * If num_chunks is negative, then the "keep" parameter specifies the manner + * for handling all unknown chunks plus all chunks recognized by libpng + * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to + * be processed by libpng. + */ +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, + int keep, png_const_bytep chunk_list, int num_chunks)); + +/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk 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_const_structrp png_ptr, + png_const_bytep chunk_name)); +#endif + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structrp png_ptr, + png_inforp info_ptr, png_const_unknown_chunkp unknowns, + int num_unknowns)); + /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added + * unknowns to the location currently stored in the png_struct. This is + * invariably the wrong value on write. To fix this call the following API + * for each chunk in the list with the correct location. If you know your + * code won't be compiled on earlier versions you can rely on + * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing + * the correct thing. + */ + +PNG_EXPORT(175, void, png_set_unknown_chunk_location, + (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); + +PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, + png_inforp 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_const_structrp png_ptr, + png_inforp info_ptr, int mask)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* The "params" pointer is currently not used and is for future expansion. */ +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif +#ifdef PNG_WRITE_SUPPORTED +PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif +#endif + +PNG_EXPORT(180, png_const_charp, png_get_copyright, + (png_const_structrp png_ptr)); +PNG_EXPORT(181, png_const_charp, png_get_header_ver, + (png_const_structrp png_ptr)); +PNG_EXPORT(182, png_const_charp, png_get_header_version, + (png_const_structrp png_ptr)); +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, + (png_const_structrp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp 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 +#define PNG_HANDLE_CHUNK_LAST 4 + +/* 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_structrp 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_structrp 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_structrp png_ptr)); +PNG_EXPORT(188, png_uint_32, png_get_user_height_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.0 */ +PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, + png_uint_32 user_chunk_cache_max)); +PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.1 */ +PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, + png_alloc_size_t user_chunk_cache_max)); +PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, + (png_const_structrp png_ptr)); +#endif + +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_FP_EXPORT(196, float, png_get_x_offset_inches, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, + png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +# ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, + png_const_inforp 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_const_structrp png_ptr)); + +/* Removed from libpng 1.6; use png_get_io_chunk_type. */ +PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), + PNG_DEPRECATED) + +PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, + (png_const_structrp 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(y_in, pass) \ + (((y_in)<>(((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_const_structrp 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. + */ +# define PNG_B(ptr, offset) (((png_const_bytep)(ptr))[offset]) +# define PNG_get_uint_32(buf) \ + PNG_U32(PNG_B(buf,0), PNG_B(buf,1), PNG_B(buf,2), PNG_B(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_U16(PNG_B(buf,0), PNG_B(buf,1)) + +# define PNG_get_int_32(buf) \ + PNG_S32(PNG_B(buf,0), PNG_B(buf,1), PNG_B(buf,2), PNG_B(buf,3)) + + /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, + * but defining a macro name prefixed with PNG_PREFIX. + */ +# ifndef PNG_PREFIX +# define png_get_uint_32(buf) PNG_get_uint_32(buf) +# define png_get_uint_16(buf) PNG_get_uint_16(buf) +# define png_get_int_32(buf) PNG_get_int_32(buf) +# endif +#else +# ifdef PNG_PREFIX + /* No macros; revert to the (redefined) function */ +# define PNG_get_uint_32 (png_get_uint_32) +# define PNG_get_uint_16 (png_get_uint_16) +# define PNG_get_int_32 (png_get_int_32) +# endif +#endif + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +PNG_EXPORT(242, void, png_set_check_for_invalid_index, + (png_structrp png_ptr, int allowed)); +# ifdef PNG_GET_PALETTE_MAX_SUPPORTED +PNG_EXPORT(243, int, png_get_palette_max, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); +# endif +#endif /* CHECK_FOR_INVALID_INDEX */ + +/******************************************************************************* + * IMPLEMENTATION OPTIONS + ******************************************************************************* + * + * Support for arbitrary implementation-specific optimizations. The API allows + * particular options to be turned on or off. 'Option' is the number of the + * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given + * by the PNG_OPTION_ defines below. + * + * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions, + * are detected at run time, however sometimes it may be impossible + * to do this in user mode, in which case it is necessary to discover + * the capabilities in an OS specific way. Such capabilities are + * listed here when libpng has support for them and must be turned + * ON by the application if present. + * + * SOFTWARE: sometimes software optimizations actually result in performance + * decrease on some architectures or systems, or with some sets of + * PNG images. 'Software' options allow such optimizations to be + * selected at run time. + */ +#ifdef PNG_SET_OPTION_SUPPORTED +#ifdef PNG_ARM_NEON_API_SUPPORTED +# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ +#endif +#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ +#define PNG_OPTION_NEXT 4 /* Next option - numbers must be even */ + +/* Return values: NOTE: there are four values and 'off' is *not* zero */ +#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ +#define PNG_OPTION_INVALID 1 /* Option number out of range */ +#define PNG_OPTION_OFF 2 +#define PNG_OPTION_ON 3 + +PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, + int onoff)); +#endif + +/******************************************************************************* + * END OF HARDWARE OPTIONS + ******************************************************************************/ + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project + * defs + */ + +/******************************************************************************* + * Section 5: SIMPLIFIED API + ******************************************************************************* + * + * Please read the documentation in libpng-manual.txt (TODO: write said + * documentation) if you don't understand what follows. + * + * The simplified API hides the details of both libpng and the PNG file format + * itself. It allows PNG files to be read into a very limited number of + * in-memory bitmap formats or to be written from the same formats. If these + * formats do not accomodate your needs then you can, and should, use the more + * sophisticated APIs above - these support a wide variety of in-memory formats + * and a wide variety of sophisticated transformations to those formats as well + * as a wide variety of APIs to manipulate ancillary information. + * + * To read a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure (see below) on the stack and set the + * version field to PNG_IMAGE_VERSION. + * 2) Call the appropriate png_image_begin_read... function. + * 3) Set the png_image 'format' member to the required sample format. + * 4) Allocate a buffer for the image and, if required, the color-map. + * 5) Call png_image_finish_read to read the image and, if required, the + * color-map into your buffers. + * + * There are no restrictions on the format of the PNG input itself; all valid + * color types, bit depths, and interlace methods are acceptable, and the + * input image is transformed as necessary to the requested in-memory format + * during the png_image_finish_read() step. The only caveat is that if you + * request a color-mapped image from a PNG that is full-color or makes + * complex use of an alpha channel the transformation is extremely lossy and the + * result may look terrible. + * + * To write a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. + * 2) Initialize the members of the structure that describe the image, setting + * the 'format' member to the format of the image samples. + * 3) Call the appropriate png_image_write... function with a pointer to the + * image and, if necessary, the color-map to write the PNG data. + * + * png_image is a structure that describes the in-memory format of an image + * when it is being read or defines the in-memory format of an image that you + * need to write: + */ +#define PNG_IMAGE_VERSION 1 + +typedef struct png_control *png_controlp; +typedef struct +{ + png_controlp opaque; /* Initialize to NULL, free with png_image_free */ + png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ + png_uint_32 width; /* Image width in pixels (columns) */ + png_uint_32 height; /* Image height in pixels (rows) */ + png_uint_32 format; /* Image format as defined below */ + png_uint_32 flags; /* A bit mask containing informational flags */ + png_uint_32 colormap_entries; + /* Number of entries in the color-map */ + + /* In the event of an error or warning the following field will be set to a + * non-zero value and the 'message' field will contain a '\0' terminated + * string with the libpng error or warning message. If both warnings and + * an error were encountered, only the error is recorded. If there + * are multiple warnings, only the first one is recorded. + * + * The upper 30 bits of this value are reserved, the low two bits contain + * a value as follows: + */ +# define PNG_IMAGE_WARNING 1 +# define PNG_IMAGE_ERROR 2 + /* + * The result is a two bit code such that a value more than 1 indicates + * a failure in the API just called: + * + * 0 - no warning or error + * 1 - warning + * 2 - error + * 3 - error preceded by warning + */ +# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) + + png_uint_32 warning_or_error; + + char message[64]; +} png_image, *png_imagep; + +/* The samples of the image have one to four channels whose components have + * original values in the range 0 to 1.0: + * + * 1: A single gray or luminance channel (G). + * 2: A gray/luminance channel and an alpha channel (GA). + * 3: Three red, green, blue color channels (RGB). + * 4: Three color channels and an alpha channel (RGBA). + * + * The components are encoded in one of two ways: + * + * a) As a small integer, value 0..255, contained in a single byte. For the + * alpha channel the original value is simply value/255. For the color or + * luminance channels the value is encoded according to the sRGB specification + * and matches the 8-bit format expected by typical display devices. + * + * The color/gray channels are not scaled (pre-multiplied) by the alpha + * channel and are suitable for passing to color management software. + * + * b) As a value in the range 0..65535, contained in a 2-byte integer. All + * channels can be converted to the original value by dividing by 65535; all + * channels are linear. Color channels use the RGB encoding (RGB end-points) of + * the sRGB specification. This encoding is identified by the + * PNG_FORMAT_FLAG_LINEAR flag below. + * + * When the simplified API needs to convert between sRGB and linear colorspaces, + * the actual sRGB transfer curve defined in the sRGB specification (see the + * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 + * approximation used elsewhere in libpng. + * + * When an alpha channel is present it is expected to denote pixel coverage + * of the color or luminance channels and is returned as an associated alpha + * channel: the color/gray channels are scaled (pre-multiplied) by the alpha + * value. + * + * The samples are either contained directly in the image data, between 1 and 8 + * bytes per pixel according to the encoding, or are held in a color-map indexed + * by bytes in the image data. In the case of a color-map the color-map entries + * are individual samples, encoded as above, and the image data has one byte per + * pixel to select the relevant sample from the color-map. + */ + +/* PNG_FORMAT_* + * + * #defines to be used in png_image::format. Each #define identifies a + * particular layout of sample data and, if present, alpha values. There are + * separate defines for each of the two component encodings. + * + * A format is built up using single bit flag values. All combinations are + * valid. Formats can be built up from the flag values or you can use one of + * the predefined values below. When testing formats always use the FORMAT_FLAG + * macros to test for individual features - future versions of the library may + * add new flags. + * + * When reading or writing color-mapped images the format should be set to the + * format of the entries in the color-map then png_image_{read,write}_colormap + * called to read or write the color-map and set the format correctly for the + * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! + * + * NOTE: libpng can be built with particular features disabled, if you see + * compiler errors because the definition of one of the following flags has been + * compiled out it is because libpng does not have the required support. It is + * possible, however, for the libpng configuration to enable the format on just + * read or just write; in that case you may see an error at run time. You can + * guard against this by checking for the definition of the appropriate + * "_SUPPORTED" macro, one of: + * + * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED + */ +#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ +#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ +#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */ +#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ + +#ifdef PNG_FORMAT_BGR_SUPPORTED +# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ +#endif + +#ifdef PNG_FORMAT_AFIRST_SUPPORTED +# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ +#endif + +/* Commonly used formats have predefined macros. + * + * First the single byte (sRGB) formats: + */ +#define PNG_FORMAT_GRAY 0 +#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA +#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR +#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) +#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) + +/* Then the linear 2-byte formats. When naming these "Y" is used to + * indicate a luminance (gray) channel. + */ +#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR +#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) +#define PNG_FORMAT_LINEAR_RGB_ALPHA \ + (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) + +/* With color-mapped formats the image data is one byte for each pixel, the byte + * is an index into the color-map which is formatted as above. To obtain a + * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP + * to one of the above definitions, or you can use one of the definitions below. + */ +#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) + +/* PNG_IMAGE macros + * + * These are convenience macros to derive information from a png_image + * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the + * actual image sample values - either the entries in the color-map or the + * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values + * for the pixels and will always return 1 for color-mapped formats. The + * remaining macros return information about the rows in the image and the + * complete image. + * + * NOTE: All the macros that take a png_image::format parameter are compile time + * constants if the format parameter is, itself, a constant. Therefore these + * macros can be used in array declarations and case labels where required. + * Similarly the macros are also pre-processor constants (sizeof is not used) so + * they can be used in #if tests. + * + * First the information about the samples. + */ +#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ + (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) + /* Return the total number of channels in a given format: 1..4 */ + +#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ + ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) + /* Return the size in bytes of a single component of a pixel or color-map + * entry (as appropriate) in the image: 1 or 2. + */ + +#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) + /* This is the size of the sample data for one sample. If the image is + * color-mapped it is the size of one color-map entry (and image pixels are + * one byte in size), otherwise it is the size of one image pixel. + */ + +#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) + /* The maximum size of the color-map required by the format expressed in a + * count of components. This can be used to compile-time allocate a + * color-map: + * + * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; + * + * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; + * + * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the + * information from one of the png_image_begin_read_ APIs and dynamically + * allocate the required memory. + */ + +/* Corresponding information about the pixels */ +#define PNG_IMAGE_PIXEL_(test,fmt)\ + (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) + +#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) + /* The number of separate channels (components) in a pixel; 1 for a + * color-mapped image. + */ + +#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) + /* The size, in bytes, of each component in a pixel; 1 for a color-mapped + * image. + */ + +#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) + /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ + +/* Information about the whole row, or whole image */ +#define PNG_IMAGE_ROW_STRIDE(image)\ + (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) + /* Return the total number of components in a single row of the image; this + * is the minimum 'row stride', the minimum count of components between each + * row. For a color-mapped image this is the minimum number of bytes in a + * row. + */ + +#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ + (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) + /* Return the size, in bytes, of an image buffer given a png_image and a row + * stride - the number of components to leave space for in each row. + */ + +#define PNG_IMAGE_SIZE(image)\ + PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) + /* Return the size, in bytes, of the image in memory given just a png_image; + * the row stride is the minimum stride required for the image. + */ + +#define PNG_IMAGE_COLORMAP_SIZE(image)\ + (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) + /* Return the size, in bytes, of the color-map of this image. If the image + * format is not a color-map format this will return a size sufficient for + * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if + * you don't want to allocate a color-map in this case. + */ + +/* PNG_IMAGE_FLAG_* + * + * Flags containing additional information about the image are held in the + * 'flags' field of png_image. + */ +#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 + /* This indicates the the RGB values of the in-memory bitmap do not + * correspond to the red, green and blue end-points defined by sRGB. + */ + +#define PNG_IMAGE_FLAG_FAST 0x02 + /* On write emphasise speed over compression; the resultant PNG file will be + * larger but will be produced significantly faster, particular for large + * images. Do not use this option for images which will be distributed, only + * used it when producing intermediate files that will be read back in + * repeatedly. For a typical 24-bit image the option will double the read + * speed at the cost of increasing the image size by 25%, however for many + * more compressible images the PNG file can be 10 times larger with only a + * slight speed gain. + */ + +#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 + /* On read if the image is a 16-bit per component image and there is no gAMA + * or sRGB chunk assume that the components are sRGB encoded. Notice that + * images output by the simplified API always have gamma information; setting + * this flag only affects the interpretation of 16-bit images from an + * external source. It is recommended that the application expose this flag + * to the user; the user can normally easily recognize the difference between + * linear and sRGB encoding. This flag has no effect on write - the data + * passed to the write APIs must have the correct encoding (as defined + * above.) + * + * If the flag is not set (the default) input 16-bit per component data is + * assumed to be linear. + * + * NOTE: the flag can only be set after the png_image_begin_read_ call, + * because that call initializes the 'flags' field. + */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* READ APIs + * --------- + * + * The png_image passed to the read APIs must have been initialized by setting + * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) + */ +#ifdef PNG_STDIO_SUPPORTED +PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, + const char *file_name)); + /* The named file is opened for read and the image header is filled in + * from the PNG header in the file. + */ + +PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, + FILE* file)); + /* The PNG header is read from the stdio FILE object. */ +#endif /* PNG_STDIO_SUPPORTED */ + +PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, + png_const_voidp memory, size_t size)); + /* The PNG header is read from the given memory buffer. */ + +PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, + png_const_colorp background, void *buffer, png_int_32 row_stride, + void *colormap)); + /* Finish reading the image into the supplied buffer and clean up the + * png_image structure. + * + * row_stride is the step, in byte or 2-byte units as appropriate, + * between adjacent rows. A positive stride indicates that the top-most row + * is first in the buffer - the normal top-down arrangement. A negative + * stride indicates that the bottom-most row is first in the buffer. + * + * background need only be supplied if an alpha channel must be removed from + * a png_byte format and the removal is to be done by compositing on a solid + * color; otherwise it may be NULL and any composition will be done directly + * onto the buffer. The value is an sRGB color to use for the background, + * for grayscale output the green channel is used. + * + * background must be supplied when an alpha channel must be removed from a + * single byte color-mapped output format, in other words if: + * + * 1) The original format from png_image_begin_read_from_* had + * PNG_FORMAT_FLAG_ALPHA set. + * 2) The format set by the application does not. + * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and + * PNG_FORMAT_FLAG_LINEAR *not* set. + * + * For linear output removing the alpha channel is always done by compositing + * on black and background is ignored. + * + * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must + * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. + * image->colormap_entries will be updated to the actual number of entries + * written to the colormap; this may be less than the original value. + */ + +PNG_EXPORT(238, void, png_image_free, (png_imagep image)); + /* Free any data allocated by libpng in image->opaque, setting the pointer to + * NULL. May be called at any time after the structure is initialized. + */ +#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */ + +#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED +#ifdef PNG_STDIO_SUPPORTED +/* WRITE APIS + * ---------- + * For write you must initialize a png_image structure to describe the image to + * be written. To do this use memset to set the whole structure to 0 then + * initialize fields describing your image. + * + * version: must be set to PNG_IMAGE_VERSION + * opaque: must be initialized to NULL + * width: image width in pixels + * height: image height in rows + * format: the format of the data (image and color-map) you wish to write + * flags: set to 0 unless one of the defined flags applies; set + * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB + * values do not correspond to the colors in sRGB. + * colormap_entries: set to the number of entries in the color-map (0 to 256) + */ +PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, + const char *file, int convert_to_8bit, const void *buffer, + png_int_32 row_stride, const void *colormap)); + /* Write the image to the named file. */ + +PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, + int convert_to_8_bit, const void *buffer, png_int_32 row_stride, + const void *colormap)); + /* Write the image to the given (FILE*). */ + +/* With both write APIs if image is in one of the linear formats with 16-bit + * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG + * gamma encoded according to the sRGB specification, otherwise a 16-bit linear + * encoded PNG file is written. + * + * With color-mapped data formats the colormap parameter point to a color-map + * with at least image->colormap_entries encoded in the specified format. If + * the format is linear the written PNG color-map will be converted to sRGB + * regardless of the convert_to_8_bit flag. + * + * With all APIs row_stride is handled as in the read APIs - it is the spacing + * from one row to the next in component sized units (1 or 2 bytes) and if + * negative indicates a bottom-up row layout in the buffer. + * + * Note that the write API does not support interlacing or sub-8-bit pixels. + */ +#endif /* PNG_STDIO_SUPPORTED */ +#endif /* PNG_SIMPLIFIED_WRITE_SUPPORTED */ +/******************************************************************************* + * END OF SIMPLIFIED API + ******************************************************************************/ + +/* 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(244); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* Do not put anything past this line */ +#endif /* PNG_H */ diff --git a/ext/native/ext/libpng17/pngconf.h b/ext/native/ext/libpng17/pngconf.h new file mode 100644 index 0000000000..de3ce894f6 --- /dev/null +++ b/ext/native/ext/libpng17/pngconf.h @@ -0,0 +1,652 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.7.0beta35 - March 17, 2014 + * + * Copyright (c) 1998-2013 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 + +/* To do: Do all of this in scripts/pnglibconf.dfa */ +#ifdef PNG_SAFE_LIMITS_SUPPORTED +# ifdef PNG_USER_WIDTH_MAX +# undef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000L +# endif +# ifdef PNG_USER_HEIGHT_MAX +# undef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000L +# endif +# ifdef PNG_USER_CHUNK_MALLOC_MAX +# undef PNG_USER_CHUNK_MALLOC_MAX +# define PNG_USER_CHUNK_MALLOC_MAX 4000000L +# endif +# ifdef PNG_USER_CHUNK_CACHE_MAX +# undef PNG_USER_CHUNK_CACHE_MAX +# define PNG_USER_CHUNK_CACHE_MAX 128 +# endif +#endif + +#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ + +/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C + * compiler for correct compilation. The following header files are required by + * the standard. If your compiler doesn't provide these header files, or they + * do not match the standard, you will need to provide/improve them. + */ +#include +#include + +/* Library header files. These header files are all defined by ISOC90; libpng + * expects conformant implementations, however, an ISOC90 conformant system need + * not provide these header files if the functionality cannot be implemented. + * In this case it will be necessary to disable the relevant parts of libpng in + * the build of pnglibconf.h. + * + * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not + * include this unnecessary header file. + */ + +#ifdef PNG_STDIO_SUPPORTED + /* Required for the definition of FILE: */ +# include +#endif + +#ifdef PNG_SETJMP_SUPPORTED + /* Required for the definition of jmp_buf and the declaration of longjmp: */ +# include +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED + /* Required for struct tm: */ +# include +#endif + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using + * PNG_NO_CONST; this is no longer supported except for data declarations which + * apparently still cause problems in 2011 on some compilers. + */ +#define PNG_CONST const /* backward compatibility only */ + +/* 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 when 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 was used in versions of libpng prior to 1.6.0 to protect + * against legacy (pre ISOC90) compilers that did not understand function + * prototypes. It is not required for modern C compilers. + */ +#ifndef PNGARG +# define PNGARG(arglist) arglist +#endif + +/* 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 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__) + /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or + * MinGW on any architecture currently supported by Windows. 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 + /* If this line results in an error __stdcall is not understood and + * PNG_API_RULE should not have been set to '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 */ +# 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. Disabling these removes the warnings but may also produce + * less efficient code. + */ +# if defined(__clang__) + /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ +# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# if !defined(PNG_PRIVATE) +# ifdef __has_extension +# if __has_extension(attribute_unavailable_with_message) +# define PNG_PRIVATE __attribute__((__unavailable__(\ + "This function is not exported by libpng."))) +# endif +# endif +# endif +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# elif defined(__GNUC__) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if __GNUC__ >= 3 +# 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 +# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ +# endif /* __GNUC__ >= 3 */ + +# elif 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 +# ifndef PNG_RESTRICT +# if (_MSC_VER >= 1400) +# define PNG_RESTRICT __restrict +# endif +# endif + +# elif defined(__WATCOMC__) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif +#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_RESTRICT +# define PNG_RESTRICT /* The C99 "restrict" feature */ +#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_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 + +#ifndef PNG_BUILDING_SYMBOL_TABLE +/* Some typedefs to get us started. These should be safe on most of the common + * platforms. + * + * png_uint_32 and png_int_32 may, currently, be larger than required to hold a + * 32-bit value however this is not normally advisable. + * + * png_uint_16 and png_int_16 should always be two bytes in size - this is + * verified at library build time. + * + * png_byte must always be one byte in size. + * + * The checks below use constants from limits.h, as defined by the ISOC90 + * standard. + */ +#if CHAR_BIT == 8 && UCHAR_MAX == 255 + typedef unsigned char png_byte; +#else +# error "libpng requires 8 bit bytes" +#endif + +#if INT_MIN == -32768 && INT_MAX == 32767 + typedef int png_int_16; +#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 + typedef short png_int_16; +#else +# error "libpng requires a signed 16 bit type" +#endif + +#if UINT_MAX == 65535 + typedef unsigned int png_uint_16; +#elif USHRT_MAX == 65535 + typedef unsigned short png_uint_16; +#else +# error "libpng requires an unsigned 16 bit type" +#endif + +#if INT_MIN < -2147483646 && INT_MAX > 2147483646 + typedef int png_int_32; +#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 + typedef long int png_int_32; +#else +# error "libpng requires a signed 32 bit (or more) type" +#endif + +#if UINT_MAX > 4294967294 + typedef unsigned int png_uint_32; +#elif ULONG_MAX > 4294967294 + typedef unsigned long int png_uint_32; +#else +# error "libpng requires an unsigned 32 bit (or more) type" +#endif + +/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, + * requires an ISOC90 compiler and relies on consistent behavior of sizeof. + * + * DEPRECATED: don't use these types, instead use size_t and ptrdiff_t. + */ +typedef size_t png_size_t; +typedef ptrdiff_t png_ptrdiff_t; + +/* libpng needs to know the maximum value of 'size_t' and this controls the + * definition of png_alloc_size_t, below. This maximum value of size_t limits + * but does not control the maximum allocations the library makes - there is + * direct application control of this through png_set_user_limits(). + */ +#ifndef PNG_SMALL_SIZE_T + /* Compiler specific tests for systems where size_t is known to be less than + * 32 bits (some of these systems may no longer work because of the lack of + * 'far' support; see above.) + */ +# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ + (defined(_MSC_VER) && defined(MAXSEG_64K)) +# define PNG_SMALL_SIZE_T +# endif +#endif + +/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no + * smaller than png_uint_32. Casts from 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 size_t or + * png_uint_32) should be explicitly applied; however, we do not expect to + * encounter practical situations that require such conversions. + * + * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than + * 4294967295 - i.e. less than the maximum value of png_uint_32. + */ +#ifdef PNG_SMALL_SIZE_T + typedef png_uint_32 png_alloc_size_t; +#else + typedef size_t png_alloc_size_t; +#endif + +/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler + * implementations of Intel CPU specific support of user-mode segmented address + * spaces, where 16-bit pointers address more than 65536 bytes of memory using + * separate 'segment' registers. The implementation requires two different + * types of pointer (only one of which includes the segment value.) + * + * If required this support is available in version 1.2 of libpng and may be + * available in versions through 1.5, although the correctness of the code has + * not been verified recently. + */ + +/* 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 * png_voidp; +typedef const void * png_const_voidp; +typedef png_byte * png_bytep; +typedef const png_byte * png_const_bytep; +typedef png_uint_32 * png_uint_32p; +typedef const png_uint_32 * png_const_uint_32p; +typedef png_int_32 * png_int_32p; +typedef const png_int_32 * png_const_int_32p; +typedef png_uint_16 * png_uint_16p; +typedef const png_uint_16 * png_const_uint_16p; +typedef png_int_16 * png_int_16p; +typedef const png_int_16 * png_const_int_16p; +typedef char * png_charp; +typedef const char * png_const_charp; +typedef png_fixed_point * png_fixed_point_p; +typedef const png_fixed_point * png_const_fixed_point_p; +typedef size_t * png_size_tp; +typedef const size_t * png_const_size_tp; + +#ifdef PNG_STDIO_SUPPORTED +typedef FILE * png_FILE_p; +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * png_doublep; +typedef const double * png_const_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte * * png_bytepp; +typedef png_uint_32 * * png_uint_32pp; +typedef png_int_32 * * png_int_32pp; +typedef png_uint_16 * * png_uint_16pp; +typedef png_int_16 * * png_int_16pp; +typedef const char * * png_const_charpp; +typedef char * * png_charpp; +typedef png_fixed_point * * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char * * * png_charppp; + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +#endif /* PNGCONF_H */ diff --git a/ext/native/ext/libpng17/pngdebug.h b/ext/native/ext/libpng17/pngdebug.h new file mode 100644 index 0000000000..b43c59cde5 --- /dev/null +++ b/ext/native/ext/libpng17/pngdebug.h @@ -0,0 +1,154 @@ + +/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c + * + * Copyright (c) 1998-2013 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.6.8 [December 19, 2013] + * + * 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' 3-space indentations (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) +# 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 ? " " : \ + (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \ + } 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 ? " " : \ + (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),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 ? " " : \ + (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),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/ext/native/ext/libpng17/pngerror.c b/ext/native/ext/libpng17/pngerror.c new file mode 100644 index 0000000000..828cac4b3d --- /dev/null +++ b/ext/native/ext/libpng17/pngerror.c @@ -0,0 +1,971 @@ + +/* pngerror.c - stub functions for i/o and memory allocation + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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_const_structrp png_ptr, + png_const_charp error_message)),PNG_NORETURN); + +#ifdef PNG_WARNINGS_SUPPORTED +static void /* PRIVATE */ +png_default_warning PNGARG((png_const_structrp 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_const_structrp 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_constcast(png_structrp,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_const_structrp 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_constcast(png_structrp,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 != 0) + *--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_const_structrp 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_constcast(png_structrp,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_const_structrp 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_const_structrp png_ptr, png_const_charp error_message) +{ + if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) + { +# ifdef PNG_READ_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + png_ptr->chunk_name != 0) + png_chunk_warning(png_ptr, error_message); + else +# endif + png_warning(png_ptr, error_message); + } + + else + { +# ifdef PNG_READ_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + png_ptr->chunk_name != 0) + png_chunk_error(png_ptr, error_message); + else +# endif + png_error(png_ptr, error_message); + } + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(error_message) +# endif +} + +void /* PRIVATE */ +png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) +{ + if (png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(error_message) +# endif +} + +void /* PRIVATE */ +png_app_error(png_const_structrp png_ptr, png_const_charp error_message) +{ + if (png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(error_message) +# endif +} +#endif /* BENIGN_ERRORS */ + +/* 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 196 /* Currently limited be profile_error in png.c */ +#if defined(PNG_WARNINGS_SUPPORTED) || \ + (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)) +static void /* PRIVATE */ +png_format_buffer(png_const_structrp 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_const_structrp 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_const_structrp 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_const_structrp 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); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(error_message) +# endif +} +#endif +#endif /* PNG_READ_SUPPORTED */ + +void /* PRIVATE */ +png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error) +{ +# ifndef PNG_WARNINGS_SUPPORTED + PNG_UNUSED(message) +# endif + + /* This is always supported, but for just read or just write it + * unconditionally does the right thing. + */ +# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) + if (png_ptr->mode & PNG_IS_READ_STRUCT) +# endif + +# ifdef PNG_READ_SUPPORTED + { + if (error < PNG_CHUNK_ERROR) + png_chunk_warning(png_ptr, message); + + else + png_chunk_benign_error(png_ptr, message); + } +# endif + +# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) + else if (!(png_ptr->mode & PNG_IS_READ_STRUCT)) +# endif + +# ifdef PNG_WRITE_SUPPORTED + { + if (error < PNG_CHUNK_WRITE_ERROR) + png_app_warning(png_ptr, message); + + else + png_app_error(png_ptr, message); + } +# endif +} + +#ifdef PNG_ERROR_TEXT_SUPPORTED + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ + defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ + (defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) &&\ + defined(PNG_sCAL_SUPPORTED)) +PNG_FUNCTION(void, +png_fixed_error,(png_const_structrp 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]; + 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_structrp png_ptr, png_longjmp_ptr longjmp_fn, + size_t jmp_buf_size) +{ + /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value + * and it must not change after that. Libpng doesn't care how big the + * buffer is, just that it doesn't change. + * + * If the buffer size is no *larger* than the size of jmp_buf when libpng is + * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0 + * semantics that this call will not fail. If the size is larger, however, + * the buffer is allocated and this may fail, causing the function to return + * NULL. + */ + if (png_ptr == NULL) + return NULL; + + if (png_ptr->jmp_buf_ptr == NULL) + { + png_ptr->jmp_buf_size = 0; /* not allocated */ + + if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local)) + png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; + + else + { + png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, + png_malloc_warn(png_ptr, jmp_buf_size)); + + if (png_ptr->jmp_buf_ptr == NULL) + return NULL; /* new NULL return on OOM */ + + png_ptr->jmp_buf_size = jmp_buf_size; + } + } + + else /* Already allocated: check the size */ + { + size_t size = png_ptr->jmp_buf_size; + + if (size == 0) + { + size = (sizeof png_ptr->jmp_buf_local); + if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local) + { + /* This is an internal error in libpng: somehow we have been left + * with a stack allocated jmp_buf when the application regained + * control. It's always possible to fix this up, but for the moment + * this is a png_error because that makes it easy to detect. + */ + png_error(png_ptr, "Libpng jmp_buf still allocated"); + /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */ + } + } + + if (size != jmp_buf_size) + { + png_warning(png_ptr, "Application jmp_buf size changed"); + return NULL; /* caller will probably crash: no choice here */ + } + } + + /* Finally fill in the function, now we have a satisfactory buffer. It is + * valid to change the function on every call. + */ + png_ptr->longjmp_fn = longjmp_fn; + return png_ptr->jmp_buf_ptr; +} + +void /* PRIVATE */ +png_free_jmpbuf(png_structrp png_ptr) +{ + if (png_ptr != NULL) + { + jmp_buf *jb = png_ptr->jmp_buf_ptr; + + /* A size of 0 is used to indicate a local, stack, allocation of the + * pointer; used here and in png.c + */ + if (jb != NULL && png_ptr->jmp_buf_size > 0) + { + + /* This stuff is so that a failure to free the error control structure + * does not leave libpng in a state with no valid error handling: the + * free always succeeds, if there is an error it gets ignored. + */ + if (jb != &png_ptr->jmp_buf_local) + { + /* Make an internal, libpng, jmp_buf to return here */ + jmp_buf free_jmp_buf; + + if (!setjmp(free_jmp_buf)) + { + png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */ + png_ptr->jmp_buf_size = 0; /* stack allocation */ + png_ptr->longjmp_fn = longjmp; + png_free(png_ptr, jb); /* Return to setjmp on error */ + } + } + } + + /* *Always* cancel everything out: */ + png_ptr->jmp_buf_size = 0; + png_ptr->jmp_buf_ptr = NULL; + png_ptr->longjmp_fn = 0; + } +} +#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_const_structrp 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_const_structrp png_ptr, int val),PNG_NORETURN) +{ +#ifdef PNG_SETJMP_SUPPORTED + if (png_ptr && png_ptr->longjmp_fn && png_ptr->jmp_buf_ptr) + png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val); +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(val) +#endif + + /* If control reaches this point, png_longjmp() must not return. The only + * choice is to terminate the whole process (or maybe the thread); to do + * this the ANSI-C abort() function is used unless a different method is + * implemented by overriding the default configuration setting for + * PNG_ABORT (see scripts/pnglibconf.dfa). + * + * API change: prior to 1.7.0 PNG_ABORT was invoked as a function type macro + * with no arguments 'PNG_ABORT();', in 1.7.0 this is changed to a simple + * macro that is defined in the configuration. + */ + 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_const_structrp 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->jmp_buf_ptr, 1) + */ +void PNGAPI +png_set_error_fn(png_structrp 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_structrp 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_structrp 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 + +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) + /* Currently the above both depend on SETJMP_SUPPORTED, however it would be + * possible to implement without setjmp support just so long as there is some + * way to handle the error return here: + */ +PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI +png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), + PNG_NORETURN) +{ + const png_const_structrp png_ptr = png_nonconst_ptr; + png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); + + /* An error is always logged here, overwriting anything (typically a warning) + * that is already there: + */ + if (image != NULL) + { + png_safecat(image->message, (sizeof image->message), 0, error_message); + image->warning_or_error |= PNG_IMAGE_ERROR; + + /* Retrieve the jmp_buf from within the png_control, making this work for + * C++ compilation too is pretty tricky: C++ wants a pointer to the first + * element of a jmp_buf, but C doesn't tell us the type of that. + */ + if (image->opaque != NULL && image->opaque->error_buf != NULL) + longjmp(png_control_jmp_buf(image->opaque), 1); + + /* Missing longjmp buffer, the following is to help debugging: */ + { + size_t pos = png_safecat(image->message, (sizeof image->message), 0, + "bad longjmp: "); + png_safecat(image->message, (sizeof image->message), pos, + error_message); + } + } + + /* Here on an internal programming error. */ + abort(); +} + +#ifdef PNG_WARNINGS_SUPPORTED +void /* PRIVATE */ PNGCBAPI +png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) +{ + const png_const_structrp png_ptr = png_nonconst_ptr; + png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); + + /* A warning is only logged if there is no prior warning or error. */ + if (image->warning_or_error == 0) + { + png_safecat(image->message, (sizeof image->message), 0, warning_message); + image->warning_or_error |= PNG_IMAGE_WARNING; + } +} +#endif + +int /* PRIVATE */ +png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg) +{ + volatile png_imagep image = image_in; + volatile int result; + volatile png_voidp saved_error_buf; + jmp_buf safe_jmpbuf; + + /* Safely execute function(arg) with png_error returning to this function. */ + saved_error_buf = image->opaque->error_buf; + result = setjmp(safe_jmpbuf) == 0; + + if (result != 0) + { + + image->opaque->error_buf = safe_jmpbuf; + result = function(arg); + } + + image->opaque->error_buf = saved_error_buf; + + /* And do the cleanup prior to any failure return. */ + if (result == 0) + png_image_free(image); + + return result; +} +#endif /* SIMPLIFIED READ/WRITE */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngget.c b/ext/native/ext/libpng17/pngget.c new file mode 100644 index 0000000000..1db8041995 --- /dev/null +++ b/ext/native/ext/libpng17/pngget.c @@ -0,0 +1,1199 @@ + +/* pngget.c - retrieval of values from info struct + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->height; + + return (0); +} + +png_byte PNGAPI +png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp + 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); + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return (0); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp + 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); + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return (0); +} + +png_uint_32 PNGAPI +png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp 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); + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return (0); +} + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp + 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)); + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return ((float)0.0); +} +#endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, + png_const_inforp 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; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} +#endif + +png_int_32 PNGAPI +png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp 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); + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp 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); + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp 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); + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp 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); + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_const_structrp 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_const_structrp png_ptr, + png_const_inforp 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_const_structrp png_ptr, + png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->channels); + + return (0); +} + +#ifdef PNG_READ_SUPPORTED +png_const_bytep PNGAPI +png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->signature); + + return (NULL); +} +#endif + +#ifdef PNG_bKGD_SUPPORTED +png_uint_32 PNGAPI +png_get_bKGD(png_const_structrp png_ptr, png_inforp 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 + */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM(png_const_structrp png_ptr, png_const_inforp 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) +{ + /* Quiet API change: this code used to only return the end points if a cHRM + * chunk was present, but the end points can also come from iCCP or sRGB + * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and + * the png_set_ APIs merely check that set end points are mutually + * consistent. + */ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS)) + { + png_debug1(1, "in %s retrieval function", "cHRM"); + + if (white_x != NULL) + *white_x = png_float(png_ptr, + info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); + if (white_y != NULL) + *white_y = png_float(png_ptr, + info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); + if (red_x != NULL) + *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, + "cHRM red X"); + if (red_y != NULL) + *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, + "cHRM red Y"); + if (green_x != NULL) + *green_x = png_float(png_ptr, + info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); + if (green_y != NULL) + *green_y = png_float(png_ptr, + info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); + if (blue_x != NULL) + *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, + "cHRM blue X"); + if (blue_y != NULL) + *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, + "cHRM blue Y"); + return (PNG_INFO_cHRM); + } + + return (0); +} + +png_uint_32 PNGAPI +png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp 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) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS)) + { + png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); + + if (red_X != NULL) + *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, + "cHRM red X"); + if (red_Y != NULL) + *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, + "cHRM red Y"); + if (red_Z != NULL) + *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, + "cHRM red Z"); + if (green_X != NULL) + *green_X = png_float(png_ptr, + info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); + if (green_Y != NULL) + *green_Y = png_float(png_ptr, + info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); + if (green_Z != NULL) + *green_Z = png_float(png_ptr, + info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); + if (blue_X != NULL) + *blue_X = png_float(png_ptr, + info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); + if (blue_Y != NULL) + *blue_Y = png_float(png_ptr, + info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); + if (blue_Z != NULL) + *blue_Z = png_float(png_ptr, + info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); + return (PNG_INFO_cHRM); + } + + return (0); +} +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp 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->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS)) + { + png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); + + if (int_red_X != NULL) + *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; + if (int_red_Y != NULL) + *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y; + if (int_red_Z != NULL) + *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z; + if (int_green_X != NULL) + *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X; + if (int_green_Y != NULL) + *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y; + if (int_green_Z != NULL) + *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z; + if (int_blue_X != NULL) + *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X; + if (int_blue_Y != NULL) + *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; + if (int_blue_Z != NULL) + *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; + return (PNG_INFO_cHRM); + } + + return (0); +} + +png_uint_32 PNGAPI +png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp 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->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS)) + { + if (white_x != NULL) + *white_x = info_ptr->colorspace.end_points_xy.whitex; + if (white_y != NULL) + *white_y = info_ptr->colorspace.end_points_xy.whitey; + if (red_x != NULL) + *red_x = info_ptr->colorspace.end_points_xy.redx; + if (red_y != NULL) + *red_y = info_ptr->colorspace.end_points_xy.redy; + if (green_x != NULL) + *green_x = info_ptr->colorspace.end_points_xy.greenx; + if (green_y != NULL) + *green_y = info_ptr->colorspace.end_points_xy.greeny; + if (blue_x != NULL) + *blue_x = info_ptr->colorspace.end_points_xy.bluex; + if (blue_y != NULL) + *blue_y = info_ptr->colorspace.end_points_xy.bluey; + return (PNG_INFO_cHRM); + } + + return (0); +} +# endif +#endif + +#ifdef PNG_gAMA_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *file_gamma) +{ + png_debug1(1, "in %s retrieval function", "gAMA"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) && + file_gamma != NULL) + { + *file_gamma = info_ptr->colorspace.gamma; + return (PNG_INFO_gAMA); + } + + return (0); +} +# endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, + double *file_gamma) +{ + png_debug1(1, "in %s retrieval function", "gAMA(float)"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) && + file_gamma != NULL) + { + *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, + "png_get_gAMA"); + return (PNG_INFO_gAMA); + } + + return (0); +} +# endif +#endif + +#ifdef PNG_sRGB_SUPPORTED +png_uint_32 PNGAPI +png_get_sRGB(png_const_structrp png_ptr, png_const_inforp 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 = info_ptr->colorspace.rendering_intent; + return (PNG_INFO_sRGB); + } + + return (0); +} +#endif + +#ifdef PNG_iCCP_SUPPORTED +png_uint_32 PNGAPI +png_get_iCCP(png_const_structrp png_ptr, png_inforp 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; + *proflen = png_get_uint_32(info_ptr->iccp_profile); + /* This is somewhat irrelevant since the profile data returned has + * actually been uncompressed. + */ + *compression_type = PNG_COMPRESSION_TYPE_BASE; + return (PNG_INFO_iCCP); + } + + return (0); +} +#endif + +#ifdef PNG_sPLT_SUPPORTED +int PNGAPI +png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, + png_sPLT_tpp spalettes) +{ + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) + { + *spalettes = info_ptr->splt_palettes; + return info_ptr->splt_palettes_num; + } + + return (0); +} +#endif + +#ifdef PNG_hIST_SUPPORTED +png_uint_32 PNGAPI +png_get_hIST(png_const_structrp png_ptr, png_inforp 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_const_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_inforp 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_FLOATING_ARITHMETIC_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp 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; the API is currently eliminated + * if neither floating point APIs nor internal floating point arithmetic + * are enabled. + */ + *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 /* FIXED_POINT */ + +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL(png_const_structrp png_ptr, png_const_inforp 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 */ +# endif /* FLOATING_ARITHMETIC */ + +png_uint_32 PNGAPI +png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_const_inforp 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_structrp png_ptr, png_inforp 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_structrp png_ptr, png_inforp 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 +int PNGAPI +png_get_text(png_const_structrp png_ptr, png_inforp 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 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_structrp png_ptr, png_inforp 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_structrp png_ptr, png_inforp 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_STORE_UNKNOWN_CHUNKS_SUPPORTED +int PNGAPI +png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp 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_structrp 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_structrp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_ptr : NULL); +} +#endif + +png_size_t PNGAPI +png_get_compression_buffer_size(png_const_structrp png_ptr) +{ + if (png_ptr == NULL) + return 0; + +# ifdef PNG_WRITE_SUPPORTED + if (png_ptr->mode & PNG_IS_READ_STRUCT) +# endif + { +# ifdef PNG_SEQUENTIAL_READ_SUPPORTED + return png_ptr->IDAT_read_size; +# else + return PNG_IDAT_READ_SIZE; +# endif + } + +# ifdef PNG_WRITE_SUPPORTED + else + return png_ptr->zbuffer_size; +# endif +} + +#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_structrp png_ptr) +{ + return (png_ptr ? png_ptr->user_width_max : 0); +} + +png_uint_32 PNGAPI +png_get_user_height_max (png_const_structrp 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_structrp 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_structrp 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_const_structrp png_ptr) +{ + return png_ptr->io_state; +} + +png_uint_32 PNGAPI +png_get_io_chunk_type (png_const_structrp png_ptr) +{ + return png_ptr->chunk_name; +} +#endif /* ?PNG_IO_STATE_SUPPORTED */ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +# ifdef PNG_GET_PALETTE_MAX_SUPPORTED +int PNGAPI +png_get_palette_max(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return png_ptr->num_palette_max; + + return (-1); +} +# endif +#endif + +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pnginfo.h b/ext/native/ext/libpng17/pnginfo.h new file mode 100644 index 0000000000..26bf26502c --- /dev/null +++ b/ext/native/ext/libpng17/pnginfo.h @@ -0,0 +1,260 @@ + +/* pnginfo.h - header file for PNG reference library + * + * Copyright (c) 1998-2013 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.6.1 [March 28, 2013] + * + * 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 are set by png_set_IHDR, called from the application on + * write, but the are never actually used by the write code. + */ + 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 */ + +#ifdef PNG_READ_SUPPORTED + /* This is never set during write */ + png_byte signature[8]; /* magic bytes read by libpng from start of file */ +#endif + + /* 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_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) + /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are + * defined. When COLORSPACE is switched on all the colorspace-defining + * chunks should be enabled, when GAMMA is switched on all the gamma-defining + * chunks should be enabled. If this is not done it becomes possible to read + * inconsistent PNG files and assign a probably incorrect interpretation to + * the information. (In other words, by carefully choosing which chunks to + * recognize the system configuration can select an interpretation for PNG + * files containing ambiguous data and this will result in inconsistent + * behavior between different libpng builds!) + */ + png_colorspace colorspace; +#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 */ +#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_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 */ + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + /* Storage for unknown chunks that the library doesn't recognize. */ + png_unknown_chunkp unknown_chunks; + + /* The type of this field is limited by the type of + * png_struct::user_chunk_cache_max, else overflow can occur. + */ + int unknown_chunks_num; +#endif + +#ifdef PNG_sPLT_SUPPORTED + /* Data on sPLT chunks (there may be more than one). */ + png_sPLT_tp splt_palettes; + int splt_palettes_num; /* Match type returned by png_get API */ +#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/ext/native/ext/libpng17/pnglibconf.h b/ext/native/ext/libpng17/pnglibconf.h new file mode 100644 index 0000000000..b93120c791 --- /dev/null +++ b/ext/native/ext/libpng17/pnglibconf.h @@ -0,0 +1,210 @@ +/* libpng 1.7.0beta35 STANDARD API DEFINITION */ + +/* pnglibconf.h - library build configuration */ + +/* Libpng version 1.7.0beta35 - March 22, 2014 */ + +/* Copyright (c) 1998-2013 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 */ +/* Machine generated file: DO NOT EDIT */ +/* Derived from: scripts/pnglibconf.dfa */ +#ifndef PNGLCONF_H +#define PNGLCONF_H +/* options */ +#define PNG_16BIT_SUPPORTED +#define PNG_ALIGNED_MEMORY_SUPPORTED +/*#undef PNG_ARM_NEON_API_SUPPORTED*/ +/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ +#define PNG_BENIGN_ERRORS_SUPPORTED +#define PNG_BENIGN_READ_ERRORS_SUPPORTED +/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ +#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_COLORSPACE_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_GAMMA_SUPPORTED +#define PNG_GET_PALETTE_MAX_SUPPORTED +#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#define PNG_INCH_CONVERSIONS_SUPPORTED +#define PNG_INFO_IMAGE_SUPPORTED +#define PNG_IO_STATE_SUPPORTED +#define PNG_MNG_FEATURES_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_CHECK_FOR_INVALID_INDEX_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_GAMMA_SUPPORTED +#define PNG_READ_GET_PALETTE_MAX_SUPPORTED +#define PNG_READ_GRAY_TO_RGB_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_OPT_PLTE_SUPPORTED +#define PNG_READ_PACKSWAP_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_QUANTIZE_SUPPORTED +#define PNG_READ_RGB_TO_GRAY_SUPPORTED +#define PNG_READ_SCALE_16_TO_8_SUPPORTED +#define PNG_READ_SHIFT_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_TRANSFORMS_SUPPORTED +#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_READ_USER_CHUNKS_SUPPORTED +#define PNG_READ_USER_TRANSFORM_SUPPORTED +#define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_gAMA_SUPPORTED +#define PNG_READ_hIST_SUPPORTED +#define PNG_READ_iCCP_SUPPORTED +#define PNG_READ_iTXt_SUPPORTED +#define PNG_READ_oFFs_SUPPORTED +#define PNG_READ_pCAL_SUPPORTED +#define PNG_READ_pHYs_SUPPORTED +#define PNG_READ_sBIT_SUPPORTED +#define PNG_READ_sCAL_SUPPORTED +#define PNG_READ_sPLT_SUPPORTED +#define PNG_READ_sRGB_SUPPORTED +#define PNG_READ_tEXt_SUPPORTED +#define PNG_READ_tIME_SUPPORTED +#define PNG_READ_tRNS_SUPPORTED +#define PNG_READ_zTXt_SUPPORTED +/*#undef PNG_SAFE_LIMITS_SUPPORTED*/ +#define PNG_SAVE_INT_32_SUPPORTED +#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SEQUENTIAL_READ_SUPPORTED +#define PNG_SETJMP_SUPPORTED +#define PNG_SET_OPTION_SUPPORTED +#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SET_USER_LIMITS_SUPPORTED +#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED +#define PNG_SIMPLIFIED_READ_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_SUPPORTED +#define PNG_STDIO_SUPPORTED +#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_TEXT_SUPPORTED +#define PNG_TIME_RFC1123_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_CHECK_FOR_INVALID_INDEX_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_GET_PALETTE_MAX_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_OPTIMIZE_CMF_SUPPORTED +#define PNG_WRITE_PACKSWAP_SUPPORTED +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED +#define PNG_WRITE_SUPPORTED +#define PNG_WRITE_SWAP_ALPHA_SUPPORTED +#define PNG_WRITE_SWAP_SUPPORTED +#define PNG_WRITE_TEXT_SUPPORTED +#define PNG_WRITE_TRANSFORMS_SUPPORTED +#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_WRITE_USER_TRANSFORM_SUPPORTED +#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_gAMA_SUPPORTED +#define PNG_WRITE_hIST_SUPPORTED +#define PNG_WRITE_iCCP_SUPPORTED +#define PNG_WRITE_iTXt_SUPPORTED +#define PNG_WRITE_oFFs_SUPPORTED +#define PNG_WRITE_pCAL_SUPPORTED +#define PNG_WRITE_pHYs_SUPPORTED +#define PNG_WRITE_sBIT_SUPPORTED +#define PNG_WRITE_sCAL_SUPPORTED +#define PNG_WRITE_sPLT_SUPPORTED +#define PNG_WRITE_sRGB_SUPPORTED +#define PNG_WRITE_tEXt_SUPPORTED +#define PNG_WRITE_tIME_SUPPORTED +#define PNG_WRITE_tRNS_SUPPORTED +#define PNG_WRITE_zTXt_SUPPORTED +#define PNG_bKGD_SUPPORTED +#define PNG_cHRM_SUPPORTED +#define PNG_gAMA_SUPPORTED +#define PNG_hIST_SUPPORTED +#define PNG_iCCP_SUPPORTED +#define PNG_iTXt_SUPPORTED +#define PNG_oFFs_SUPPORTED +#define PNG_pCAL_SUPPORTED +#define PNG_pHYs_SUPPORTED +#define PNG_sBIT_SUPPORTED +#define PNG_sCAL_SUPPORTED +#define PNG_sPLT_SUPPORTED +#define PNG_sRGB_SUPPORTED +#define PNG_tEXt_SUPPORTED +#define PNG_tIME_SUPPORTED +#define PNG_tRNS_SUPPORTED +#define PNG_zTXt_SUPPORTED +/* end of options */ +/* settings */ +#define PNG_ABORT { (abort()); } +#define PNG_API_RULE 0 +#define PNG_COST_SHIFT 3 +#define PNG_DEFAULT_READ_MACROS 1 +#define PNG_GAMMA_THRESHOLD_FIXED 5000 +#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE +#define PNG_INFLATE_BUF_SIZE 1024 +#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_TEXT_Z_DEFAULT_COMPRESSION (-1) +#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 +#define PNG_WEIGHT_SHIFT 8 +#define PNG_ZLIB_VERNUM 0 /* unknown */ +#define PNG_ZBUF_SIZE 8192 +#define PNG_ZLIB_HEADER +#define PNG_Z_DEFAULT_COMPRESSION (-1) +#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 +#define PNG_Z_DEFAULT_STRATEGY 1 +#define PNG_sCAL_PRECISION 5 +#define PNG_sRGB_PROFILE_CHECKS 2 +/* end of settings */ +#endif /* PNGLCONF_H */ diff --git a/ext/native/ext/libpng17/pngmem.c b/ext/native/ext/libpng17/pngmem.c new file mode 100644 index 0000000000..db336c8698 --- /dev/null +++ b/ext/native/ext/libpng17/pngmem.c @@ -0,0 +1,261 @@ + +/* pngmem.c - stub functions for memory allocation + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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) +/* Free a png_struct */ +void /* PRIVATE */ +png_destroy_png_struct(png_structrp png_ptr) +{ + if (png_ptr != NULL) + { + /* png_free might call png_error and may certainly call + * png_get_mem_ptr, so fake a temporary png_struct to support this. + */ + png_struct dummy_struct = *png_ptr; + memset(png_ptr, 0, (sizeof *png_ptr)); + png_free(&dummy_struct, png_ptr); + +# ifdef PNG_SETJMP_SUPPORTED + /* We may have a jmp_buf left to deallocate. */ + png_free_jmpbuf(&dummy_struct); +# 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_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; + + ret = png_malloc(png_ptr, size); + + if (ret != NULL) + memset(ret, 0, size); + + return ret; +} + +/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of + * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. + * Checking and error handling must happen outside this routine; it returns NULL + * if the allocation cannot be done (for any reason.) + */ +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED) +{ + /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS + * allocators have also been removed in 1.6.0, so any 16-bit system now has + * to implement a user memory handler. This checks to be sure it isn't + * called with big numbers. + */ +#ifndef PNG_USER_MEM_SUPPORTED + PNG_UNUSED(png_ptr) +#endif + + if (size > 0 && size <= PNG_SIZE_MAX +# ifdef PNG_MAX_MALLOC_64K + && size <= 65536U +# endif + ) + { +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr != NULL && png_ptr->malloc_fn != NULL) + return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); + + else +#endif + return malloc((size_t)size); /* checked for truncation above */ + } + + else + return NULL; +} + +#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ + defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) +/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 + * that arises because of the checks in png_realloc_array that are repeated in + * png_malloc_array. + */ +static png_voidp +png_malloc_array_checked(png_const_structrp png_ptr, int nelements, + size_t element_size) +{ + png_alloc_size_t req = nelements; /* known to be > 0 */ + + if (req <= PNG_SIZE_MAX/element_size) + return png_malloc_base(png_ptr, req * element_size); + + /* The failure case when the request is too large */ + return NULL; +} + +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_malloc_array,(png_const_structrp png_ptr, int nelements, + size_t element_size),PNG_ALLOCATED) +{ + if (nelements <= 0 || element_size == 0) + png_error(png_ptr, "internal error: array alloc"); + + return png_malloc_array_checked(png_ptr, nelements, element_size); +} + +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_realloc_array,(png_structrp png_ptr, png_const_voidp old_array, + int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) +{ + /* These are internal errors: */ + if (add_elements <= 0 || element_size == 0 || old_elements < 0 || + (old_array == NULL && old_elements > 0)) + png_error(png_ptr, "internal error: array realloc"); + + /* Check for overflow on the elements count (so the caller does not have to + * check.) + */ + if (add_elements <= INT_MAX - old_elements) + { + png_voidp new_array = png_malloc_array_checked(png_ptr, + old_elements+add_elements, element_size); + + if (new_array != NULL) + { + /* Because png_malloc_array worked the size calculations below cannot + * overflow. + */ + if (old_elements > 0) + memcpy(new_array, old_array, element_size*(unsigned)old_elements); + + memset((char*)new_array + element_size*(unsigned)old_elements, 0, + element_size*(unsigned)add_elements); + + return new_array; + } + } + +#ifdef PNG_READ_SUPPORTED +# ifdef PNG_USER_LIMITS_SUPPORTED + /* The potential overflow case. Set the cache counter so libpng will + * not make any more attempts + */ + png_ptr->user_chunk_cache_max = 2; +# endif +#endif + + return NULL; /* error */ +} +#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */ + +/* Various functions that have different error handling are derived from this. + * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate + * function png_malloc_default is also provided. + */ +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; + + if (png_ptr == NULL) + return NULL; + + ret = png_malloc_base(png_ptr, size); + + if (ret == NULL) + png_error(png_ptr, "Out of memory"); + + return ret; +} + +/* This function was added at libpng version 1.2.3. The png_malloc_warn() + * function will 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_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED) +{ + if (png_ptr != NULL) + { + png_voidp ret = png_malloc_base(png_ptr, size); + + if (ret != NULL) + return ret; + + png_warning(png_ptr, "Out of memory"); + } + + return NULL; +} + +/* Free a pointer allocated by png_malloc(). If ptr is NULL, return + * without taking any action. + */ +void PNGAPI +png_free(png_const_structrp 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_constcast(png_structrp,png_ptr), ptr); + + else +#endif /* PNG_USER_MEM_SUPPORTED */ + free(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_structrp 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_structrp png_ptr) +{ + if (png_ptr == NULL) + return NULL; + + return png_ptr->mem_ptr; +} +#endif /* PNG_USER_MEM_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngpread.c b/ext/native/ext/libpng17/pngpread.c new file mode 100644 index 0000000000..0b251f7363 --- /dev/null +++ b/ext/native/ext/libpng17/pngpread.c @@ -0,0 +1,1292 @@ + +/* pngpread.c - read a png file in push mode + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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_structrp png_ptr, png_inforp 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_structrp 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 != 0) + 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_structrp 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_structrp png_ptr, png_inforp 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; + } + + 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_structrp png_ptr, png_inforp info_ptr) +{ + png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ + 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_structrp png_ptr, png_inforp info_ptr) +{ + png_uint_32 chunk_name; +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + int keep; /* unknown handling method */ +#endif + + /* 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) + { + if (png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_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"); + + png_ptr->mode |= PNG_HAVE_IDAT; + png_ptr->process_mode = PNG_READ_IDAT_MODE; + + 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[p]"); + } + + 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_SET_UNKNOWN_CHUNKS_SUPPORTED + else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); + + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + } +#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) + { + png_ptr->idat_size = png_ptr->push_length; + 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_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_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_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_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, + PNG_HANDLE_CHUNK_AS_DEFAULT); + } + + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; +} + +void /* PRIVATE */ +png_push_crc_skip(png_structrp 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_structrp 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; + + 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; + + 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_structrp 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"); + } + + 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) + { + 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_structrp 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_structrp 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_ZSTREAM_ENDED)) + 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; + png_ptr->zowner = 0; + } +} + +void /* PRIVATE */ +png_process_IDAT_data(png_structrp 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; + /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ + 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_ZSTREAM_ENDED)) + { + 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)) + { + /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ + 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_ZSTREAM_ENDED; + png_ptr->zowner = 0; + + /* 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_ZSTREAM_ENDED; + png_ptr->zowner = 0; + + /* 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_ZSTREAM_ENDED; + } + + /* 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_structrp 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: + */ + 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_structrp 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[] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte 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 png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + */ +#endif + + 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; + 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 */ +} + +void /* PRIVATE */ +png_push_have_info(png_structrp png_ptr, png_inforp info_ptr) +{ + if (png_ptr->info_fn != NULL) + (*(png_ptr->info_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_end(png_structrp png_ptr, png_inforp info_ptr) +{ + if (png_ptr->end_fn != NULL) + (*(png_ptr->end_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_row(png_structrp 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_const_structrp 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_structrp 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_structrp png_ptr) +{ + if (png_ptr == NULL) + return (NULL); + + return png_ptr->io_ptr; +} +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngpriv.h b/ext/native/ext/libpng17/pngpriv.h new file mode 100644 index 0000000000..1156092683 --- /dev/null +++ b/ext/native/ext/libpng17/pngpriv.h @@ -0,0 +1,1852 @@ + +/* pngpriv.h - private declarations for use inside libpng + * + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2014 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.7.0 [(PENDING RELEASE)] + * + * 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 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 */ + +#ifndef PNG_VERSION_INFO_ONLY +/* Keep standard libraries at the top of this file */ + +/* Standard library headers not required by png.h: */ +# include +# include + +/* For headers only required with some build configurations see the lines after + * pnglibconf.h is included! + */ + +#endif /* VERSION_INFO_ONLY */ + +#define PNGLIB_BUILD /*libpng is being built, not used*/ + +/* If HAVE_CONFIG_H is defined during the build then the build system must + * provide an appropriate "config.h" file on the include path. The header file + * must provide definitions as required below (search for "HAVE_CONFIG_H"); + * see configure.ac for more details of the requirements. The macro + * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on + * 'configure'; define this macro to prevent the configure build including the + * configure generated config.h. Libpng is expected to compile without *any* + * special build system support on a reasonably ANSI-C compliant system. + */ +#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) +# include + + /* Pick up the definition of 'restrict' from config.h if it was read: */ +# define PNG_RESTRICT restrict +#endif + +/* To support symbol prefixing it is necessary to know *before* including png.h + * whether the fixed point (and maybe other) APIs are exported, because if they + * are not internal definitions may be required. This is handled below just + * before png.h is included, but load the configuration now if it is available. + */ +#ifndef PNGLCONF_H +# include "pnglibconf.h" +#endif + +/* Local renames may change non-exported API functions from png.h */ +#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H) +# include "pngprefix.h" +#endif + +#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 + +#ifndef PNG_VERSION_INFO_ONLY +/* Additional standard libaries required in certain cases, put only standard + * ANSI-C89 headers here. If not available, or non-functional, the problem + * should be fixed by writing a wrapper for the header and the file on your + * include path. + */ +#if defined(PNG_sCAL_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + /* png.c requires the following ANSI-C constants if the conversion of + * floating point to ASCII is implemented therein: + * + * DBL_MIN_10_EXP Minimum negative integer such that 10^integer is a + * normalized (double) value. + * 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 +#endif /* sCAL && FLOATING_POINT */ + +#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) ||\ + defined(PNG_FLOATING_POINT_SUPPORTED) + /* ANSI-C90 math functions are required. Full compliance with the standard + * is probably not a requirement, but the functions must exist and be + * declared in + */ +# include +#endif /* FLOATING_ARITHMETIC || FLOATING_POINT */ + +#endif /* VERSION_INFO_ONLY */ + +/* Compile time options. + * ===================== + * In a multi-arch build the compiler may compile the code several times for the + * same object module, producing different binaries for different architectures. + * When this happens configure-time setting of the target host options cannot be + * done and this interferes with the handling of the ARM NEON optimizations, and + * possibly other similar optimizations. Put additional tests here; in general + * this is needed when the same option can be changed at both compile time and + * run time depending on the target OS (i.e. iOS vs Android.) + * + * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because + * this is not possible with certain compilers (Oracle SUN OS CC), as a result + * it is necessary to ensure that all extern functions that *might* be used + * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__ + * below is one example of this behavior because it is controlled by the + * presence or not of -mfpu=neon on the GCC command line, it is possible to do + * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely + * do this. + */ +#ifndef PNG_ARM_NEON_OPT + /* ARM NEON optimizations are being controlled by the compiler settings, + * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon + * with GCC) then the compiler will define __ARM_NEON__ and we can rely + * unconditionally on NEON instructions not crashing, otherwise we must + * disable use of NEON instructions. + * + * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they + * can only be turned on automatically if that is supported too. If + * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail + * to compile with an appropriate #error if ALIGNED_MEMORY has been turned + * off. + */ +# if defined(__ARM_NEON__) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_ARM_NEON_OPT 2 +# else +# define PNG_ARM_NEON_OPT 0 +# endif +#endif + +#if PNG_ARM_NEON_OPT > 0 + /* NEON optimizations are to be at least considered by libpng, so enable the + * callbacks to do this. + */ +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon + + /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used + * if possible - if __ARM_NEON__ is set and the compiler version is not known + * to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can + * be: + * + * 1 The intrinsics code (the default with __ARM_NEON__) + * 2 The hand coded assembler (the default without __ARM_NEON__) + * + * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however + * this is *NOT* supported and may cease to work even after a minor revision + * to libpng. It *is* valid to do this for testing purposes, e.g. speed + * testing or a new compiler, but the results should be communicated to the + * libpng implementation list for incorporation in the next minor release. + */ +# ifndef PNG_ARM_NEON_IMPLEMENTATION +# ifdef __ARM_NEON__ +# if defined(__clang__) + /* At present it is unknown by the libpng developers which versions + * of clang support the intrinsics, however some or perhaps all + * versions do not work with the assembler so this may be + * irrelevant, so just use the default (do nothing here.) + */ +# elif defined(__GNUC__) + /* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to + * work, so if this *is* GCC, or G++, look for a version >4.5 + */ +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6) +# define PNG_ARM_NEON_IMPLEMENTATION 2 +# endif /* no GNUC support */ +# endif /* __GNUC__ */ +# else /* !defined __ARM_NEON__ */ + /* The 'intrinsics' code simply won't compile without this -mfpu=neon: + */ +# define PNG_ARM_NEON_IMPLEMENTATION 2 +# endif /* __ARM_NEON__ */ +# endif /* !defined PNG_ARM_NEON_IMPLEMENTATION */ + +# ifndef PNG_ARM_NEON_IMPLEMENTATION + /* Use the intrinsics code by default. */ +# define PNG_ARM_NEON_IMPLEMENTATION 1 +# endif +#endif /* PNG_ARM_NEON_OPT > 0 */ + +/* 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 + +/* Symbol preprocessing support. + * + * To enable listing global, but internal, symbols the following macros should + * always be used to declare an extern data or function object in this file. + */ +#ifndef PNG_INTERNAL_DATA +# define PNG_INTERNAL_DATA(type, name, array) extern type name array +#endif + +#ifndef PNG_INTERNAL_FUNCTION +# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ + extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) +#endif + +#ifndef PNG_INTERNAL_CALLBACK +# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ + extern PNG_FUNCTION(type, (PNGCBAPI name), args, PNG_EMPTY attributes) +#endif + +/* If floating or fixed point APIs are disabled they may still be compiled + * internally. To handle this make sure they are declared as the appropriate + * internal extern function (otherwise the symbol prefixing stuff won't work and + * the functions will be used without definitions.) + * + * NOTE: although all the API functions are declared here they are not all + * actually built! Because the declarations are still made it is necessary to + * fake out types that they depend on. + */ +#ifndef PNG_FP_EXPORT +# ifndef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); +# ifndef PNG_VERSION_INFO_ONLY + typedef struct png_incomplete png_double; + typedef png_double* png_doublep; + typedef const png_double* png_const_doublep; + typedef png_double** png_doublepp; +# endif +# endif +#endif +#ifndef PNG_FIXED_EXPORT +# ifndef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); +# endif +#endif + +/* Include png.h here to get the version info and other macros, pngstruct.h and + * pnginfo.h are included later under the protection of !PNG_VERSION_INFO_ONLY + */ +#include "png.h" + +/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ +#ifndef PNG_DLL_EXPORT +# define PNG_DLL_EXPORT +#endif + +/* asserts are turned off in release code, but are in even in release candidates + * because often system builders only check future libpng releases when a + * release candidate is available. + */ +#if PNG_LIBPNG_BUILD_BASE_TYPE == PNG_LIBPNG_BUILD_STABLE +# define NDEBUG +#endif +#ifndef PNG_VERSION_INFO_ONLY +# include +#endif + +/* SECURITY and SAFETY: + * + * By default libpng is built without any internal limits on image size, + * individual heap (png_malloc) allocations or the total amount of memory used. + * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used + * (unless individually overridden). These limits are believed to be fairly + * safe, but builders of secure systems should verify the values against the + * real system capabilities. + */ +#ifdef PNG_SAFE_LIMITS_SUPPORTED + /* 'safe' limits */ +# ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000 +# endif +# ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000 +# endif +# ifndef PNG_USER_CHUNK_CACHE_MAX +# define PNG_USER_CHUNK_CACHE_MAX 128 +# endif +# ifndef PNG_USER_CHUNK_MALLOC_MAX +# define PNG_USER_CHUNK_MALLOC_MAX 8000000 +# endif +#else + /* values for no limits */ +# ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 0x7fffffff +# endif +# ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 0x7fffffff +# endif +# ifndef PNG_USER_CHUNK_CACHE_MAX +# define PNG_USER_CHUNK_CACHE_MAX 0 +# endif +# ifndef PNG_USER_CHUNK_MALLOC_MAX +# define PNG_USER_CHUNK_MALLOC_MAX 0 +# 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 + +/* 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_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_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) +# define png_constcast(type, value) const_cast(value) +# define png_aligncast(type, value) \ + static_cast(static_cast(value)) +# define png_aligncastconst(type, value) \ + static_cast(static_cast(value)) +#else +# define png_voidcast(type, value) (value) +# define png_constcast(type, value) ((type)(value)) +# define png_aligncast(type, value) ((void*)(value)) +# define png_aligncastconst(type, value) ((const void*)(value)) +#endif /* __cplusplus */ + +/* 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 + +/* 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_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 + /* 0x20 (unused) */ + /* 0x40 (unused) */ + /* 0x80 (unused) */ +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 + /* 0x800 (unused) */ +#define PNG_HAVE_PNG_SIGNATURE 0x1000 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ + /* 0x4000 (unused) */ +#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */ + +/* 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 */ + /* 0x0100 unused */ +#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_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */ + /* 0x0004 unused */ +#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */ + /* 0x0010 unused */ + /* 0x0020 unused */ +#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_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */ +#define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */ +#define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */ +#define PNG_FLAG_BACKGROUND_IS_GRAY 0x800000 +#define PNG_FLAG_BACKGROUND_EXPAND 0x1000000 + /* 0x2000000 unused */ + /* 0x4000000 unused */ + /* 0x8000000 unused */ + /* 0x10000000 unused */ + /* 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) + +/* 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))) + +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +/* See below for the definitions of the tables used in these macros */ +#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\ + ((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)) + /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB + * encoded value with maximum error 0.646365. Note that the input is not a + * 16-bit value; it has been multiplied by 255! */ +#endif /* PNG_SIMPLIFIED_READ/WRITE */ + +/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255 + * by dividing by 257 *with rounding*. This macro is exact for the given range. + * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the + * macro were established by experiment (modifying the added value). The macro + * has a second variant that takes a value already scaled by 255 and divides by + * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it + * only gives off-by-one errors and only for 0.5% (1 in 200) of the values. + */ +#define PNG_DIV65535(v24) (((v24) + 32895) >> 16) +#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255) + +/* 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)) +#endif +/* else the corresponding function is defined below, inside the scope of the + * cplusplus test. + */ +#endif + +/* 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 + +/* Almost everything below is C specific; the #defines above can be used in + * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot. + */ +#ifndef PNG_VERSION_INFO_ONLY + +#include "pngstruct.h" +#include "pnginfo.h" + +/* Validate the include paths - the include path used to generate pnglibconf.h + * must match that used in the build, or we must be using pnglibconf.h.prebuilt: + */ +#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM +# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \ + "-I (include path) error: see the notes in pngpriv.h" + /* This means that when pnglibconf.h was built the copy of zlib.h that it + * used is not the same as the one being used here. Because the build of + * libpng makes decisions to use inflateInit2 and inflateReset2 based on the + * zlib version number and because this affects handling of certain broken + * PNG files the -I directives must match. + * + * The most likely explanation is that you passed a -I in CFLAGS, this will + * not work; all the preprocessor directories and in particular all the -I + * directives must be in CPPFLAGS. + */ +#endif + +/* This is used for 16 bit gamma tables -- only the top level pointers are + * const; this could be changed: + */ +typedef const png_uint_16p * png_const_uint_16pp; + +/* Added to libpng-1.5.7: sRGB conversion tables */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]); + /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value, + * 0..65535. This table gives the closest 16-bit answers (no errors). + */ +#endif + +PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]); +PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]); +#endif /* PNG_SIMPLIFIED_READ/WRITE */ + + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Internal functions; these are not exported from a DLL however because they + * are used within several of the C source files they have to be C extern. + * + * All of these functions must be declared with PNG_INTERNAL_FUNCTION. + */ + +/* Zlib support */ +#define PNG_UNEXPECTED_ZLIB_RETURN (-7) +PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret), + PNG_EMPTY); + /* Used by the zlib handling functions to ensure that z_stream::msg is always + * set before they return. + */ + +#ifdef PNG_WRITE_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr, + png_compression_bufferp *list),PNG_EMPTY); + /* Free the buffer list used by the compressed write code. */ +#endif + +#ifdef PNG_WRITE_FILTER_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_alloc_filter_row_buffers, + (png_structrp png_ptr, int filters),PNG_EMPTY); + /* Allocate pixel row buffers to cache filtered rows while testing candidate + * filters. + * TODO: avoid this, only one spare row buffer (at most) is required, this + * wastes a lot of memory for large images. + */ +#endif + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ + (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ + defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ + (defined(PNG_sCAL_SUPPORTED) && \ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) +PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr, + double fp, png_const_charp text),PNG_EMPTY); +#endif + +/* Check the user version string for compatibility, returns false if the version + * numbers aren't compatible. + */ +PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr, + png_const_charp user_png_ver),PNG_EMPTY); + +/* Internal base allocator - no messages, NULL on failure to allocate. This + * does, however, call the application provided allocator and that could call + * png_error (although that would be a bug in the application implementation.) + */ +PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr, + png_alloc_size_t size),PNG_ALLOCATED); + +#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ + defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) +/* Internal array allocator, outputs no error or warning messages on failure, + * just returns NULL. + */ +PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr, + int nelements, size_t element_size),PNG_ALLOCATED); + +/* The same but an existing array is extended by add_elements. This function + * also memsets the new elements to 0 and copies the old elements. The old + * array is not freed or altered. + */ +PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_structrp png_ptr, + png_const_voidp array, int old_elements, int add_elements, + size_t element_size),PNG_ALLOCATED); +#endif /* text, sPLT or unknown chunks */ + +/* Magic to create a struct when there is no struct to call the user supplied + * memory allocators. Because error handling has not been set up the memory + * handlers can't safely call png_error, but this is an obscure and undocumented + * restriction so libpng has to assume that the 'free' handler, at least, might + * call png_error. + */ +PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct, + (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); + +/* Free memory from internal libpng struct */ +PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr), + PNG_EMPTY); + +/* Free an allocated jmp_buf (always succeeds) */ +PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY); + +/* Function to allocate memory for zlib. PNGAPI is disallowed. */ +PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size), + PNG_ALLOCATED); + +/* Function to free memory for zlib. PNGAPI is disallowed. */ +PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY); + +/* 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_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, + png_bytep data, png_size_t length),PNG_EMPTY); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr, + png_bytep buffer, png_size_t length),PNG_EMPTY); +#endif + +PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr, + png_bytep data, png_size_t length),PNG_EMPTY); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED +PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr), + PNG_EMPTY); +# endif +#endif + +/* Reset the CRC variable */ +PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY); + +/* Write the "data" buffer to whatever output you are using */ +PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr, + png_const_bytep data, png_size_t length),PNG_EMPTY); + +/* Read and check the PNG file signature */ +PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); + +/* Read the chunk header (length + type name) */ +PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr), + PNG_EMPTY); + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data, + png_size_t length),PNG_EMPTY); + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf, + png_uint_32 length),PNG_EMPTY); + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr, + png_uint_32 skip),PNG_EMPTY); + +/* Read the CRC from the file and compare it to the libpng calculated CRC */ +PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY); + +/* 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_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr, + png_const_bytep ptr, png_size_t length),PNG_EMPTY); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY); +#endif + +/* Write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp 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_EMPTY); + +PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr, + png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr, + png_const_bytep row_data, png_alloc_size_t row_data_length, int flush), + PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY); + +#ifdef PNG_WRITE_gAMA_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr, + png_fixed_point file_gamma),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr, + png_const_color_8p sbit, int color_type),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_cHRM_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr, + const png_xy *xy), PNG_EMPTY); + /* The xy value must have been previously validated */ +#endif + +#ifdef PNG_WRITE_sRGB_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr, + int intent),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, + png_const_charp name, png_const_bytep profile), PNG_EMPTY); + /* The profile must have been previously validated for correctness, the + * length comes from the first four bytes. Only the base, deflate, + * compression is supported. + */ +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr, + png_const_sPLT_tp palette),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr, + png_const_bytep trans, png_const_color_16p values, int number, + int color_type),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_bKGD_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr, + png_const_color_16p values, int color_type),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr, + png_const_uint_16p hist, int num_hist),PNG_EMPTY); +#endif + +/* Chunks that have keywords */ +#ifdef PNG_WRITE_tEXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, + png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp + key, png_const_charp text, png_size_t text_len, int compression),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_iTXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr, + int compression, png_const_charp key, png_const_charp lang, + png_const_charp lang_key, png_const_charp text),PNG_EMPTY); +#endif + +#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ +PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_structrp png_ptr, + png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_pCAL_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp 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_EMPTY); +#endif + +#ifdef PNG_WRITE_pHYs_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_tIME_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr, + png_const_timep mod_time),PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr, + int unit, png_const_charp width, png_const_charp height),PNG_EMPTY); +#endif + +/* Called when finished processing a row of data */ +PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr), + PNG_EMPTY); + +/* Internal use only. Called before first row of data */ +PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr), + PNG_EMPTY); + +/* 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 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_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr, + png_bytep row, int display),PNG_EMPTY); + +#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_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY); +#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_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info, + png_bytep row, int pass),PNG_EMPTY); +#endif + +/* Unfilter a row: check the filter value before calling this, there is no point + * calling it for PNG_FILTER_VALUE_NONE. + */ +PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop + row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); + +/* Choose the best filter to use and filter the row data */ +PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, + png_row_infop row_info),PNG_EMPTY); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr, + png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY); + /* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer + * is NULL the function checks, instead, for the end of the stream. In this + * case a benign error will be issued if the stream end is not found or if + * extra data has to be consumed. + */ +PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr), + PNG_EMPTY); + /* This cleans up when the IDAT LZ stream does not end when the last image + * byte is read; there is still some pending input. + */ + +PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr), + PNG_EMPTY); + /* Finish a row while reading, dealing with interlacing passes, etc. */ +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +/* Initialize the row buffers, etc. */ +PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +/* Optional call to update the users info structure */ +PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +#endif + +/* Shared transform functions, defined in pngtran.c */ +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info, + png_bytep row, int at_start),PNG_EMPTY); +#endif + +#ifdef PNG_16BIT_SUPPORTED +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info, + png_bytep row),PNG_EMPTY); +#endif +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info, + png_bytep row),PNG_EMPTY); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info, + png_bytep row),PNG_EMPTY); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info, + png_bytep row),PNG_EMPTY); +#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_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + +#ifdef PNG_READ_bKGD_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_gAMA_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_hIST_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_iCCP_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#ifdef PNG_READ_iTXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_sPLT_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#ifdef PNG_READ_sRGB_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_tIME_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_tRNS_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + +PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr, + png_uint_32 chunk_name),PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); + /* This is the function that gets called for unknown chunks. The 'keep' + * argument is either non-zero for a known chunk that has been set to be + * handled as unknown or zero for an unknown chunk. By default the function + * just skips the chunk or errors out if it is critical. + */ + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) +PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling, + (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY); + /* Exactly as the API png_handle_as_unknown() except that the argument is a + * 32-bit chunk name, not a string. + */ +#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ + +/* Handle the transformations for reading and writing */ +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr, + png_row_infop row_info),PNG_EMPTY); +#endif +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr, + png_row_infop row_info),PNG_EMPTY); +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr), + PNG_EMPTY); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_crc_skip,(png_structrp png_ptr, + png_uint_32 length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_crc_finish,(png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr, + png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr, + png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr, + png_bytep row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr), + PNG_EMPTY); +# ifdef PNG_READ_tEXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +# endif +# ifdef PNG_READ_zTXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +# endif +# ifdef PNG_READ_iTXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr, + png_inforp info_ptr),PNG_EMPTY); +# endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +/* Added at libpng version 1.6.0 */ +#ifdef PNG_GAMMA_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr, + png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY); + /* Set the colorspace gamma with a value provided by the application or by + * the gAMA chunk on read. The value will override anything set by an ICC + * profile. + */ + +PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, + png_inforp info_ptr), PNG_EMPTY); + /* Synchronize the info 'valid' flags with the colorspace */ + +PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, + png_inforp info_ptr), PNG_EMPTY); + /* Copy the png_struct colorspace to the info_struct and call the above to + * synchronize the flags. Checks for NULL info_ptr and does nothing. + */ +#endif + +/* Added at libpng version 1.4.0 */ +#ifdef PNG_COLORSPACE_SUPPORTED +/* These internal functions are for maintaining the colorspace structure within + * a png_info or png_struct (or, indeed, both). + */ +PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities, + (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy, + int preferred), PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints, + (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ, + int preferred), PNG_EMPTY); + +#ifdef PNG_sRGB_SUPPORTED +PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr, + png_colorspacerp colorspace, int intent), PNG_EMPTY); + /* This does set the colorspace gAMA and cHRM values too, but doesn't set the + * flags to write them, if it returns false there was a problem and an error + * message has already been output (but the colorspace may still need to be + * synced to record the invalid flag). + */ +#endif /* sRGB */ + +#ifdef PNG_iCCP_SUPPORTED +PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, + png_colorspacerp colorspace, png_const_charp name, + png_uint_32 profile_length, png_const_bytep profile, int color_type), + PNG_EMPTY); + /* The 'name' is used for information only */ + +/* Routines for checking parts of an ICC profile. */ +PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, + png_colorspacerp colorspace, png_const_charp name, + png_uint_32 profile_length), PNG_EMPTY); +PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, + png_colorspacerp colorspace, png_const_charp name, + png_uint_32 profile_length, + png_const_bytep profile /* first 132 bytes only */, int color_type), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr, + png_colorspacerp colorspace, png_const_charp name, + png_uint_32 profile_length, + png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY); +#ifdef PNG_sRGB_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,( + png_const_structrp png_ptr, png_colorspacerp colorspace, + png_const_bytep profile, uLong adler), PNG_EMPTY); + /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may + * be zero to indicate that it is not available. It is used, if provided, + * as a fast check on the profile when checking to see if it is sRGB. + */ +#endif +#endif /* iCCP */ + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients, + (png_structrp png_ptr), PNG_EMPTY); + /* Set the rgb_to_gray coefficients from the colorspace Y values */ +#endif /* READ_RGB_TO_GRAY */ +#endif /* COLORSPACE */ + +/* Added at libpng version 1.4.0 */ +PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp 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),PNG_EMPTY); + +/* Added at libpng version 1.5.10 */ +#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ + defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) +PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes, + (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); +#endif + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp 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_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize, + size_t pos, png_const_charp string),PNG_EMPTY); + +/* 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_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start, + png_charp end, int format, png_alloc_size_t number),PNG_EMPTY); + +/* 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 /* Maximum 9; see pngerror.c */ + +/* 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_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p, + int number, png_const_charp string),PNG_EMPTY); + /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, + * including the trailing '\0'. + */ +PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned, + (png_warning_parameters p, int number, int format, png_alloc_size_t value), + PNG_EMPTY); + /* 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_INTERNAL_FUNCTION(void,png_warning_parameter_signed, + (png_warning_parameters p, int number, int format, png_int_32 value), + PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr, + png_warning_parameters p, png_const_charp message),PNG_EMPTY); + /* 'message' follows the X/Open approach of using @1, @2 to insert + * parameters previously supplied using the above functions. Errors in + * specifying the parameters will simply result in garbage substitutions. + */ +#endif + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +/* Application errors (new in 1.6); use these functions (declared below) for + * errors in the parameters or order of API function calls on read. The + * 'warning' should be used for an error that can be handled completely; the + * 'error' for one which can be handled safely but which may lose application + * information or settings. + * + * By default these both result in a png_error call prior to release, while in a + * released version the 'warning' is just a warning. However if the application + * explicitly disables benign errors (explicitly permitting the code to lose + * information) they both turn into warnings. + * + * If benign errors aren't supported they end up as the corresponding base call + * (png_warning or png_error.) + */ +PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr, + png_const_charp message),PNG_EMPTY); + /* The application provided invalid parameters to an API function or called + * an API function at the wrong time, libpng can completely recover. + */ + +PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr, + png_const_charp message),PNG_EMPTY); + /* As above but libpng will ignore the call, or attempt some other partial + * recovery from the error. + */ +#else +# define png_app_warning(pp,s) png_warning(pp,s) +# define png_app_error(pp,s) png_error(pp,s) +#endif + +PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr, + png_const_charp message, int error),PNG_EMPTY); + /* Report a recoverable issue in chunk data. On read this is used to report + * a problem found while reading a particular chunk and the + * png_chunk_benign_error or png_chunk_warning function is used as + * appropriate. On write this is used to report an error that comes from + * data set via an application call to a png_set_ API and png_app_error or + * png_app_warning is used as appropriate. + * + * The 'error' parameter must have one of the following values: + */ +#define PNG_CHUNK_WARNING 0 /* never an error */ +#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */ +#define PNG_CHUNK_ERROR 2 /* always an error */ + +/* ASCII to FP interfaces, currently only implemented if sCAL + * support is required. + */ +#if defined(PNG_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 assumptions about the + * maximum ridiculous exponent. + */ +#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) + +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr, + png_charp ascii, png_size_t size, double fp, unsigned int precision), + PNG_EMPTY); +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, + png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY); +#endif /* FIXED_POINT */ +#endif /* 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 numbers 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 initialized 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+ and 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_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, + png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); + +/* 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_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, + png_size_t size),PNG_EMPTY); +#endif /* pCAL || sCAL */ + +#if defined(PNG_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_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a, + png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* Same deal, but issue a warning on overflow and return 0. */ +PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn, + (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by, + png_int_32 divided_by),PNG_EMPTY); +#endif + +#ifdef PNG_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_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a), + PNG_EMPTY); + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* 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. Only required at present on read. + */ +PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a, + png_fixed_point b),PNG_EMPTY); +#endif + +/* Return true if the gamma value is significantly different from 1.0 */ +PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value), + PNG_EMPTY); +#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_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr, + unsigned int value, png_fixed_point gamma_value),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value, + png_fixed_point gamma_value),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value, + png_fixed_point gamma_value),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_build_gamma_tables,(png_structrp png_ptr, + int bit_depth),PNG_EMPTY); +#endif + +/* SIMPLIFIED READ/WRITE SUPPORT */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +/* The internal structure that png_image::opaque points to. */ +typedef struct png_control +{ + png_structp png_ptr; + png_infop info_ptr; + png_voidp error_buf; /* Always a jmp_buf at present. */ + + png_const_bytep memory; /* Memory buffer. */ + png_size_t size; /* Size of the memory buffer. */ + + unsigned int for_write :1; /* Otherwise it is a read structure */ + unsigned int owned_file :1; /* We own the file in io_ptr */ +} png_control; + +/* Return the pointer to the jmp_buf from a png_control: necessary because C + * does not reveal the type of the elements of jmp_buf. + */ +#ifdef __cplusplus +# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0]) +#else +# define png_control_jmp_buf(pc) ((pc)->error_buf) +#endif + +/* Utility to safely execute a piece of libpng code catching and logging any + * errors that might occur. Returns true on success, false on failure (either + * of the function or as a result of a png_error.) + */ +PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr, + png_const_charp error_message),PNG_NORETURN); + +#ifdef PNG_WARNINGS_SUPPORTED +PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr, + png_const_charp warning_message),PNG_EMPTY); +#else +# define png_safe_warning 0/*dummy argument*/ +#endif + +PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image, + int (*function)(png_voidp), png_voidp arg),PNG_EMPTY); + +/* Utility to log an error; this also cleans up the png_image; the function + * always returns 0 (false). + */ +PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image, + png_const_charp error_message),PNG_EMPTY); + +#ifndef PNG_SIMPLIFIED_READ_SUPPORTED +/* png_image_free is used by the write code but not exported */ +PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY); +#endif /* !SIMPLIFIED_READ */ + +#endif /* SIMPLIFIED READ/WRITE */ + +/* These are initialization functions for hardware specific PNG filter + * optimizations; list these here then select the appropriate one at compile + * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined + * the generic code is used. + */ +#ifdef PNG_FILTER_OPTIMIZATIONS +PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structrp png_ptr, + unsigned int bpp), PNG_EMPTY); + /* Just declare the optimization that will be used */ +#else + /* List *all* the possible optimizations here - this branch is required if + * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in + * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. + */ +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +#endif + +/* Maintainer: Put new private prototypes here ^ */ + +#include "pngdebug.h" + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +#endif /* PNGPRIV_H */ diff --git a/ext/native/ext/libpng17/pngread.c b/ext/native/ext/libpng17/pngread.c new file mode 100644 index 0000000000..cec1144451 --- /dev/null +++ b/ext/native/ext/libpng17/pngread.c @@ -0,0 +1,4103 @@ + +/* pngread.c - read a PNG file + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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. + */ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include "pngpriv.h" +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) +# include +#endif + +#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) +{ +#ifndef PNG_USER_MEM_SUPPORTED + png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, NULL, NULL, NULL); +#else + 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) +{ + png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); +#endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr != NULL) + { + png_ptr->mode = PNG_IS_READ_STRUCT; + + /* Added in libpng-1.6.0; this can be used to detect a read structure if + * required (it will be zero in a write structure.) + */ +# ifdef PNG_SEQUENTIAL_READ_SUPPORTED + png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; +# endif + +# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; + + /* In stable builds only warn if an application error can be completely + * handled. + */ +# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC + png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; +# endif +# endif + + /* TODO: delay this, it can be done in png_init_io (if the app doesn't + * do it itself) avoiding setting the default function if it is not + * required. + */ + 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_structrp png_ptr, png_inforp info_ptr) +{ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + int keep; +#endif + + 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; + + /* IDAT logic needs to happen here to simplify getting the two flags + * right. + */ + if (chunk_name == png_IDAT) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_chunk_error(png_ptr, "Missing PLTE before IDAT"); + + else if (png_ptr->mode & PNG_AFTER_IDAT) + png_chunk_benign_error(png_ptr, "Too many IDATs found[s]"); + + png_ptr->mode |= PNG_HAVE_IDAT; + } + + else if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + + /* This should be a binary subdivision search or a hash for + * matching the chunk name rather than a linear search. + */ + 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 ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { + png_handle_unknown(png_ptr, info_ptr, length, keep); + + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + + else if (chunk_name == png_IDAT) + { + png_ptr->idat_size = 0; /* It has been consumed */ + break; + } + } +#endif + else if (chunk_name == png_PLTE) + png_handle_PLTE(png_ptr, info_ptr, length); + + else if (chunk_name == png_IDAT) + { + png_ptr->idat_size = length; + 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, + PNG_HANDLE_CHUNK_AS_DEFAULT); + } +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +/* Optional call to update the users info_ptr structure */ +void PNGAPI +png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) +{ + png_debug(1, "in png_read_update_info"); + + if (png_ptr != NULL) + { + if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + { + 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 + } + + /* New in 1.6.0 this avoids the bug of doing the initializations twice */ + else + png_app_error(png_ptr, + "png_read_update_info/png_start_read_image: duplicate call"); + } +} + +#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_structrp png_ptr) +{ + png_debug(1, "in png_start_read_image"); + + if (png_ptr != NULL) + { + if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + png_read_start_row(png_ptr); + + /* New in 1.6.0 this avoids the bug of doing the initializations twice */ + else + png_app_error(png_ptr, + "png_start_read_image/png_read_update_info: duplicate call"); + } +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +#ifdef PNG_MNG_FEATURES_SUPPORTED +/* Undoes intrapixel differencing, + * NOTE: this is apparently only supported in the 'sequential' reader. + */ +static void +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 */ + +void PNGAPI +png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) +{ + 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"); + + /* Fill the row with IDAT data: */ + png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); + + 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: + */ + 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_structrp 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_structrp 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_structrp png_ptr, png_inforp info_ptr) +{ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + int keep; +#endif + + png_debug(1, "in png_read_end"); + + if (png_ptr == NULL) + return; + + /* If png_read_end is called in the middle of reading the rows there may + * still be pending IDAT data and an owned zstream. Deal with this here. + */ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (!png_chunk_unknown_handling(png_ptr, png_IDAT)) +#endif + png_read_finish_IDAT(png_ptr); + +#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Report invalid palette index; added at libng-1.5.10 */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max > png_ptr->num_palette) + png_benign_error(png_ptr, "Read palette index exceeding num_palette"); +#endif + + do + { + png_uint_32 length = png_read_chunk_header(png_ptr); + png_uint_32 chunk_name = png_ptr->chunk_name; + + if (chunk_name == png_IEND) + png_handle_IEND(png_ptr, info_ptr, length); + + else if (chunk_name == png_IHDR) + png_handle_IHDR(png_ptr, info_ptr, length); + + else if (info_ptr == NULL) + png_crc_finish(png_ptr, length); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { + 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(a1)"); + } + png_handle_unknown(png_ptr, info_ptr, length, keep); + 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(a2)"); + + 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, + PNG_HANDLE_CHUNK_AS_DEFAULT); + } while (!(png_ptr->mode & PNG_HAVE_IEND)); +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +/* Free all memory used in the read struct */ +static void +png_read_destroy(png_structrp png_ptr) +{ + png_debug(1, "in png_read_destroy"); + +#ifdef PNG_READ_GAMMA_SUPPORTED + png_destroy_gamma_table(png_ptr); +#endif + + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->big_prev_row); + png_free(png_ptr, png_ptr->read_buffer); + +#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 + + inflateEnd(&png_ptr->zstream); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_free(png_ptr, png_ptr->save_buffer); +#endif + +#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \ + defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + png_free(png_ptr, png_ptr->unknown_chunk.data); +#endif + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + png_free(png_ptr, png_ptr->chunk_list); +#endif + + /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error + * callbacks are still set at this point. They are required to complete the + * destruction of the png_struct itself. + */ +} + +/* 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_structrp png_ptr = NULL; + + png_debug(1, "in png_destroy_read_struct"); + + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; + + if (png_ptr == NULL) + return; + + /* libpng 1.6.0: use the API to destroy info structs to ensure consistent + * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. + * The extra was, apparently, unnecessary yet this hides memory leak bugs. + */ + png_destroy_info_struct(png_ptr, end_info_ptr_ptr); + png_destroy_info_struct(png_ptr, info_ptr_ptr); + + *png_ptr_ptr = NULL; + png_read_destroy(png_ptr); + png_destroy_png_struct(png_ptr); +} + +void PNGAPI +png_set_read_status_fn(png_structrp 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_structrp png_ptr, png_inforp info_ptr, + int transforms, + voidp params) +{ + 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/(sizeof (png_bytep))) + png_error(png_ptr, "Image is too high to process with png_read_png()"); + + /* -------------- image transformations start here ------------------- */ + /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM + * is not implemented. This will only happen in de-configured (non-default) + * libpng builds. The results can be unexpected - png_read_png may return + * short or mal-formed rows because the transform is skipped. + */ + + /* 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. + */ +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_set_scale_16(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported"); +#endif + + /* 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) +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + png_set_strip_16(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported"); +#endif + + /* Strip alpha bytes from the input data without combining with + * the background (not recommended). + */ + if (transforms & PNG_TRANSFORM_STRIP_ALPHA) +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + png_set_strip_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported"); +#endif + + /* 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) +#ifdef PNG_READ_PACK_SUPPORTED + png_set_packing(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); +#endif + + /* 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) +#ifdef PNG_READ_PACKSWAP_SUPPORTED + png_set_packswap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); +#endif + + /* 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) +#ifdef PNG_READ_EXPAND_SUPPORTED + png_set_expand(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported"); +#endif + + /* We don't handle background color or gamma transformation or quantizing. + */ + + /* Invert monochrome files to have 0 as white and 1 as black + */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) +#ifdef PNG_READ_INVERT_SUPPORTED + png_set_invert_mono(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); +#endif + + /* 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) +#ifdef PNG_READ_SHIFT_SUPPORTED + if (info_ptr->valid & PNG_INFO_sBIT) + png_set_shift(png_ptr, &info_ptr->sig_bit); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); +#endif + + /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ + if (transforms & PNG_TRANSFORM_BGR) +#ifdef PNG_READ_BGR_SUPPORTED + png_set_bgr(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); +#endif + + /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ + if (transforms & PNG_TRANSFORM_SWAP_ALPHA) +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED + png_set_swap_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); +#endif + + /* Swap bytes of 16-bit files to least significant byte first */ + if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) +#ifdef PNG_READ_SWAP_SUPPORTED + png_set_swap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); +#endif + +/* Added at libpng-1.2.41 */ + /* Invert the alpha channel from opacity to transparency */ + if (transforms & PNG_TRANSFORM_INVERT_ALPHA) +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + png_set_invert_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); +#endif + +/* Added at libpng-1.2.41 */ + /* Expand grayscale image to RGB */ + if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + png_set_gray_to_rgb(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported"); +#endif + +/* Added at libpng-1.5.4 */ + if (transforms & PNG_TRANSFORM_EXPAND_16) +#ifdef PNG_READ_EXPAND_16_SUPPORTED + png_set_expand_16(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported"); +#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_voidcast(png_bytepp, png_malloc(png_ptr, + info_ptr->height * (sizeof (png_bytep)))); + + for (iptr=0; iptrheight; iptr++) + info_ptr->row_pointers[iptr] = NULL; + + info_ptr->free_me |= PNG_FREE_ROWS; + + for (iptr = 0; iptr < info_ptr->height; iptr++) + info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, + png_malloc(png_ptr, info_ptr->rowbytes)); + } + + 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(params) +} +#endif /* PNG_INFO_IMAGE_SUPPORTED */ +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* SIMPLIFIED READ + * + * This code currently relies on the sequential reader, though it could easily + * be made to work with the progressive one. + */ +/* Arguments to png_image_finish_read: */ + +/* Encoding of PNG data (used by the color-map code) */ +# define P_NOTSET 0 /* File encoding not yet known */ +# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */ +# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ +# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ +# define P_LINEAR8 4 /* 8-bit linear: only from a file value */ + +/* Color-map processing: after libpng has run on the PNG image further + * processing may be needed to conver the data to color-map indicies. + */ +#define PNG_CMAP_NONE 0 +#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ +#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ +#define PNG_CMAP_RGB 3 /* Process RGB data */ +#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ + +/* The following document where the background is for each processing case. */ +#define PNG_CMAP_NONE_BACKGROUND 256 +#define PNG_CMAP_GA_BACKGROUND 231 +#define PNG_CMAP_TRANS_BACKGROUND 254 +#define PNG_CMAP_RGB_BACKGROUND 256 +#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 + +typedef struct +{ + /* Arguments: */ + png_imagep image; + png_voidp buffer; + png_int_32 row_stride; + png_voidp colormap; + png_const_colorp background; + /* Local variables: */ + png_voidp local_row; + png_voidp first_row; + ptrdiff_t row_bytes; /* step between rows */ + int file_encoding; /* E_ values above */ + png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */ + int colormap_processing; /* PNG_CMAP_ values above */ +} png_image_read_control; + +/* Do all the *safe* initialization - 'safe' means that png_error won't be + * called, so setting up the jmp_buf is not required. This means that anything + * called from here must *not* call png_malloc - it has to call png_malloc_warn + * instead so that control is returned safely back to this routine. + */ +static int +png_image_read_init(png_imagep image) +{ + if (image->opaque == NULL) + { + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, + png_safe_error, png_safe_warning); + + /* And set the rest of the structure to NULL to ensure that the various + * fields are consistent. + */ + memset(image, 0, (sizeof *image)); + image->version = PNG_IMAGE_VERSION; + + if (png_ptr != NULL) + { + png_infop info_ptr = png_create_info_struct(png_ptr); + + if (info_ptr != NULL) + { + png_controlp control = png_voidcast(png_controlp, + png_malloc_warn(png_ptr, (sizeof *control))); + + if (control != NULL) + { + memset(control, 0, (sizeof *control)); + + control->png_ptr = png_ptr; + control->info_ptr = info_ptr; + control->for_write = 0; + + image->opaque = control; + return 1; + } + + /* Error clean up */ + png_destroy_info_struct(png_ptr, &info_ptr); + } + + png_destroy_read_struct(&png_ptr, NULL, NULL); + } + + return png_image_error(image, "png_image_read: out of memory"); + } + + return png_image_error(image, "png_image_read: opaque pointer not NULL"); +} + +/* Utility to find the base format of a PNG file from a png_struct. */ +static png_uint_32 +png_image_format(png_structrp png_ptr) +{ + png_uint_32 format = 0; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + format |= PNG_FORMAT_FLAG_COLOR; + + if (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) + format |= PNG_FORMAT_FLAG_ALPHA; + + /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS + * sets the png_struct fields; that's all we are interested in here. The + * precise interaction with an app call to png_set_tRNS and PNG file reading + * is unclear. + */ + else if (png_ptr->num_trans > 0) + format |= PNG_FORMAT_FLAG_ALPHA; + + if (png_ptr->bit_depth == 16) + format |= PNG_FORMAT_FLAG_LINEAR; + + if (png_ptr->color_type & PNG_COLOR_MASK_PALETTE) + format |= PNG_FORMAT_FLAG_COLORMAP; + + return format; +} + +/* Is the given gamma significantly different from sRGB? The test is the same + * one used in pngrtran.c when deciding whether to do gamma correction. The + * arithmetic optimizes the division by using the fact that the inverse of the + * file sRGB gamma is 2.2 + */ +static int +png_gamma_not_sRGB(png_fixed_point g) +{ + if (g < PNG_FP_1) + { + /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ + if (g == 0) + return 0; + + return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); + } + + return 1; +} + +/* Do the main body of a 'png_image_begin_read' function; read the PNG file + * header and fill in all the information. This is executed in a safe context, + * unlike the init routine above. + */ +static int +png_image_read_header(png_voidp argument) +{ + png_imagep image = png_voidcast(png_imagep, argument); + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + + png_set_benign_errors(png_ptr, 1/*warn*/); + png_read_info(png_ptr, info_ptr); + + /* Do this the fast way; just read directly out of png_struct. */ + image->width = png_ptr->width; + image->height = png_ptr->height; + + { + png_uint_32 format = png_image_format(png_ptr); + + image->format = format; + +#ifdef PNG_COLORSPACE_SUPPORTED + /* Does the colorspace match sRGB? If there is no color endpoint + * (colorant) information assume yes, otherwise require the + * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the + * colorspace has been determined to be invalid ignore it. + */ + if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags + & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| + PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) + image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; +#endif + } + + /* We need the maximum number of entries regardless of the format the + * application sets here. + */ + { + png_uint_32 cmap_entries; + + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_GRAY: + cmap_entries = 1U << png_ptr->bit_depth; + break; + + case PNG_COLOR_TYPE_PALETTE: + cmap_entries = png_ptr->num_palette; + break; + + default: + cmap_entries = 256; + break; + } + + if (cmap_entries > 256) + cmap_entries = 256; + + image->colormap_entries = cmap_entries; + } + + return 1; +} + +#ifdef PNG_STDIO_SUPPORTED +int PNGAPI +png_image_begin_read_from_stdio(png_imagep image, FILE* file) +{ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file != NULL) + { + if (png_image_read_init(image)) + { + /* This is slightly evil, but png_init_io doesn't do anything other + * than this and we haven't changed the standard IO functions so + * this saves a 'safe' function. + */ + image->opaque->png_ptr->io_ptr = file; + return png_safe_execute(image, png_image_read_header, image); + } + } + + else + return png_image_error(image, + "png_image_begin_read_from_stdio: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); + + return 0; +} + +int PNGAPI +png_image_begin_read_from_file(png_imagep image, const char *file_name) +{ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file_name != NULL) + { + FILE *fp = fopen(file_name, "rb"); + + if (fp != NULL) + { + if (png_image_read_init(image)) + { + image->opaque->png_ptr->io_ptr = fp; + image->opaque->owned_file = 1; + return png_safe_execute(image, png_image_read_header, image); + } + + /* Clean up: just the opened file. */ + (void)fclose(fp); + } + + else + return png_image_error(image, strerror(errno)); + } + + else + return png_image_error(image, + "png_image_begin_read_from_file: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); + + return 0; +} +#endif /* PNG_STDIO_SUPPORTED */ + +static void PNGCBAPI +png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) +{ + if (png_ptr != NULL) + { + png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); + if (image != NULL) + { + png_controlp cp = image->opaque; + if (cp != NULL) + { + png_const_bytep memory = cp->memory; + png_size_t size = cp->size; + + if (memory != NULL && size >= need) + { + memcpy(out, memory, need); + cp->memory = memory + need; + cp->size = size - need; + return; + } + + png_error(png_ptr, "read beyond end of data"); + } + } + + png_error(png_ptr, "invalid memory read"); + } +} + +int PNGAPI png_image_begin_read_from_memory(png_imagep image, + png_const_voidp memory, png_size_t size) +{ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (memory != NULL && size > 0) + { + if (png_image_read_init(image)) + { + /* Now set the IO functions to read from the memory buffer and + * store it into io_ptr. Again do this in-place to avoid calling a + * libpng function that requires error handling. + */ + image->opaque->memory = png_voidcast(png_const_bytep, memory); + image->opaque->size = size; + image->opaque->png_ptr->io_ptr = image; + image->opaque->png_ptr->read_data_fn = png_image_memory_read; + + return png_safe_execute(image, png_image_read_header, image); + } + } + + else + return png_image_error(image, + "png_image_begin_read_from_memory: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); + + return 0; +} + +/* Utility function to skip chunks that are not used by the simplified image + * read functions and an appropriate macro to call it. + */ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +static void +png_image_skip_unused_chunks(png_structrp png_ptr) +{ + /* Prepare the reader to ignore all recognized chunks whose data will not + * be used, i.e., all chunks recognized by libpng except for those + * involved in basic image reading: + * + * IHDR, PLTE, IDAT, IEND + * + * Or image data handling: + * + * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT. + * + * This provides a small performance improvement and eliminates any + * potential vulnerability to security problems in the unused chunks. + * + * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored + * too. This allows the simplified API to be compiled without iCCP support, + * however if the support is there the chunk is still checked to detect + * errors (which are unfortunately quite common.) + */ + { + static PNG_CONST png_byte chunks_to_process[] = { + 98, 75, 71, 68, '\0', /* bKGD */ + 99, 72, 82, 77, '\0', /* cHRM */ + 103, 65, 77, 65, '\0', /* gAMA */ +# ifdef PNG_READ_iCCP_SUPPORTED + 105, 67, 67, 80, '\0', /* iCCP */ +# endif + 115, 66, 73, 84, '\0', /* sBIT */ + 115, 82, 71, 66, '\0', /* sRGB */ + }; + + /* Ignore unknown chunks and all other chunks except for the + * IHDR, PLTE, tRNS, IDAT, and IEND chunks. + */ + png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, + NULL, -1); + + /* But do not ignore image data handling chunks */ + png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, + chunks_to_process, (sizeof chunks_to_process)/5); + } +} + +# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) +#else +# define PNG_SKIP_CHUNKS(p) ((void)0) +#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */ + +/* The following macro gives the exact rounded answer for all values in the + * range 0..255 (it actually divides by 51.2, but the rounding still generates + * the correct numbers 0..5 + */ +#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) + +/* Utility functions to make particular color-maps */ +static void +set_file_encoding(png_image_read_control *display) +{ + png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; + if (png_gamma_significant(g)) + { + if (png_gamma_not_sRGB(g)) + { + display->file_encoding = P_FILE; + display->gamma_to_linear = png_reciprocal(g); + } + + else + display->file_encoding = P_sRGB; + } + + else + display->file_encoding = P_LINEAR8; +} + +static unsigned int +decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) +{ + if (encoding == P_FILE) /* double check */ + encoding = display->file_encoding; + + if (encoding == P_NOTSET) /* must be the file encoding */ + { + set_file_encoding(display); + encoding = display->file_encoding; + } + + switch (encoding) + { + case P_FILE: + value = png_gamma_16bit_correct(value*257, display->gamma_to_linear); + break; + + case P_sRGB: + value = png_sRGB_table[value]; + break; + + case P_LINEAR: + break; + + case P_LINEAR8: + value *= 257; + break; + + default: + png_error(display->image->opaque->png_ptr, + "unexpected encoding (internal error)"); + break; + } + + return value; +} + +static png_uint_32 +png_colormap_compose(png_image_read_control *display, + png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, + png_uint_32 background, int encoding) +{ + /* The file value is composed on the background, the background has the given + * encoding and so does the result, the file is encoded with P_FILE and the + * file and alpha are 8-bit values. The (output) encoding will always be + * P_LINEAR or P_sRGB. + */ + png_uint_32 f = decode_gamma(display, foreground, foreground_encoding); + png_uint_32 b = decode_gamma(display, background, encoding); + + /* The alpha is always an 8-bit value (it comes from the palette), the value + * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. + */ + f = f * alpha + b * (255-alpha); + + if (encoding == P_LINEAR) + { + /* Scale to 65535; divide by 255, approximately (in fact this is extremely + * accurate, it divides by 255.00000005937181414556, with no overflow.) + */ + f *= 257; /* Now scaled by 65535 */ + f += f >> 16; + f = (f+32768) >> 16; + } + + else /* P_sRGB */ + f = PNG_sRGB_FROM_LINEAR(f); + + return f; +} + +/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must + * be 8-bit. + */ +static void +png_create_colormap_entry(png_image_read_control *display, + png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, + png_uint_32 alpha, int encoding) +{ + png_imagep image = display->image; + const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) ? + P_LINEAR : P_sRGB; + const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && + (red != green || green != blue); + + if (ip > 255) + png_error(image->opaque->png_ptr, "color-map index out of range"); + + /* Update the cache with whether the file gamma is significantly different + * from sRGB. + */ + if (encoding == P_FILE) + { + if (display->file_encoding == P_NOTSET) + set_file_encoding(display); + + /* Note that the cached value may be P_FILE too, but if it is then the + * gamma_to_linear member has been set. + */ + encoding = display->file_encoding; + } + + if (encoding == P_FILE) + { + png_fixed_point g = display->gamma_to_linear; + + red = png_gamma_16bit_correct(red*257, g); + green = png_gamma_16bit_correct(green*257, g); + blue = png_gamma_16bit_correct(blue*257, g); + + if (convert_to_Y || output_encoding == P_LINEAR) + { + alpha *= 257; + encoding = P_LINEAR; + } + + else + { + red = PNG_sRGB_FROM_LINEAR(red * 255); + green = PNG_sRGB_FROM_LINEAR(green * 255); + blue = PNG_sRGB_FROM_LINEAR(blue * 255); + encoding = P_sRGB; + } + } + + else if (encoding == P_LINEAR8) + { + /* This encoding occurs quite frequently in test cases because PngSuite + * includes a gAMA 1.0 chunk with most images. + */ + red *= 257; + green *= 257; + blue *= 257; + alpha *= 257; + encoding = P_LINEAR; + } + + else if (encoding == P_sRGB && (convert_to_Y || output_encoding == P_LINEAR)) + { + /* The values are 8-bit sRGB values, but must be converted to 16-bit + * linear. + */ + red = png_sRGB_table[red]; + green = png_sRGB_table[green]; + blue = png_sRGB_table[blue]; + alpha *= 257; + encoding = P_LINEAR; + } + + /* This is set if the color isn't gray but the output is. */ + if (encoding == P_LINEAR) + { + if (convert_to_Y != 0) + { + /* NOTE: these values are copied from png_do_rgb_to_gray */ + png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green + + (png_uint_32)2366 * blue; + + if (output_encoding == P_LINEAR) + y = (y + 16384) >> 15; + + else + { + /* y is scaled by 32768, we need it scaled by 255: */ + y = (y + 128) >> 8; + y *= 255; + y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7); + encoding = P_sRGB; + } + + blue = red = green = y; + } + + else if (output_encoding == P_sRGB) + { + red = PNG_sRGB_FROM_LINEAR(red * 255); + green = PNG_sRGB_FROM_LINEAR(green * 255); + blue = PNG_sRGB_FROM_LINEAR(blue * 255); + alpha = PNG_DIV257(alpha); + encoding = P_sRGB; + } + } + + if (encoding != output_encoding) + png_error(image->opaque->png_ptr, "bad encoding (internal error)"); + + /* Store the value. */ + { +# ifdef PNG_FORMAT_AFIRST_SUPPORTED + const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && + (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; +# else +# define afirst 0 +# endif +# ifdef PNG_FORMAT_BGR_SUPPORTED + const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) ? 2 : 0; +# else +# define bgr 0 +# endif + + if (output_encoding == P_LINEAR) + { + png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); + + entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); + + /* The linear 16-bit values must be pre-multiplied by the alpha channel + * value, if less than 65535 (this is, effectively, composite on black + * if the alpha channel is removed.) + */ + switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) + { + case 4: + entry[afirst ? 0 : 3] = (png_uint_16)alpha; + /* FALL THROUGH */ + + case 3: + if (alpha < 65535) + { + if (alpha > 0) + { + blue = (blue * alpha + 32767U)/65535U; + green = (green * alpha + 32767U)/65535U; + red = (red * alpha + 32767U)/65535U; + } + + else + red = green = blue = 0; + } + entry[afirst + (2 ^ bgr)] = (png_uint_16)blue; + entry[afirst + 1] = (png_uint_16)green; + entry[afirst + bgr] = (png_uint_16)red; + break; + + case 2: + entry[1 ^ afirst] = (png_uint_16)alpha; + /* FALL THROUGH */ + + case 1: + if (alpha < 65535) + { + if (alpha > 0) + green = (green * alpha + 32767U)/65535U; + + else + green = 0; + } + entry[afirst] = (png_uint_16)green; + break; + + default: + break; + } + } + + else /* output encoding is P_sRGB */ + { + png_bytep entry = png_voidcast(png_bytep, display->colormap); + + entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); + + switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) + { + case 4: + entry[afirst ? 0 : 3] = (png_byte)alpha; + case 3: + entry[afirst + (2 ^ bgr)] = (png_byte)blue; + entry[afirst + 1] = (png_byte)green; + entry[afirst + bgr] = (png_byte)red; + break; + + case 2: + entry[1 ^ afirst] = (png_byte)alpha; + case 1: + entry[afirst] = (png_byte)green; + break; + + default: + break; + } + } + +# ifdef afirst +# undef afirst +# endif +# ifdef bgr +# undef bgr +# endif + } +} + +static int +make_gray_file_colormap(png_image_read_control *display) +{ + unsigned int i; + + for (i=0; i<256; ++i) + png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); + + return i; +} + +static int +make_gray_colormap(png_image_read_control *display) +{ + unsigned int i; + + for (i=0; i<256; ++i) + png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); + + return i; +} +#define PNG_GRAY_COLORMAP_ENTRIES 256 + +static int +make_ga_colormap(png_image_read_control *display) +{ + unsigned int i, a; + + /* Alpha is retained, the output will be a color-map with entries + * selected by six levels of alpha. One transparent entry, 6 gray + * levels for all the intermediate alpha values, leaving 230 entries + * for the opaque grays. The color-map entries are the six values + * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the + * relevant entry. + * + * if (alpha > 229) // opaque + * { + * // The 231 entries are selected to make the math below work: + * base = 0; + * entry = (231 * gray + 128) >> 8; + * } + * else if (alpha < 26) // transparent + * { + * base = 231; + * entry = 0; + * } + * else // partially opaque + * { + * base = 226 + 6 * PNG_DIV51(alpha); + * entry = PNG_DIV51(gray); + * } + */ + i = 0; + while (i < 231) + { + unsigned int gray = (i * 256 + 115) / 231; + png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB); + } + + /* 255 is used here for the component values for consistency with the code + * that undoes premultiplication in pngwrite.c. + */ + png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB); + + for (a=1; a<5; ++a) + { + unsigned int g; + + for (g=0; g<6; ++g) + png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, + P_sRGB); + } + + return i; +} + +#define PNG_GA_COLORMAP_ENTRIES 256 + +static int +make_rgb_colormap(png_image_read_control *display) +{ + unsigned int i, r; + + /* Build a 6x6x6 opaque RGB cube */ + for (i=r=0; r<6; ++r) + { + unsigned int g; + + for (g=0; g<6; ++g) + { + unsigned int b; + + for (b=0; b<6; ++b) + png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, + P_sRGB); + } + } + + return i; +} + +#define PNG_RGB_COLORMAP_ENTRIES 216 + +/* Return a palette index to the above palette given three 8-bit sRGB values. */ +#define PNG_RGB_INDEX(r,g,b) \ + ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) + +static int +png_image_read_colormap(png_voidp argument) +{ + png_image_read_control *display = + png_voidcast(png_image_read_control*, argument); + const png_imagep image = display->image; + + const png_structrp png_ptr = image->opaque->png_ptr; + const png_uint_32 output_format = image->format; + const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) ? + P_LINEAR : P_sRGB; + + unsigned int cmap_entries; + unsigned int output_processing; /* Output processing option */ + unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */ + + /* Background information; the background color and the index of this color + * in the color-map if it exists (else 256). + */ + unsigned int background_index = 256; + png_uint_32 back_r, back_g, back_b; + + /* Flags to accumulate things that need to be done to the input. */ + int expand_tRNS = 0; + + /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is + * very difficult to do, the results look awful, and it is difficult to see + * what possible use it is because the application can't control the + * color-map. + */ + if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || + png_ptr->num_trans > 0) /* alpha in input */ && + ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) + { + if (output_encoding == P_LINEAR) /* compose on black */ + back_b = back_g = back_r = 0; + + else if (display->background == NULL /* no way to remove it */) + png_error(png_ptr, + "a background color must be supplied to remove alpha/transparency"); + + /* Get a copy of the background color (this avoids repeating the checks + * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the + * output format. + */ + else + { + back_g = display->background->green; + if (output_format & PNG_FORMAT_FLAG_COLOR) + { + back_r = display->background->red; + back_b = display->background->blue; + } + else + back_b = back_r = back_g; + } + } + + else if (output_encoding == P_LINEAR) + back_b = back_r = back_g = 65535; + + else + back_b = back_r = back_g = 255; + + /* Default the input file gamma if required - this is necessary because + * libpng assumes that if no gamma information is present the data is in the + * output format, but the simplified API deduces the gamma from the input + * format. + */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) + { + /* Do this directly, not using the png_colorspace functions, to ensure + * that it happens even if the colorspace is invalid (though probably if + * it is the setting will be ignored) Note that the same thing can be + * achieved at the application interface with png_set_gAMA. + */ + if (png_ptr->bit_depth == 16 && + (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) + png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; + + else + png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; + + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + } + + /* Decide what to do based on the PNG color type of the input data. The + * utility function png_create_colormap_entry deals with most aspects of the + * output transformations; this code works out how to produce bytes of + * color-map entries from the original format. + */ + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_GRAY: + if (png_ptr->bit_depth <= 8) + { + /* There at most 256 colors in the output, regardless of + * transparency. + */ + unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; + + cmap_entries = 1U << png_ptr->bit_depth; + if (cmap_entries > image->colormap_entries) + png_error(png_ptr, "gray[8] color-map: too few entries"); + + step = 255 / (cmap_entries - 1); + output_processing = PNG_CMAP_NONE; + + /* If there is a tRNS chunk then this either selects a transparent + * value or, if the output has no alpha, the background color. + */ + if (png_ptr->num_trans > 0) + { + trans = png_ptr->trans_color.gray; + + if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) + back_alpha = output_encoding == P_LINEAR ? 65535 : 255; + } + + /* png_create_colormap_entry just takes an RGBA and writes the + * corresponding color-map entry using the format from 'image', + * including the required conversion to sRGB or linear as + * appropriate. The input values are always either sRGB (if the + * gamma correction flag is 0) or 0..255 scaled file encoded values + * (if the function must gamma correct them). + */ + for (i=val=0; ibit_depth < 8) + png_set_packing(png_ptr); + } + + else /* bit depth is 16 */ + { + /* The 16-bit input values can be converted directly to 8-bit gamma + * encoded values; however, if a tRNS chunk is present 257 color-map + * entries are required. This means that the extra entry requires + * special processing; add an alpha channel, sacrifice gray level + * 254 and convert transparent (alpha==0) entries to that. + * + * Use libpng to chop the data to 8 bits. Convert it to sRGB at the + * same time to minimize quality loss. If a tRNS chunk is present + * this means libpng must handle it too; otherwise it is impossible + * to do the exact match on the 16-bit value. + * + * If the output has no alpha channel *and* the background color is + * gray then it is possible to let libpng handle the substitution by + * ensuring that the corresponding gray level matches the background + * color exactly. + */ + data_encoding = P_sRGB; + + if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "gray[16] color-map: too few entries"); + + cmap_entries = make_gray_colormap(display); + + if (png_ptr->num_trans > 0) + { + unsigned int back_alpha; + + if (output_format & PNG_FORMAT_FLAG_ALPHA) + back_alpha = 0; + + else + { + if (back_r == back_g && back_g == back_b) + { + /* Background is gray; no special processing will be + * required. + */ + png_color_16 c; + png_uint_32 gray = back_g; + + if (output_encoding == P_LINEAR) + { + gray = PNG_sRGB_FROM_LINEAR(gray * 255); + + /* And make sure the corresponding palette entry + * matches. + */ + png_create_colormap_entry(display, gray, back_g, back_g, + back_g, 65535, P_LINEAR); + } + + /* The background passed to libpng, however, must be the + * sRGB value. + */ + c.index = 0; /*unused*/ + c.gray = c.red = c.green = c.blue = (png_uint_16)gray; + + /* NOTE: does this work without expanding tRNS to alpha? + * It should be the color->gray case below apparently + * doesn't. + */ + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + + output_processing = PNG_CMAP_NONE; + break; + } + + back_alpha = output_encoding == P_LINEAR ? 65535 : 255; + } + + /* output_processing means that the libpng-processed row will be + * 8-bit GA and it has to be processing to single byte color-map + * values. Entry 254 is replaced by either a completely + * transparent entry or by the background color at full + * precision (and the background color is not a simple gray leve + * in this case.) + */ + expand_tRNS = 1; + output_processing = PNG_CMAP_TRANS; + background_index = 254; + + /* And set (overwrite) color-map entry 254 to the actual + * background color at full precision. + */ + png_create_colormap_entry(display, 254, back_r, back_g, back_b, + back_alpha, output_encoding); + } + + else + output_processing = PNG_CMAP_NONE; + } + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum + * of 65536 combinations. If, however, the alpha channel is to be + * removed there are only 256 possibilities if the background is gray. + * (Otherwise there is a subset of the 65536 possibilities defined by + * the triangle between black, white and the background color.) + * + * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to + * worry about tRNS matching - tRNS is ignored if there is an alpha + * channel. + */ + data_encoding = P_sRGB; + + if (output_format & PNG_FORMAT_FLAG_ALPHA) + { + if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "gray+alpha color-map: too few entries"); + + cmap_entries = make_ga_colormap(display); + + background_index = PNG_CMAP_GA_BACKGROUND; + output_processing = PNG_CMAP_GA; + } + + else /* alpha is removed */ + { + /* Alpha must be removed as the PNG data is processed when the + * background is a color because the G and A channels are + * independent and the vector addition (non-parallel vectors) is a + * 2-D problem. + * + * This can be reduced to the same algorithm as above by making a + * colormap containing gray levels (for the opaque grays), a + * background entry (for a transparent pixel) and a set of four six + * level color values, one set for each intermediate alpha value. + * See the comments in make_ga_colormap for how this works in the + * per-pixel processing. + * + * If the background is gray, however, we only need a 256 entry gray + * level color map. It is sufficient to make the entry generated + * for the background color be exactly the color specified. + */ + if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || + (back_r == back_g && back_g == back_b)) + { + /* Background is gray; no special processing will be required. */ + png_color_16 c; + png_uint_32 gray = back_g; + + if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "gray-alpha color-map: too few entries"); + + cmap_entries = make_gray_colormap(display); + + if (output_encoding == P_LINEAR) + { + gray = PNG_sRGB_FROM_LINEAR(gray * 255); + + /* And make sure the corresponding palette entry matches. */ + png_create_colormap_entry(display, gray, back_g, back_g, + back_g, 65535, P_LINEAR); + } + + /* The background passed to libpng, however, must be the sRGB + * value. + */ + c.index = 0; /*unused*/ + c.gray = c.red = c.green = c.blue = (png_uint_16)gray; + + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + + output_processing = PNG_CMAP_NONE; + } + + else + { + png_uint_32 i, a; + + /* This is the same as png_make_ga_colormap, above, except that + * the entries are all opaque. + */ + if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "ga-alpha color-map: too few entries"); + + i = 0; + while (i < 231) + { + png_uint_32 gray = (i * 256 + 115) / 231; + png_create_colormap_entry(display, i++, gray, gray, gray, + 255, P_sRGB); + } + + /* NOTE: this preserves the full precision of the application + * background color. + */ + background_index = i; + png_create_colormap_entry(display, i++, back_r, back_g, back_b, + output_encoding == P_LINEAR ? 65535U : 255U, output_encoding); + + /* For non-opaque input composite on the sRGB background - this + * requires inverting the encoding for each component. The input + * is still converted to the sRGB encoding because this is a + * reasonable approximate to the logarithmic curve of human + * visual sensitivity, at least over the narrow range which PNG + * represents. Consequently 'G' is always sRGB encoded, while + * 'A' is linear. We need the linear background colors. + */ + if (output_encoding == P_sRGB) /* else already linear */ + { + /* This may produce a value not exactly matching the + * background, but that's ok because these numbers are only + * used when alpha != 0 + */ + back_r = png_sRGB_table[back_r]; + back_g = png_sRGB_table[back_g]; + back_b = png_sRGB_table[back_b]; + } + + for (a=1; a<5; ++a) + { + unsigned int g; + + /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled + * by an 8-bit alpha value (0..255). + */ + png_uint_32 alpha = 51 * a; + png_uint_32 back_rx = (255-alpha) * back_r; + png_uint_32 back_gx = (255-alpha) * back_g; + png_uint_32 back_bx = (255-alpha) * back_b; + + for (g=0; g<6; ++g) + { + png_uint_32 gray = png_sRGB_table[g*51] * alpha; + + png_create_colormap_entry(display, i++, + PNG_sRGB_FROM_LINEAR(gray + back_rx), + PNG_sRGB_FROM_LINEAR(gray + back_gx), + PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); + } + } + + cmap_entries = i; + output_processing = PNG_CMAP_GA; + } + } + break; + + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + /* Exclude the case where the output is gray; we can always handle this + * with the cases above. + */ + if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) + { + /* The color-map will be grayscale, so we may as well convert the + * input RGB values to a simple grayscale and use the grayscale + * code above. + * + * NOTE: calling this apparently damages the recognition of the + * transparent color in background color handling; call + * png_set_tRNS_to_alpha before png_set_background_fixed. + */ + png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, + -1); + data_encoding = P_sRGB; + + /* The output will now be one or two 8-bit gray or gray+alpha + * channels. The more complex case arises when the input has alpha. + */ + if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + png_ptr->num_trans > 0) && + (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) + { + /* Both input and output have an alpha channel, so no background + * processing is required; just map the GA bytes to the right + * color-map entry. + */ + expand_tRNS = 1; + + if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "rgb[ga] color-map: too few entries"); + + cmap_entries = make_ga_colormap(display); + background_index = PNG_CMAP_GA_BACKGROUND; + output_processing = PNG_CMAP_GA; + } + + else + { + /* Either the input or the output has no alpha channel, so there + * will be no non-opaque pixels in the color-map; it will just be + * grayscale. + */ + if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "rgb[gray] color-map: too few entries"); + + /* Ideally this code would use libpng to do the gamma correction, + * but if an input alpha channel is to be removed we will hit the + * libpng bug in gamma+compose+rgb-to-gray (the double gamma + * correction bug). Fix this by dropping the gamma correction in + * this case and doing it in the palette; this will result in + * duplicate palette entries, but that's better than the + * alternative of double gamma correction. + */ + if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + png_ptr->num_trans > 0) && + png_gamma_not_sRGB(png_ptr->colorspace.gamma)) + { + cmap_entries = make_gray_file_colormap(display); + data_encoding = P_FILE; + } + + else + cmap_entries = make_gray_colormap(display); + + /* But if the input has alpha or transparency it must be removed + */ + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + png_ptr->num_trans > 0) + { + png_color_16 c; + png_uint_32 gray = back_g; + + /* We need to ensure that the application background exists in + * the colormap and that completely transparent pixels map to + * it. Achieve this simply by ensuring that the entry + * selected for the background really is the background color. + */ + if (data_encoding == P_FILE) /* from the fixup above */ + { + /* The app supplied a gray which is in output_encoding, we + * need to convert it to a value of the input (P_FILE) + * encoding then set this palette entry to the required + * output encoding. + */ + if (output_encoding == P_sRGB) + gray = png_sRGB_table[gray]; /* now P_LINEAR */ + + gray = PNG_DIV257(png_gamma_16bit_correct(gray, + png_ptr->colorspace.gamma)); /* now P_FILE */ + + /* And make sure the corresponding palette entry contains + * exactly the required sRGB value. + */ + png_create_colormap_entry(display, gray, back_g, back_g, + back_g, 0/*unused*/, output_encoding); + } + + else if (output_encoding == P_LINEAR) + { + gray = PNG_sRGB_FROM_LINEAR(gray * 255); + + /* And make sure the corresponding palette entry matches. + */ + png_create_colormap_entry(display, gray, back_g, back_g, + back_g, 0/*unused*/, P_LINEAR); + } + + /* The background passed to libpng, however, must be the + * output (normally sRGB) value. + */ + c.index = 0; /*unused*/ + c.gray = c.red = c.green = c.blue = (png_uint_16)gray; + + /* NOTE: the following is apparently a bug in libpng. Without + * it the transparent color recognition in + * png_set_background_fixed seems to go wrong. + */ + expand_tRNS = 1; + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + } + + output_processing = PNG_CMAP_NONE; + } + } + + else /* output is color */ + { + /* We could use png_quantize here so long as there is no transparent + * color or alpha; png_quantize ignores alpha. Easier overall just + * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. + * Consequently we always want libpng to produce sRGB data. + */ + data_encoding = P_sRGB; + + /* Is there any transparency or alpha? */ + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + png_ptr->num_trans > 0) + { + /* Is there alpha in the output too? If so all four channels are + * processed into a special RGB cube with alpha support. + */ + if (output_format & PNG_FORMAT_FLAG_ALPHA) + { + png_uint_32 r; + + if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) + png_error(png_ptr, "rgb+alpha color-map: too few entries"); + + cmap_entries = make_rgb_colormap(display); + + /* Add a transparent entry. */ + png_create_colormap_entry(display, cmap_entries, 255, 255, + 255, 0, P_sRGB); + + /* This is stored as the background index for the processing + * algorithm. + */ + background_index = cmap_entries++; + + /* Add 27 r,g,b entries each with alpha 0.5. */ + for (r=0; r<256; r = (r << 1) | 0x7f) + { + png_uint_32 g; + + for (g=0; g<256; g = (g << 1) | 0x7f) + { + png_uint_32 b; + + /* This generates components with the values 0, 127 and + * 255 + */ + for (b=0; b<256; b = (b << 1) | 0x7f) + png_create_colormap_entry(display, cmap_entries++, + r, g, b, 128, P_sRGB); + } + } + + expand_tRNS = 1; + output_processing = PNG_CMAP_RGB_ALPHA; + } + + else + { + /* Alpha/transparency must be removed. The background must + * exist in the color map (achieved by setting adding it after + * the 666 color-map). If the standard processing code will + * pick up this entry automatically that's all that is + * required; libpng can be called to do the background + * processing. + */ + unsigned int sample_size = + PNG_IMAGE_SAMPLE_SIZE(output_format); + png_uint_32 r, g, b; /* sRGB background */ + + if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) + png_error(png_ptr, "rgb-alpha color-map: too few entries"); + + cmap_entries = make_rgb_colormap(display); + + png_create_colormap_entry(display, cmap_entries, back_r, + back_g, back_b, 0/*unused*/, output_encoding); + + if (output_encoding == P_LINEAR) + { + r = PNG_sRGB_FROM_LINEAR(back_r * 255); + g = PNG_sRGB_FROM_LINEAR(back_g * 255); + b = PNG_sRGB_FROM_LINEAR(back_b * 255); + } + + else + { + r = back_r; + g = back_g; + b = back_g; + } + + /* Compare the newly-created color-map entry with the one the + * PNG_CMAP_RGB algorithm will use. If the two entries don't + * match, add the new one and set this as the background + * index. + */ + if (memcmp((png_const_bytep)display->colormap + + sample_size * cmap_entries, + (png_const_bytep)display->colormap + + sample_size * PNG_RGB_INDEX(r,g,b), + sample_size) != 0) + { + /* The background color must be added. */ + background_index = cmap_entries++; + + /* Add 27 r,g,b entries each with created by composing with + * the background at alpha 0.5. + */ + for (r=0; r<256; r = (r << 1) | 0x7f) + { + for (g=0; g<256; g = (g << 1) | 0x7f) + { + /* This generates components with the values 0, 127 + * and 255 + */ + for (b=0; b<256; b = (b << 1) | 0x7f) + png_create_colormap_entry(display, cmap_entries++, + png_colormap_compose(display, r, P_sRGB, 128, + back_r, output_encoding), + png_colormap_compose(display, g, P_sRGB, 128, + back_g, output_encoding), + png_colormap_compose(display, b, P_sRGB, 128, + back_b, output_encoding), + 0/*unused*/, output_encoding); + } + } + + expand_tRNS = 1; + output_processing = PNG_CMAP_RGB_ALPHA; + } + + else /* background color is in the standard color-map */ + { + png_color_16 c; + + c.index = 0; /*unused*/ + c.red = (png_uint_16)back_r; + c.gray = c.green = (png_uint_16)back_g; + c.blue = (png_uint_16)back_b; + + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + + output_processing = PNG_CMAP_RGB; + } + } + } + + else /* no alpha or transparency in the input */ + { + /* Alpha in the output is irrelevant, simply map the opaque input + * pixels to the 6x6x6 color-map. + */ + if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "rgb color-map: too few entries"); + + cmap_entries = make_rgb_colormap(display); + output_processing = PNG_CMAP_RGB; + } + } + break; + + case PNG_COLOR_TYPE_PALETTE: + /* It's already got a color-map. It may be necessary to eliminate the + * tRNS entries though. + */ + { + unsigned int num_trans = png_ptr->num_trans; + png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; + png_const_colorp colormap = png_ptr->palette; + const int do_background = trans != NULL && + (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; + unsigned int i; + + /* Just in case: */ + if (trans == NULL) + num_trans = 0; + + output_processing = PNG_CMAP_NONE; + data_encoding = P_FILE; /* Don't change from color-map indicies */ + cmap_entries = png_ptr->num_palette; + if (cmap_entries > 256) + cmap_entries = 256; + + if (cmap_entries > image->colormap_entries) + png_error(png_ptr, "palette color-map: too few entries"); + + for (i=0; i < cmap_entries; ++i) + { + if (do_background && i < num_trans && trans[i] < 255) + { + if (trans[i] == 0) + png_create_colormap_entry(display, i, back_r, back_g, + back_b, 0, output_encoding); + + else + { + /* Must compose the PNG file color in the color-map entry + * on the sRGB color in 'back'. + */ + png_create_colormap_entry(display, i, + png_colormap_compose(display, colormap[i].red, P_FILE, + trans[i], back_r, output_encoding), + png_colormap_compose(display, colormap[i].green, P_FILE, + trans[i], back_g, output_encoding), + png_colormap_compose(display, colormap[i].blue, P_FILE, + trans[i], back_b, output_encoding), + output_encoding == P_LINEAR ? trans[i] * 257U : + trans[i], + output_encoding); + } + } + + else + png_create_colormap_entry(display, i, colormap[i].red, + colormap[i].green, colormap[i].blue, + i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); + } + + /* The PNG data may have indicies packed in fewer than 8 bits, it + * must be expanded if so. + */ + if (png_ptr->bit_depth < 8) + png_set_packing(png_ptr); + } + break; + + default: + png_error(png_ptr, "invalid PNG color type"); + /*NOT REACHED*/ + break; + } + + /* Now deal with the output processing */ + if (expand_tRNS && png_ptr->num_trans > 0 && + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) + png_set_tRNS_to_alpha(png_ptr); + + switch (data_encoding) + { + default: + png_error(png_ptr, "bad data option (internal error)"); + break; + + case P_sRGB: + /* Change to 8-bit sRGB */ + png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); + /* FALL THROUGH */ + + case P_FILE: + if (png_ptr->bit_depth > 8) + png_set_scale_16(png_ptr); + break; + } + + if (cmap_entries > 256 || cmap_entries > image->colormap_entries) + png_error(png_ptr, "color map overflow (BAD internal error)"); + + image->colormap_entries = cmap_entries; + + /* Double check using the recorded background index */ + switch (output_processing) + { + case PNG_CMAP_NONE: + if (background_index != PNG_CMAP_NONE_BACKGROUND) + goto bad_background; + break; + + case PNG_CMAP_GA: + if (background_index != PNG_CMAP_GA_BACKGROUND) + goto bad_background; + break; + + case PNG_CMAP_TRANS: + if (background_index >= cmap_entries || + background_index != PNG_CMAP_TRANS_BACKGROUND) + goto bad_background; + break; + + case PNG_CMAP_RGB: + if (background_index != PNG_CMAP_RGB_BACKGROUND) + goto bad_background; + break; + + case PNG_CMAP_RGB_ALPHA: + if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) + goto bad_background; + break; + + default: + png_error(png_ptr, "bad processing option (internal error)"); + + bad_background: + png_error(png_ptr, "bad background index (internal error)"); + } + + display->colormap_processing = output_processing; + + return 1/*ok*/; +} + +/* The final part of the color-map read called from png_image_finish_read. */ +static int +png_image_read_and_map(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + int passes; + + /* Called when the libpng data must be transformed into the color-mapped + * form. There is a local row buffer in display->local and this routine must + * do the interlace handling. + */ + switch (png_ptr->interlaced) + { + case PNG_INTERLACE_NONE: + passes = 1; + break; + + case PNG_INTERLACE_ADAM7: + passes = PNG_INTERLACE_ADAM7_PASSES; + break; + + default: + png_error(png_ptr, "unknown interlace type"); + } + + { + png_uint_32 height = image->height; + png_uint_32 width = image->width; + int proc = display->colormap_processing; + png_bytep first_row = png_voidcast(png_bytep, display->first_row); + ptrdiff_t step_row = display->row_bytes; + int pass; + + for (pass = 0; pass < passes; ++pass) + { + unsigned int startx, stepx, stepy; + png_uint_32 y; + + if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) + { + /* The row may be empty for a short image: */ + if (PNG_PASS_COLS(width, pass) == 0) + continue; + + startx = PNG_PASS_START_COL(pass); + stepx = PNG_PASS_COL_OFFSET(pass); + y = PNG_PASS_START_ROW(pass); + stepy = PNG_PASS_ROW_OFFSET(pass); + } + + else + { + y = 0; + startx = 0; + stepx = stepy = 1; + } + + for (; ylocal_row); + png_bytep outrow = first_row + y * step_row; + png_const_bytep end_row = outrow + width; + + /* Read read the libpng data into the temporary buffer. */ + png_read_row(png_ptr, inrow, NULL); + + /* Now process the row according to the processing option, note + * that the caller verifies that the format of the libpng output + * data is as required. + */ + outrow += startx; + switch (proc) + { + case PNG_CMAP_GA: + for (; outrow < end_row; outrow += stepx) + { + /* The data is always in the PNG order */ + unsigned int gray = *inrow++; + unsigned int alpha = *inrow++; + unsigned int entry; + + /* NOTE: this code is copied as a comment in + * make_ga_colormap above. Please update the + * comment if you change this code! + */ + if (alpha > 229) /* opaque */ + { + entry = (231 * gray + 128) >> 8; + } + else if (alpha < 26) /* transparent */ + { + entry = 231; + } + else /* partially opaque */ + { + entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); + } + + *outrow = (png_byte)entry; + } + break; + + case PNG_CMAP_TRANS: + for (; outrow < end_row; outrow += stepx) + { + png_byte gray = *inrow++; + png_byte alpha = *inrow++; + + if (alpha == 0) + *outrow = PNG_CMAP_TRANS_BACKGROUND; + + else if (gray != PNG_CMAP_TRANS_BACKGROUND) + *outrow = gray; + + else + *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1); + } + break; + + case PNG_CMAP_RGB: + for (; outrow < end_row; outrow += stepx) + { + *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); + inrow += 3; + } + break; + + case PNG_CMAP_RGB_ALPHA: + for (; outrow < end_row; outrow += stepx) + { + unsigned int alpha = inrow[3]; + + /* Because the alpha entries only hold alpha==0.5 values + * split the processing at alpha==0.25 (64) and 0.75 + * (196). + */ + + if (alpha >= 196) + *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], + inrow[2]); + + else if (alpha < 64) + *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; + + else + { + /* Likewise there are three entries for each of r, g + * and b. We could select the entry by popcount on + * the top two bits on those architectures that + * support it, this is what the code below does, + * crudely. + */ + unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; + + /* Here are how the values map: + * + * 0x00 .. 0x3f -> 0 + * 0x40 .. 0xbf -> 1 + * 0xc0 .. 0xff -> 2 + * + * So, as above with the explicit alpha checks, the + * breakpoints are at 64 and 196. + */ + if (inrow[0] & 0x80) back_i += 9; /* red */ + if (inrow[0] & 0x40) back_i += 9; + if (inrow[0] & 0x80) back_i += 3; /* green */ + if (inrow[0] & 0x40) back_i += 3; + if (inrow[0] & 0x80) back_i += 1; /* blue */ + if (inrow[0] & 0x40) back_i += 1; + + *outrow = (png_byte)back_i; + } + + inrow += 4; + } + break; + + default: + break; + } + } + } + } + + return 1; +} + +static int +png_image_read_colormapped(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_controlp control = image->opaque; + png_structrp png_ptr = control->png_ptr; + png_inforp info_ptr = control->info_ptr; + + int passes = 0; /* As a flag */ + + PNG_SKIP_CHUNKS(png_ptr); + + /* Update the 'info' structure and make sure the result is as required; first + * make sure to turn on the interlace handling if it will be required + * (because it can't be turned on *after* the call to png_read_update_info!) + */ + if (display->colormap_processing == PNG_CMAP_NONE) + passes = png_set_interlace_handling(png_ptr); + + png_read_update_info(png_ptr, info_ptr); + + /* The expected output can be deduced from the colormap_processing option. */ + switch (display->colormap_processing) + { + case PNG_CMAP_NONE: + /* Output must be one channel and one byte per pixel, the output + * encoding can be anything. + */ + if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || + info_ptr->color_type == PNG_COLOR_TYPE_GRAY) && + info_ptr->bit_depth == 8) + break; + + goto bad_output; + + case PNG_CMAP_TRANS: + case PNG_CMAP_GA: + /* Output must be two channels and the 'G' one must be sRGB, the latter + * can be checked with an exact number because it should have been set + * to this number above! + */ + if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + info_ptr->bit_depth == 8 && + png_ptr->screen_gamma == PNG_GAMMA_sRGB && + image->colormap_entries == 256) + break; + + goto bad_output; + + case PNG_CMAP_RGB: + /* Output must be 8-bit sRGB encoded RGB */ + if (info_ptr->color_type == PNG_COLOR_TYPE_RGB && + info_ptr->bit_depth == 8 && + png_ptr->screen_gamma == PNG_GAMMA_sRGB && + image->colormap_entries == 216) + break; + + goto bad_output; + + case PNG_CMAP_RGB_ALPHA: + /* Output must be 8-bit sRGB encoded RGBA */ + if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + info_ptr->bit_depth == 8 && + png_ptr->screen_gamma == PNG_GAMMA_sRGB && + image->colormap_entries == 244 /* 216 + 1 + 27 */) + break; + + /* goto bad_output; */ + /* FALL THROUGH */ + + default: + bad_output: + png_error(png_ptr, "bad color-map processing (internal error)"); + } + + /* Now read the rows. Do this here if it is possible to read directly into + * the output buffer, otherwise allocate a local row buffer of the maximum + * size libpng requires and call the relevant processing routine safely. + */ + { + png_voidp first_row = display->buffer; + ptrdiff_t row_bytes = display->row_stride; + + /* The following expression is designed to work correctly whether it gives + * a signed or an unsigned result. + */ + if (row_bytes < 0) + { + char *ptr = png_voidcast(char*, first_row); + ptr += (image->height-1) * (-row_bytes); + first_row = png_voidcast(png_voidp, ptr); + } + + display->first_row = first_row; + display->row_bytes = row_bytes; + } + + if (passes == 0) + { + int result; + png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + + display->local_row = row; + result = png_safe_execute(image, png_image_read_and_map, display); + display->local_row = NULL; + png_free(png_ptr, row); + + return result; + } + + else + { + png_alloc_size_t row_bytes = display->row_bytes; + + while (--passes >= 0) + { + png_uint_32 y = image->height; + png_bytep row = png_voidcast(png_bytep, display->first_row); + + while (y-- > 0) + { + png_read_row(png_ptr, row, NULL); + row += row_bytes; + } + } + + return 1; + } +} + +/* Just the row reading part of png_image_read. */ +static int +png_image_read_composite(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + int passes; + + switch (png_ptr->interlaced) + { + case PNG_INTERLACE_NONE: + passes = 1; + break; + + case PNG_INTERLACE_ADAM7: + passes = PNG_INTERLACE_ADAM7_PASSES; + break; + + default: + png_error(png_ptr, "unknown interlace type"); + } + + { + png_uint_32 height = image->height; + png_uint_32 width = image->width; + ptrdiff_t step_row = display->row_bytes; + unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1; + int pass; + + for (pass = 0; pass < passes; ++pass) + { + unsigned int startx, stepx, stepy; + png_uint_32 y; + + if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) + { + /* The row may be empty for a short image: */ + if (PNG_PASS_COLS(width, pass) == 0) + continue; + + startx = PNG_PASS_START_COL(pass) * channels; + stepx = PNG_PASS_COL_OFFSET(pass) * channels; + y = PNG_PASS_START_ROW(pass); + stepy = PNG_PASS_ROW_OFFSET(pass); + } + + else + { + y = 0; + startx = 0; + stepx = channels; + stepy = 1; + } + + for (; ylocal_row); + png_bytep outrow; + png_const_bytep end_row; + + /* Read the row, which is packed: */ + png_read_row(png_ptr, inrow, NULL); + + outrow = png_voidcast(png_bytep, display->first_row); + outrow += y * step_row; + end_row = outrow + width * channels; + + /* Now do the composition on each pixel in this row. */ + outrow += startx; + for (; outrow < end_row; outrow += stepx) + { + png_byte alpha = inrow[channels]; + + if (alpha > 0) /* else no change to the output */ + { + unsigned int c; + + for (c=0; cimage; + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + png_uint_32 height = image->height; + png_uint_32 width = image->width; + int pass, passes; + + /* Double check the convoluted logic below. We expect to get here with + * libpng doing rgb to gray and gamma correction but background processing + * left to the png_image_read_background function. The rows libpng produce + * might be 8 or 16-bit but should always have two channels; gray plus alpha. + */ + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) + png_error(png_ptr, "lost rgb to gray"); + + if ((png_ptr->transformations & PNG_COMPOSE) != 0) + png_error(png_ptr, "unexpected compose"); + + if (png_get_channels(png_ptr, info_ptr) != 2) + png_error(png_ptr, "lost/gained channels"); + + /* Expect the 8-bit case to always remove the alpha channel */ + if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && + (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) + png_error(png_ptr, "unexpected 8-bit transformation"); + + switch (png_ptr->interlaced) + { + case PNG_INTERLACE_NONE: + passes = 1; + break; + + case PNG_INTERLACE_ADAM7: + passes = PNG_INTERLACE_ADAM7_PASSES; + break; + + default: + png_error(png_ptr, "unknown interlace type"); + } + + /* Use direct access to info_ptr here because otherwise the simplified API + * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is + * checking the value after libpng expansions, not the original value in the + * PNG. + */ + switch (info_ptr->bit_depth) + { + default: + png_error(png_ptr, "unexpected bit depth"); + break; + + case 8: + /* 8-bit sRGB gray values with an alpha channel; the alpha channel is + * to be removed by composing on a background: either the row if + * display->background is NULL or display->background->green if not. + * Unlike the code above ALPHA_OPTIMIZED has *not* been done. + */ + { + png_bytep first_row = png_voidcast(png_bytep, display->first_row); + ptrdiff_t step_row = display->row_bytes; + + for (pass = 0; pass < passes; ++pass) + { + png_bytep row = png_voidcast(png_bytep, + display->first_row); + unsigned int startx, stepx, stepy; + png_uint_32 y; + + if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) + { + /* The row may be empty for a short image: */ + if (PNG_PASS_COLS(width, pass) == 0) + continue; + + startx = PNG_PASS_START_COL(pass); + stepx = PNG_PASS_COL_OFFSET(pass); + y = PNG_PASS_START_ROW(pass); + stepy = PNG_PASS_ROW_OFFSET(pass); + } + + else + { + y = 0; + startx = 0; + stepx = stepy = 1; + } + + if (display->background == NULL) + { + for (; ylocal_row); + png_bytep outrow = first_row + y * step_row; + png_const_bytep end_row = outrow + width; + + /* Read the row, which is packed: */ + png_read_row(png_ptr, inrow, NULL); + + /* Now do the composition on each pixel in this row. */ + outrow += startx; + for (; outrow < end_row; outrow += stepx) + { + png_byte alpha = inrow[1]; + + if (alpha > 0) /* else no change to the output */ + { + png_uint_32 component = inrow[0]; + + if (alpha < 255) /* else just use component */ + { + /* Since PNG_OPTIMIZED_ALPHA was not set it is + * necessary to invert the sRGB transfer + * function and multiply the alpha out. + */ + component = png_sRGB_table[component] * alpha; + component += png_sRGB_table[outrow[0]] * + (255-alpha); + component = PNG_sRGB_FROM_LINEAR(component); + } + + outrow[0] = (png_byte)component; + } + + inrow += 2; /* gray and alpha channel */ + } + } + } + + else /* constant background value */ + { + png_byte background8 = display->background->green; + png_uint_16 background = png_sRGB_table[background8]; + + for (; ylocal_row); + png_bytep outrow = first_row + y * step_row; + png_const_bytep end_row = outrow + width; + + /* Read the row, which is packed: */ + png_read_row(png_ptr, inrow, NULL); + + /* Now do the composition on each pixel in this row. */ + outrow += startx; + for (; outrow < end_row; outrow += stepx) + { + png_byte alpha = inrow[1]; + + if (alpha > 0) /* else use background */ + { + png_uint_32 component = inrow[0]; + + if (alpha < 255) /* else just use component */ + { + component = png_sRGB_table[component] * alpha; + component += background * (255-alpha); + component = PNG_sRGB_FROM_LINEAR(component); + } + + outrow[0] = (png_byte)component; + } + + else + outrow[0] = background8; + + inrow += 2; /* gray and alpha channel */ + } + + row += display->row_bytes; + } + } + } + } + break; + + case 16: + /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must + * still be done and, maybe, the alpha channel removed. This code also + * handles the alpha-first option. + */ + { + png_uint_16p first_row = png_voidcast(png_uint_16p, + display->first_row); + /* The division by two is safe because the caller passed in a + * stride which was multiplied by 2 (below) to get row_bytes. + */ + ptrdiff_t step_row = display->row_bytes / 2; + int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; + unsigned int outchannels = 1+preserve_alpha; + int swap_alpha = 0; + +# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED + if (preserve_alpha && (image->format & PNG_FORMAT_FLAG_AFIRST)) + swap_alpha = 1; +# endif + + for (pass = 0; pass < passes; ++pass) + { + unsigned int startx, stepx, stepy; + png_uint_32 y; + + /* The 'x' start and step are adjusted to output components here. + */ + if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) + { + /* The row may be empty for a short image: */ + if (PNG_PASS_COLS(width, pass) == 0) + continue; + + startx = PNG_PASS_START_COL(pass) * outchannels; + stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; + y = PNG_PASS_START_ROW(pass); + stepy = PNG_PASS_ROW_OFFSET(pass); + } + + else + { + y = 0; + startx = 0; + stepx = outchannels; + stepy = 1; + } + + for (; ylocal_row), NULL); + inrow = png_voidcast(png_const_uint_16p, display->local_row); + + /* Now do the pre-multiplication on each pixel in this row. + */ + outrow += startx; + for (; outrow < end_row; outrow += stepx) + { + png_uint_32 component = inrow[0]; + png_uint_16 alpha = inrow[1]; + + if (alpha > 0) /* else 0 */ + { + if (alpha < 65535) /* else just use component */ + { + component *= alpha; + component += 32767; + component /= 65535; + } + } + + else + component = 0; + + outrow[swap_alpha] = (png_uint_16)component; + if (preserve_alpha != 0) + outrow[1 ^ swap_alpha] = alpha; + + inrow += 2; /* components and alpha channel */ + } + } + } + } + break; + } + + return 1; +} + +/* The guts of png_image_finish_read as a png_safe_execute callback. */ +static int +png_image_read_direct(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + + png_uint_32 format = image->format; + int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; + int do_local_compose = 0; + int do_local_background = 0; /* to avoid double gamma correction bug */ + int passes = 0; + + /* Add transforms to ensure the correct output format is produced then check + * that the required implementation support is there. Always expand; always + * need 8 bits minimum, no palette and expanded tRNS. + */ + png_set_expand(png_ptr); + + /* Now check the format to see if it was modified. */ + { + png_uint_32 base_format = png_image_format(png_ptr) & + ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */; + png_uint_32 change = format ^ base_format; + png_fixed_point output_gamma; + int mode; /* alpha mode */ + + /* Do this first so that we have a record if rgb to gray is happening. */ + if (change & PNG_FORMAT_FLAG_COLOR) + { + /* gray<->color transformation required. */ + if (format & PNG_FORMAT_FLAG_COLOR) + png_set_gray_to_rgb(png_ptr); + + else + { + /* libpng can't do both rgb to gray and + * background/pre-multiplication if there is also significant gamma + * correction, because both operations require linear colors and + * the code only supports one transform doing the gamma correction. + * Handle this by doing the pre-multiplication or background + * operation in this code, if necessary. + * + * TODO: fix this by rewriting pngrtran.c (!) + * + * For the moment (given that fixing this in pngrtran.c is an + * enormous change) 'do_local_background' is used to indicate that + * the problem exists. + */ + if (base_format & PNG_FORMAT_FLAG_ALPHA) + do_local_background = 1/*maybe*/; + + png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, + PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); + } + + change &= ~PNG_FORMAT_FLAG_COLOR; + } + + /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. + */ + { + png_fixed_point input_gamma_default; + + if ((base_format & PNG_FORMAT_FLAG_LINEAR) && + (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) + input_gamma_default = PNG_GAMMA_LINEAR; + else + input_gamma_default = PNG_DEFAULT_sRGB; + + /* Call png_set_alpha_mode to set the default for the input gamma; the + * output gamma is set by a second call below. + */ + png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); + } + + if (linear != 0) + { + /* If there *is* an alpha channel in the input it must be multiplied + * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. + */ + if (base_format & PNG_FORMAT_FLAG_ALPHA) + mode = PNG_ALPHA_STANDARD; /* associated alpha */ + + else + mode = PNG_ALPHA_PNG; + + output_gamma = PNG_GAMMA_LINEAR; + } + + else + { + mode = PNG_ALPHA_PNG; + output_gamma = PNG_DEFAULT_sRGB; + } + + /* If 'do_local_background' is set check for the presence of gamma + * correction; this is part of the work-round for the libpng bug + * described above. + * + * TODO: fix libpng and remove this. + */ + if (do_local_background != 0) + { + png_fixed_point gtest; + + /* This is 'png_gamma_threshold' from pngrtran.c; the test used for + * gamma correction, the screen gamma hasn't been set on png_struct + * yet; it's set below. png_struct::gamma, however, is set to the + * final value. + */ + if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, + PNG_FP_1) && !png_gamma_significant(gtest)) + do_local_background = 0; + + else if (mode == PNG_ALPHA_STANDARD) + { + do_local_background = 2/*required*/; + mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ + } + + /* else leave as 1 for the checks below */ + } + + /* If the bit-depth changes then handle that here. */ + if (change & PNG_FORMAT_FLAG_LINEAR) + { + if (linear /*16-bit output*/) + png_set_expand_16(png_ptr); + + else /* 8-bit output */ + png_set_scale_16(png_ptr); + + change &= ~PNG_FORMAT_FLAG_LINEAR; + } + + /* Now the background/alpha channel changes. */ + if (change & PNG_FORMAT_FLAG_ALPHA) + { + /* Removing an alpha channel requires composition for the 8-bit + * formats; for the 16-bit it is already done, above, by the + * pre-multiplication and the channel just needs to be stripped. + */ + if (base_format & PNG_FORMAT_FLAG_ALPHA) + { + /* If RGB->gray is happening the alpha channel must be left and the + * operation completed locally. + * + * TODO: fix libpng and remove this. + */ + if (do_local_background != 0) + do_local_background = 2/*required*/; + + /* 16-bit output: just remove the channel */ + else if (linear != 0) /* compose on black (well, pre-multiply) */ + png_set_strip_alpha(png_ptr); + + /* 8-bit output: do an appropriate compose */ + else if (display->background != NULL) + { + png_color_16 c; + + c.index = 0; /*unused*/ + c.red = display->background->red; + c.green = display->background->green; + c.blue = display->background->blue; + c.gray = display->background->green; + + /* This is always an 8-bit sRGB value, using the 'green' channel + * for gray is much better than calculating the luminance here; + * we can get off-by-one errors in that calculation relative to + * the app expectations and that will show up in transparent + * pixels. + */ + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + } + + else /* compose on row: implemented below. */ + { + do_local_compose = 1; + /* This leaves the alpha channel in the output, so it has to be + * removed by the code below. Set the encoding to the 'OPTIMIZE' + * one so the code only has to hack on the pixels that require + * composition. + */ + mode = PNG_ALPHA_OPTIMIZED; + } + } + + else /* output needs an alpha channel */ + { + /* This is tricky because it happens before the swap operation has + * been accomplished; however, the swap does *not* swap the added + * alpha channel (weird API), so it must be added in the correct + * place. + */ + png_uint_32 filler; /* opaque filler */ + int where; + + if (linear != 0) + filler = 65535; + + else + filler = 255; + +# ifdef PNG_FORMAT_AFIRST_SUPPORTED + if (format & PNG_FORMAT_FLAG_AFIRST) + { + where = PNG_FILLER_BEFORE; + change &= ~PNG_FORMAT_FLAG_AFIRST; + } + + else +# endif + where = PNG_FILLER_AFTER; + + png_set_add_alpha(png_ptr, filler, where); + } + + /* This stops the (irrelevant) call to swap_alpha below. */ + change &= ~PNG_FORMAT_FLAG_ALPHA; + } + + /* Now set the alpha mode correctly; this is always done, even if there is + * no alpha channel in either the input or the output because it correctly + * sets the output gamma. + */ + png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); + +# ifdef PNG_FORMAT_BGR_SUPPORTED + if (change & PNG_FORMAT_FLAG_BGR) + { + /* Check only the output format; PNG is never BGR; don't do this if + * the output is gray, but fix up the 'format' value in that case. + */ + if (format & PNG_FORMAT_FLAG_COLOR) + png_set_bgr(png_ptr); + + else + format &= ~PNG_FORMAT_FLAG_BGR; + + change &= ~PNG_FORMAT_FLAG_BGR; + } +# endif + +# ifdef PNG_FORMAT_AFIRST_SUPPORTED + if (change & PNG_FORMAT_FLAG_AFIRST) + { + /* Only relevant if there is an alpha channel - it's particularly + * important to handle this correctly because do_local_compose may + * be set above and then libpng will keep the alpha channel for this + * code to remove. + */ + if (format & PNG_FORMAT_FLAG_ALPHA) + { + /* Disable this if doing a local background, + * TODO: remove this when local background is no longer required. + */ + if (do_local_background != 2) + png_set_swap_alpha(png_ptr); + } + + else + format &= ~PNG_FORMAT_FLAG_AFIRST; + + change &= ~PNG_FORMAT_FLAG_AFIRST; + } +# endif + + /* If the *output* is 16-bit then we need to check for a byte-swap on this + * architecture. + */ + if (linear != 0) + { + PNG_CONST png_uint_16 le = 0x0001; + + if (*(png_const_bytep)&le) + png_set_swap(png_ptr); + } + + /* If change is not now 0 some transformation is missing - error out. */ + if (change != 0) + png_error(png_ptr, "png_read_image: unsupported transformation"); + } + + PNG_SKIP_CHUNKS(png_ptr); + + /* Update the 'info' structure and make sure the result is as required; first + * make sure to turn on the interlace handling if it will be required + * (because it can't be turned on *after* the call to png_read_update_info!) + * + * TODO: remove the do_local_background fixup below. + */ + if (do_local_compose == 0 && do_local_background != 2) + passes = png_set_interlace_handling(png_ptr); + + png_read_update_info(png_ptr, info_ptr); + + { + png_uint_32 info_format = 0; + + if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + info_format |= PNG_FORMAT_FLAG_COLOR; + + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + { + /* do_local_compose removes this channel below. */ + if (do_local_compose == 0) + { + /* do_local_background does the same if required. */ + if (do_local_background != 2 || + (format & PNG_FORMAT_FLAG_ALPHA) != 0) + info_format |= PNG_FORMAT_FLAG_ALPHA; + } + } + + else if (do_local_compose != 0) /* internal error */ + png_error(png_ptr, "png_image_read: alpha channel lost"); + + if (info_ptr->bit_depth == 16) + info_format |= PNG_FORMAT_FLAG_LINEAR; + +# ifdef PNG_FORMAT_BGR_SUPPORTED + if (png_ptr->transformations & PNG_BGR) + info_format |= PNG_FORMAT_FLAG_BGR; +# endif + +# ifdef PNG_FORMAT_AFIRST_SUPPORTED + if (do_local_background == 2) + { + if (format & PNG_FORMAT_FLAG_AFIRST) + info_format |= PNG_FORMAT_FLAG_AFIRST; + } + + if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || + ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && + (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) + { + if (do_local_background == 2) + png_error(png_ptr, "unexpected alpha swap transformation"); + + info_format |= PNG_FORMAT_FLAG_AFIRST; + } +# endif + + /* This is actually an internal error. */ + if (info_format != format) + png_error(png_ptr, "png_read_image: invalid transformations"); + } + + /* Now read the rows. If do_local_compose is set then it is necessary to use + * a local row buffer. The output will be GA, RGBA or BGRA and must be + * converted to G, RGB or BGR as appropriate. The 'local_row' member of the + * display acts as a flag. + */ + { + png_voidp first_row = display->buffer; + ptrdiff_t row_bytes = display->row_stride; + + if (linear != 0) + row_bytes *= 2; + + /* The following expression is designed to work correctly whether it gives + * a signed or an unsigned result. + */ + if (row_bytes < 0) + { + char *ptr = png_voidcast(char*, first_row); + ptr += (image->height-1) * (-row_bytes); + first_row = png_voidcast(png_voidp, ptr); + } + + display->first_row = first_row; + display->row_bytes = row_bytes; + } + + if (do_local_compose != 0) + { + int result; + png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + + display->local_row = row; + result = png_safe_execute(image, png_image_read_composite, display); + display->local_row = NULL; + png_free(png_ptr, row); + + return result; + } + + else if (do_local_background == 2) + { + int result; + png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + + display->local_row = row; + result = png_safe_execute(image, png_image_read_background, display); + display->local_row = NULL; + png_free(png_ptr, row); + + return result; + } + + else + { + png_alloc_size_t row_bytes = display->row_bytes; + + while (--passes >= 0) + { + png_uint_32 y = image->height; + png_bytep row = png_voidcast(png_bytep, display->first_row); + + while (y-- > 0) + { + png_read_row(png_ptr, row, NULL); + row += row_bytes; + } + } + + return 1; + } +} + +int PNGAPI +png_image_finish_read(png_imagep image, png_const_colorp background, + void *buffer, png_int_32 row_stride, void *colormap) +{ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + png_uint_32 check; + + if (row_stride == 0) + row_stride = PNG_IMAGE_ROW_STRIDE(*image); + + if (row_stride < 0) + check = -row_stride; + + else + check = row_stride; + + if (image->opaque != NULL && buffer != NULL && + check >= PNG_IMAGE_ROW_STRIDE(*image)) + { + if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || + (image->colormap_entries > 0 && colormap != NULL)) + { + int result; + png_image_read_control display; + + memset(&display, 0, (sizeof display)); + display.image = image; + display.buffer = buffer; + display.row_stride = row_stride; + display.colormap = colormap; + display.background = background; + display.local_row = NULL; + + /* Choose the correct 'end' routine; for the color-map case all the + * setup has already been done. + */ + if (image->format & PNG_FORMAT_FLAG_COLORMAP) + result = + png_safe_execute(image, png_image_read_colormap, &display) && + png_safe_execute(image, png_image_read_colormapped, &display); + + else + result = + png_safe_execute(image, png_image_read_direct, &display); + + png_image_free(image); + return result; + } + + else + return png_image_error(image, + "png_image_finish_read[color-map]: no color-map"); + } + + else + return png_image_error(image, + "png_image_finish_read: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_finish_read: damaged PNG_IMAGE_VERSION"); + + return 0; +} + +#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngrio.c b/ext/native/ext/libpng17/pngrio.c new file mode 100644 index 0000000000..d75ac5b4dd --- /dev/null +++ b/ext/native/ext/libpng17/pngrio.c @@ -0,0 +1,120 @@ + +/* pngrio.c - functions for data input + * + * Last changed in libpng 1.6.9 [February 6, 2014] + * Copyright (c) 1998-2014 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_structrp 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. + */ +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_voidcast(png_FILE_p, png_ptr->io_ptr)); + + if (check != length) + png_error(png_ptr, "Read Error"); +} +#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_structrp 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 + +#ifdef PNG_WRITE_SUPPORTED + /* 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"); + } +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->output_flush_fn = NULL; +#endif +} +#endif /* PNG_READ_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngrtran.c b/ext/native/ext/libpng17/pngrtran.c new file mode 100644 index 0000000000..331b59ee62 --- /dev/null +++ b/ext/native/ext/libpng17/pngrtran.c @@ -0,0 +1,4885 @@ + +/* pngrtran.c - transforms the data in a row for PNG readers + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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_structrp 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_TRANSFORMS_SUPPORTED +/* Is it OK to set a transformation now? Only if png_start_read_image or + * png_read_update_info have not been called. It is not necessary for the IHDR + * to have been read in all cases, the parameter allows for this check too. + */ +static int +png_rtran_ok(png_structrp png_ptr, int need_IHDR) +{ + if (png_ptr != NULL) + { + if (png_ptr->flags & PNG_FLAG_ROW_INIT) + png_app_error(png_ptr, + "invalid after png_start_read_image or png_read_update_info"); + + else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_app_error(png_ptr, "invalid before the PNG header has been read"); + + else + { + /* Turn on failure to initialize correctly for all transforms. */ + png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; + + return 1; /* Ok */ + } + } + + return 0; /* no png_error possible! */ +} +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS via a background color */ +void PNGFAPI +png_set_background_fixed(png_structrp 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_rtran_ok(png_ptr, 0) || background_color == NULL) + return; + + if (background_gamma_code != PNG_BACKGROUND_GAMMA_SCREEN && + background_gamma_code != PNG_BACKGROUND_GAMMA_FILE && + background_gamma_code != PNG_BACKGROUND_GAMMA_UNIQUE) + { + png_app_error(png_ptr, "invalid gamma type"); + return; + } + + png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + png_ptr->background = *background_color; + png_ptr->background_gamma = background_gamma; + png_ptr->background_gamma_type = (png_byte)(background_gamma_code); + + if (need_expand != 0) + png_ptr->flags |= PNG_FLAG_BACKGROUND_EXPAND; + + else + png_ptr->flags &= ~PNG_FLAG_BACKGROUND_EXPAND; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_background(png_structrp 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_structrp png_ptr) +{ + png_debug(1, "in png_set_scale_16"); + + if (!png_rtran_ok(png_ptr, 0)) + 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_structrp png_ptr) +{ + png_debug(1, "in png_set_strip_16"); + + if (!png_rtran_ok(png_ptr, 0)) + return; + + png_ptr->transformations |= PNG_16_TO_8; +} +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +void PNGAPI +png_set_strip_alpha(png_structrp png_ptr) +{ + png_debug(1, "in png_set_strip_alpha"); + + if (!png_rtran_ok(png_ptr, 0)) + 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_structrp 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; +# else + PNG_UNUSED(png_ptr) +# endif + if (is_screen != 0) + 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 != 0) + 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_structrp 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 *= .00001; + + return png_fixed(png_ptr, output_gamma, "gamma value"); +} +# endif +#endif /* READ_ALPHA_MODE || READ_GAMMA */ + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +void PNGFAPI +png_set_alpha_mode_fixed(png_structrp 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_rtran_ok(png_ptr, 0)) + 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->colorspace.gamma == 0) + { + png_ptr->colorspace.gamma = file_gamma; + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_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 != 0) + { + /* And obtain alpha pre-multiplication by composing on black: */ + memset(&png_ptr->background, 0, (sizeof png_ptr->background)); + png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; + png_ptr->flags &= ~PNG_FLAG_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; + } +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_alpha_mode(png_structrp 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 * next; + png_byte left; + png_byte right; +} png_dsort; +typedef png_dsort * png_dsortp; +typedef png_dsort * * png_dsortpp; + +void PNGAPI +png_set_quantize(png_structrp 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_rtran_ok(png_ptr, 0)) + return; + + png_ptr->transformations |= PNG_QUANTIZE; + + if (full_quantize == 0) + { + int i; + + png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * (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 * (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 != 0) + break; + } + + /* Swap the palette around, and set up a table, if necessary */ + if (full_quantize != 0) + { + 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 * (sizeof (png_byte)))); + png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * (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 * + (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)(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 == 0) + { + 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 != 0) + { + 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 * (sizeof (png_byte)))); + + distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * + (sizeof (png_byte)))); + + memset(distance, 0xff, num_entries * (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_structrp png_ptr, png_fixed_point scrn_gamma, + png_fixed_point file_gamma) +{ + png_debug(1, "in png_set_gamma_fixed"); + + if (!png_rtran_ok(png_ptr, 0)) + 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*/); + + /* 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) the following checks were only enabled in + * 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"); + + /* 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->colorspace.gamma = file_gamma; + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + png_ptr->screen_gamma = scrn_gamma; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gamma(png_structrp 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_structrp png_ptr) +{ + png_debug(1, "in png_set_expand"); + + if (!png_rtran_ok(png_ptr, 0)) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} + +/* 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_structrp png_ptr) +{ + png_debug(1, "in png_set_palette_to_rgb"); + + if (!png_rtran_ok(png_ptr, 0)) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} + +/* Expand grayscale images of less than 8-bit depth to 8 bits. */ +void PNGAPI +png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) +{ + png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); + + if (!png_rtran_ok(png_ptr, 0)) + return; + + png_ptr->transformations |= PNG_EXPAND; +} + +/* Expand tRNS chunks to alpha channels. */ +void PNGAPI +png_set_tRNS_to_alpha(png_structrp png_ptr) +{ + png_debug(1, "in png_set_tRNS_to_alpha"); + + if (!png_rtran_ok(png_ptr, 0)) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} +#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_structrp png_ptr) +{ + png_debug(1, "in png_set_expand_16"); + + if (!png_rtran_ok(png_ptr, 0)) + return; + + png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); +} +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +void PNGAPI +png_set_gray_to_rgb(png_structrp png_ptr) +{ + png_debug(1, "in png_set_gray_to_rgb"); + + if (!png_rtran_ok(png_ptr, 0)) + return; + + /* 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; +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +void PNGFAPI +png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, + png_fixed_point red, png_fixed_point green) +{ + png_debug(1, "in png_set_rgb_to_gray"); + + /* Need the IHDR here because of the check on color_type below. */ + /* TODO: fix this */ + if (!png_rtran_ok(png_ptr, 1)) + 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 + { + /* Make this an error in 1.6 because otherwise the application may assume + * that it just worked and get a memory overwrite. + */ + png_error(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; +# if defined(PNG_COLORS_SPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) + png_ptr->colorspace.flags |= PNG_COLORSPACE_RGB_TO_GRAY_SET; +# endif + } + + else + { + if (red >= 0 && green >= 0) + png_app_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_structrp png_ptr, int error_action, double red, + double green) +{ + 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 /* RGB_TO_GRAY */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +void PNGAPI +png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr + read_user_transform_fn) +{ + png_debug(1, "in png_set_read_user_transform_fn"); + +#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. + */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) +static void +gamma_correct_background(unsigned int value, unsigned int depth, + png_uint_16p backgroundp, png_uint_16p background_1p, + png_fixed_point gamma_correct, png_fixed_point gamma_to_1) +{ + switch (depth) + { + case 8: + if (gamma_correct != PNG_FP_1) + *backgroundp = png_gamma_8bit_correct(value, gamma_correct); + + else + *backgroundp = (png_uint_16)value; + + if (gamma_to_1 != PNG_FP_1) + *background_1p = png_gamma_16bit_correct(value*257, gamma_to_1); + + else + *background_1p = (png_uint_16)(value*257); + + return; + + case 16: + if (gamma_correct != PNG_FP_1) + *backgroundp = png_gamma_16bit_correct(value, gamma_correct); + + else + *backgroundp = (png_uint_16)value; + + if (gamma_to_1 != PNG_FP_1) + *background_1p = png_gamma_16bit_correct(value, gamma_to_1); + + else + *background_1p = (png_uint_16)value; + + return; + + default: + /* Low bit depth gray levels; do no harm. */ + break; + } + + *backgroundp = (png_uint_16)value; + *background_1p = 0; /* should not be used */ +} + +static void /* PRIVATE */ +png_init_background_transformations(png_structrp png_ptr) + /* Set the png_ptr->background and png_ptr->background_1 members correctly + * for the bit depth and format. + */ +{ + /* png_ptr->background is only assigned by png_set_background and + * png_set_alpha_mode (which just zeros out the fields.) png_set_background + * can set the PNG_FLAG_BACKGROUND_EXPAND flag if the input value is in the + * file format, for example if it comes from a bKGD chunk. + * + * Under some circumstances deficiencies in the current libpng code mean that + * the bit depth of the values must differ from the final bit depth; the bit + * depth has to match that at which the processing of the image pixels + * happens and this is not always the final bit depth. This is fixed up + * here. + * + * First find the required depth. + */ + unsigned int bit_depth, required_bit_depth; + unsigned int color_type = png_ptr->color_type; + const png_uint_32 transform = png_ptr->transformations; + const int expand = (png_ptr->flags & PNG_FLAG_BACKGROUND_EXPAND) != 0; + + if (color_type & PNG_COLOR_MASK_PALETTE) + required_bit_depth = bit_depth = 8; + + else + { + required_bit_depth = bit_depth = png_ptr->bit_depth; + + /* But not PNG_EXPAND_16 at present because it happens after the compose + * operation where the background is used! + */ + if (bit_depth < 8 && (transform & PNG_EXPAND) != 0) + required_bit_depth = 8; + } + + /* bit_depth and color_type now refer to the original file data and + * required_bit_depth is correct for the processing libpng does, however it + * does not necessarily match the output the application gets, fix that and + * the color type here: + */ + if (expand == 0) + { + /* The background bit_depth and color_type need correcting */ + if ((transform & PNG_EXPAND) != 0) + color_type &= ~PNG_COLOR_MASK_PALETTE; + + /* The RGB<->gray transformations do the to gray operation first, then the + * from gray. + */ + if ((transform & PNG_RGB_TO_GRAY) != 0) + color_type &= ~PNG_COLOR_MASK_COLOR; + + if ((transform & PNG_GRAY_TO_RGB) != 0) + color_type |= PNG_COLOR_MASK_COLOR; + + bit_depth = required_bit_depth; + + /* The expansion to 16 bits and the scaling back from 16 bits per + * component to only 8 happens after the background processing (at + * present) so these transforms only affect the screen value, not the + * required value. Note that the 16_TO_8 conversions happen before the 8 + * to 16 one, so in theory both could occur - the order of the tests below + * must be correct! + * + * TODO: Note that the second of these changes cause an input 16-bit + * background value to be temporarily crushed to 8-bits per component, + * losing precision. This is a bug and should be fixed. + */ + if (bit_depth == 16 && + (transform & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0) + bit_depth = 8; + + if (bit_depth == 8 && (color_type & PNG_COLOR_MASK_PALETTE) == 0 && + (transform & PNG_EXPAND_16) != 0) + bit_depth = 16; + } + + /* Now make the background have the correct format. This involves reading the + * correct fields from png_ptr->background, adjusting the bit depth of the + * result and potentially gamma correcting the value then calculating the + * png_ptr->background_1 values too. + */ + { + unsigned int mult = 1; + png_fixed_point gamma_to_1, gamma_correct; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + gamma_to_1 = png_ptr->screen_gamma; + gamma_correct = PNG_FP_1; + break; + + case PNG_BACKGROUND_GAMMA_FILE: + gamma_to_1 = png_reciprocal(png_ptr->colorspace.gamma); + gamma_correct = png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: + gamma_to_1 = png_reciprocal(png_ptr->background_gamma); + gamma_correct = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); + break; + + default: + gamma_to_1 = PNG_FP_1; + gamma_correct = PNG_FP_1; + break; + } + +# define CORRECT(v, c)\ + gamma_correct_background((v)*mult, bit_depth,\ + &png_ptr->background.c, &png_ptr->background_1.c,\ + gamma_correct, gamma_to_1);\ + if (bit_depth > required_bit_depth)\ + png_ptr->background.c =\ + (png_uint_16)PNG_DIV257(png_ptr->background.c) + + /* The multiplier 'mult' scales the values to 'required_depth', + * 'bit_depth' is the depth of the resultant values. + */ + while (bit_depth < required_bit_depth) + mult += mult << bit_depth, bit_depth <<= 1; + + /* In the event that this still leaves the background bit depth greater + * than the libpng required depth scale the values back to the 8-bit + * range, the test below verifies that this is correct. + */ + if (bit_depth > required_bit_depth) + { + if (bit_depth != 16 || required_bit_depth != 8) + png_error(png_ptr, "internal error handling background depth"); + } + + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_ptr->flags &= ~PNG_FLAG_BACKGROUND_IS_GRAY; /* checked below */ + + /* If need_expand was passed to png_set_background the background value + * was in the file format, therefore if the file is a palette file the + * background will have been an index into the palette. Notice that if + * need_expand was false then the color is RGB even if the output still + * has a palette. + */ + if (expand && (color_type & PNG_COLOR_MASK_PALETTE) != 0) + { + unsigned int background_index = png_ptr->background.index; + + if (background_index < png_ptr->num_palette && + png_ptr->palette != NULL) + { + /* In fact 'mult' is always 1 at present in this case */ + CORRECT(png_ptr->palette[background_index].red, red); + CORRECT(png_ptr->palette[background_index].green, green); + CORRECT(png_ptr->palette[background_index].blue, blue); + } + + else + { + png_app_error(png_ptr, "out of range background index"); + memset(&png_ptr->background, 0, sizeof png_ptr->background); + memset(&png_ptr->background_1, 0, sizeof png_ptr->background_1); + } + } + + else + { + CORRECT(png_ptr->background.red, red); + CORRECT(png_ptr->background.green, green); + CORRECT(png_ptr->background.blue, blue); + } + + if (png_ptr->background.red == png_ptr->background.blue && + png_ptr->background.red == png_ptr->background.green) + { + png_ptr->flags |= PNG_FLAG_BACKGROUND_IS_GRAY; + png_ptr->background.gray = png_ptr->background.red; + png_ptr->background_1.gray = png_ptr->background_1.red; + } + + else + png_ptr->background.gray = png_ptr->background_1.gray = 0; + } + + else + { + png_ptr->flags |= PNG_FLAG_BACKGROUND_IS_GRAY; + + CORRECT(png_ptr->background.gray, gray); + + png_ptr->background.red = + png_ptr->background.green = + png_ptr->background.blue = png_ptr->background.gray; + + png_ptr->background_1.red = + png_ptr->background_1.green = + png_ptr->background_1.blue = png_ptr->background_1.gray; + } +# undef CORRECT + } +} +#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ + +static void /* PRIVATE */ +png_init_palette_transformations(png_structrp png_ptr) +{ + 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_transparency = 1; + input_has_alpha = 1; + break; + } + } + } + + /* If no alpha we can optimize. */ + if (input_has_alpha == 0) + { + /* Any alpha means background and associative alpha processing is + * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + if (input_has_transparency == 0) + png_ptr->transformations &= ~PNG_COMPOSE; + } +} + +static void /* PRIVATE */ +png_init_rgb_transformations(png_structrp 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 == 0) + { + /* Any alpha means background and associative alpha processing is + * required, however if the alpha is 0 or 1 throughout OPTIMIZE_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 == 0) + png_ptr->transformations &= ~PNG_COMPOSE; + } +} + +void /* PRIVATE */ +png_init_read_transformations(png_structrp 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->colorspace.gamma != 0) /* has been set */ + { + if (png_ptr->screen_gamma != 0) /* screen set too */ + gamma_correction = png_gamma_threshold(png_ptr->colorspace.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->colorspace.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->colorspace.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->colorspace.gamma = PNG_FP_1; + + /* We have a gamma value now. */ + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + + /* 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 != 0) + 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_FLAG_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_FLAG_BACKGROUND_IS_GRAY + * 14) PNG_INVERT_MONO + * 15) PNG_INVERT_ALPHA + * 16) PNG_SHIFT + * 17) PNG_PACK + * 18) PNG_BGR + * 19) PNG_PACKSWAP + * 20) PNG_FILLER (includes PNG_ADD_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) + { + if (!(png_ptr->transformations & PNG_FILLER)) + png_ptr->transformations &= ~(PNG_INVERT_ALPHA|PNG_SWAP_ALPHA); + + if (!(png_ptr->transformations & PNG_COMPOSE)) + { + /* Stripping the alpha channel happens immediately after the 'expand' + * transformations, before all other transformations, so it cancels out + * the alpha handling. It has the side effect negating the effect of + * PNG_EXPAND_tRNS too: + */ + png_ptr->transformations &= ~(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 + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Make sure the coefficients for the rgb to gray conversion are set + * appropriately. + */ + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + png_colorspace_set_rgb_coefficients(png_ptr); +#endif + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_init_palette_transformations(png_ptr); + + else + png_init_rgb_transformations(png_ptr); + +#ifdef PNG_READ_BACKGROUND_SUPPORTED + /* Set up the background information if required. It is only used if + * PNG_COMPOSE is specified. + */ + if (png_ptr->transformations & PNG_COMPOSE) + png_init_background_transformations(png_ptr); +#endif + + /* 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 0 /* NYI */ + png_do_palette_transformations(png_ptr); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* 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->colorspace.gamma) || + png_gamma_significant(png_ptr->screen_gamma))) + || ((png_ptr->transformations & PNG_COMPOSE) + && (png_gamma_significant(png_ptr->colorspace.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_tables(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) + { + unsigned int i, num_palette = png_ptr->num_palette; + png_color back; + png_color_16 back_1 = png_ptr->background_1; + 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 < num_palette; i++) + { + if (i < 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_uint_16 v, w; + unsigned int alpha = png_ptr->trans_alpha[i] * 257U; + unsigned int shift = png_ptr->gamma_shift; + unsigned int add = (shift > 0 ? 1U<<(shift-1) : 0); + + v = png_ptr->gamma_to_1[palette[i].red]; + png_composite_16(w, v, alpha, back_1.red); + palette[i].red = png_ptr->gamma_from_1[(w+add)>>shift]; + + v = png_ptr->gamma_to_1[palette[i].green]; + png_composite_16(w, v, alpha, back_1.green); + palette[i].green = png_ptr->gamma_from_1[(w+add)>>shift]; + + v = png_ptr->gamma_to_1[palette[i].blue]; + png_composite_16(w, v, alpha, back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[(w+add)>>shift]; + } + } + 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 */ + }/* 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->transformations & PNG_EXPAND) && + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; + int istop = png_ptr->num_palette; + int shift = 8 - png_ptr->sig_bit.red; + + png_ptr->transformations &= ~PNG_SHIFT; + + /* 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_structrp png_ptr, png_inforp 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; + + if (png_ptr->palette == NULL) + png_error (png_ptr, "Palette is NULL in indexed image"); + } + 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. + * + * TODO: this looks wrong; the info_ptr should end up with a gamma equal to + * the screen_gamma value. The following probably results in weirdness if + * the info_ptr is used by the app after the rows have been read. + */ + info_ptr->colorspace.gamma = png_ptr->colorspace.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 != NULL) + return; +#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. + */ +static void +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. + */ +static void +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 == 0) + 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 */ +static void +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 +static void +/* 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 +static void +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 +static void +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 */ +static void +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 */ +static void +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. + */ +static int +png_do_rgb_to_gray(png_structrp 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) + { + /* 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_CONST unsigned int shift = 15 + png_ptr->gamma_shift; + PNG_CONST png_uint_32 add = 1U << (shift-1); + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + unsigned int red = *(sp++); + unsigned int green = *(sp++); + unsigned int 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 + add)>>shift]; + } + + 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++) = (png_byte)red; + } + + if (have_alpha != 0) + *(dp++) = *(sp++); + } + } + + else + { + 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; + *(dp++) = (png_byte)((rc*red+gc*green+bc*blue+16384)>>15); + } + + else + *(dp++) = red; + + if (have_alpha != 0) + *(dp++) = *(sp++); + } + } + } + + else /* RGB bit_depth == 16 */ + { + if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) + { + unsigned int shift = png_ptr->gamma_shift; + unsigned int add = (shift > 0 ? (1U << (shift-1)) : 0); + 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+add) >> shift]; + + else + w = red; + } + + else + { + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red+add) + >> shift]; + png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green+add) + >> shift]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue+add) + >> shift]; + 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+add) >> shift]; + rgb_error |= 1; + } + + *(dp++) = (png_byte)((w>>8) & 0xff); + *(dp++) = (png_byte)(w & 0xff); + + if (have_alpha != 0) + { + *(dp++) = *(sp++); + *(dp++) = *(sp++); + } + } + } + + else + { + 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 != 0) + { + *(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 + +#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. + */ +static void +png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) +{ + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; + png_const_uint_16p gamma_to_1 = png_ptr->gamma_to_1; + png_const_uint_16p gamma_16 = png_ptr->gamma_16_table; + png_const_uint_16p gamma_16_from_1 = png_ptr->gamma_16_from_1; + png_const_uint_16p gamma_16_to_1 = png_ptr->gamma_16_to_1; + PNG_CONST unsigned int shift = png_ptr->gamma_shift; + PNG_CONST unsigned int add = (shift > 0 ? 1U<<(shift-1) : 0); + PNG_CONST int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_compose"); + + { + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_GRAY: + { + switch (row_info->bit_depth) + { + case 1: + { + int bit_shift = 7; + sp = row; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> bit_shift) & 0x01) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x7f7f >> (7 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; + *sp = (png_byte)(tmp & 0xff); + } + + if (bit_shift == 0) + { + bit_shift = 7; + sp++; + } + + else + bit_shift--; + } + break; + } + + case 2: + { +#if 0 + if (gamma_table != NULL) + { + int bit_shift = 6; + sp = row; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> bit_shift) & 0x03) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x3f3f >> (6 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; + *sp = (png_byte)(tmp & 0xff); + } + + else + { + unsigned int p = (*sp >> bit_shift) & 0x03; + unsigned int g = (gamma_table [p | (p << 2) | + (p << 4) | (p << 6)] >> 6) & 0x03; + unsigned int tmp = *sp & (0x3f3f >> (6 - bit_shift)); + tmp |= g << bit_shift; + *sp = (png_byte)(tmp & 0xff); + } + + if (bit_shift == 0) + { + bit_shift = 6; + sp++; + } + + else + bit_shift -= 2; + } + } + + else +#endif + { + int bit_shift = 6; + sp = row; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> bit_shift) & 0x03) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x3f3f >> (6 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; + *sp = (png_byte)(tmp & 0xff); + } + + if (bit_shift == 0) + { + bit_shift = 6; + sp++; + } + + else + bit_shift -= 2; + } + } + break; + } + + case 4: + { +#if 0 + if (gamma_table != NULL) + { + int bit_shift = 4; + sp = row; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> bit_shift) & 0x0f) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0xf0f >> (4 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; + *sp = (png_byte)(tmp & 0xff); + } + + else + { + unsigned int p = (*sp >> bit_shift) & 0x0f; + unsigned int g = (gamma_table[p | (p << 4)] >> 4) & + 0x0f; + unsigned int tmp = *sp & (0xf0f >> (4 - bit_shift)); + tmp |= g << bit_shift; + *sp = (png_byte)(tmp & 0xff); + } + + if (bit_shift == 0) + { + bit_shift = 4; + sp++; + } + + else + bit_shift -= 4; + } + } + + else +#endif + { + int bit_shift = 4; + sp = row; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> bit_shift) & 0x0f) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0xf0f >> (4 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; + *sp = (png_byte)(tmp & 0xff); + } + + if (bit_shift == 0) + { + bit_shift = 4; + sp++; + } + + else + bit_shift -= 4; + } + } + break; + } + + case 8: + { + 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 + { + 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: + { + 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[(v+add) >> shift]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + + else + { + 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) + { + 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 + { + 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) */ + { + 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[(r+add) >> shift]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + v = gamma_16[(g+add) >> shift]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + v = gamma_16[(b+add) >> shift]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + + else + { + 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) + { + 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 + { + unsigned int v, w; + + v = gamma_to_1[*sp]; + png_composite_16(w, v, 257*a, + png_ptr->background_1.gray); + + if (optimize == 0) + w = gamma_from_1[(w+add)>>shift]; + + else /* alpha pixels linear and approximate */ + w = PNG_DIV257(w); + + *sp = (png_byte)w; + } + } + } + + else + { + 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.gray); + } + } + } + + else /* if (png_ptr->bit_depth == 16) */ + { + 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[0]<<8)+sp[1]+add) >> shift]; + *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[0]<<8)+sp[1]+add) >> shift]; + png_composite_16(v, g, a, png_ptr->background_1.gray); + + if (optimize == 0) + w = gamma_16_from_1[(v+add) >> shift]; + + else + w = v; + + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + } + } + } + + else + { + 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.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) + { + 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 + { + unsigned int v, w; + unsigned int alpha = a * 257U; + + v = gamma_to_1[*sp]; + png_composite_16(w, v, alpha, + png_ptr->background_1.red); + + if (optimize == 0) + w = gamma_from_1[(w+add)>>shift]; + + else + w = PNG_DIV257(w); + + *sp = (png_byte)w; + + v = gamma_to_1[*(sp + 1)]; + png_composite_16(w, v, alpha, + png_ptr->background_1.green); + + if (optimize == 0) + w = gamma_from_1[(w+add)>>shift]; + + else + w = PNG_DIV257(w); + + *(sp + 1) = (png_byte)w; + + v = gamma_to_1[*(sp + 2)]; + png_composite_16(w, v, alpha, + png_ptr->background_1.blue); + + if (optimize == 0) + w = gamma_from_1[(w+add)>>shift]; + + else + w = PNG_DIV257(w); + + *(sp + 2) = (png_byte)w; + } + } + } + + else + { + 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) */ + { + 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[0]<<8)+sp[1]+add) >> shift]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + v = gamma_16[((sp[2]<<8)+sp[3]+add) >> shift]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + v = gamma_16[((sp[4]<<8)+sp[5]+add) >> shift]; + *(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[0]<<8)+sp[1]+add) >> shift]; + png_composite_16(w, v, a, png_ptr->background_1.red); + + if (optimize == 0) + w = gamma_16_from_1[(w+add) >> shift]; + + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[((sp[2]<<8)+sp[3]+add) >> shift]; + png_composite_16(w, v, a, png_ptr->background_1.green); + + if (optimize == 0) + w = gamma_16_from_1[(w+add) >> shift]; + + *(sp + 2) = (png_byte)((w >> 8) & 0xff); + *(sp + 3) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[((sp[4]<<8)+sp[5]+add) >> shift]; + png_composite_16(w, v, a, png_ptr->background_1.blue); + + if (optimize == 0) + w = gamma_16_from_1[(w+add) >> shift]; + + *(sp + 4) = (png_byte)((w >> 8) & 0xff); + *(sp + 5) = (png_byte)(w & 0xff); + } + } + } + + else + { + 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(). + */ +static void +png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) +{ + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_uint_16p gamma_16_table = png_ptr->gamma_16_table; + int shift = png_ptr->gamma_shift; + int add = (shift > 0 ? 1U << (shift-1) : 0); + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_gamma"); + + /* Prior to libpng 1.7.0 this code would attempt to gamma correct 2 and 4 bit + * gray level values, the results are ridiculously inaccurate. In 1.7.0 the + * code is removed and a warning is introduced to catch cases where an + * application might actually try it. + */ + 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[0]<<8)+sp[1]+add) >> shift]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; + *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; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; + *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; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; + *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 == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + } + } + + else /*row_info->bit_depth == 16 */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; + *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. + */ +static void +png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp 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) + { + PNG_CONST unsigned int shift = png_ptr->gamma_shift; + PNG_CONST unsigned int add = (shift > 0 ? 1U<<(shift-1) : 0); + + if (row_info->bit_depth == 8) + { + PNG_CONST png_bytep gamma_from_1 = png_ptr->gamma_from_1; + + if (gamma_from_1 != 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 = gamma_from_1[(257U**row+add)>>shift]; + + return; + } + } + + else if (row_info->bit_depth == 16) + { + PNG_CONST png_uint_16p gamma_16_from_1 = png_ptr->gamma_16_from_1; + + if (gamma_16_from_1 != 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 = gamma_16_from_1[((row[0]<<8)+row[1]+add) >> shift]; + *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. + */ +static void +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. + */ +static void +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) + { + unsigned int gray = trans_color ? trans_color->gray : 0; + + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + gray = (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 = (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 = (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) + { + unsigned int gray_high = (gray >> 8) & 0xff; + unsigned int gray_low = 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. + */ +static void +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 +static void +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 */ + +/* 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_structrp 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.6 the new flag is set only for + * all transformations, however in practice the ROW_INIT always gets done on + * demand, if necessary. + */ + 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 != 0) + { + 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->flags & PNG_FLAG_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->flags & PNG_FLAG_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_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_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_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Added at libpng-1.5.10 */ + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, row_info); +#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_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 +} +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngrutil.c b/ext/native/ext/libpng17/pngrutil.c new file mode 100644 index 0000000000..2a9fc896bf --- /dev/null +++ b/ext/native/ext/libpng17/pngrutil.c @@ -0,0 +1,4450 @@ + +/* pngrutil.c - utilities to read a PNG file + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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 + +#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_structrp 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 /* READ_gAMA or READ_cHRM */ + +#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) +{ + return PNG_U32(buf[0], buf[1], buf[2], buf[3]); +} + +/* 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) +{ + return PNG_S32(buf[0], buf[1], buf[2], buf[3]); +} + +/* 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) +{ + return PNG_U16(buf[0], buf[1]); +} +#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ + +/* This is an exported function however its error handling is too harsh for most + * internal use. For example if it were used for reading the chunk parameters + * it would error out even on ancillary chunks that can be ignored. + */ +png_uint_32 PNGAPI +png_get_uint_31(png_const_structrp 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; +} + +/* Read and check the PNG file signature */ +void /* PRIVATE */ +png_read_sig(png_structrp png_ptr, png_inforp 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_structrp 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_structrp png_ptr, png_bytep buf, png_uint_32 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 an 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_structrp png_ptr, png_uint_32 skip) +{ + /* The size of the local buffer for inflate is a good guess as to a + * reasonable size to use for buffering reads from the application. + */ + while (skip > 0) + { + png_uint_32 len; + png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; + + len = (sizeof tmpbuf); + if (len > skip) + len = skip; + skip -= len; + + png_crc_read(png_ptr, tmpbuf, len); + } + + if (png_crc_error(png_ptr)) + { + if (PNG_CHUNK_ANCILLARY(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_error(png_ptr, "CRC error"); + + 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_structrp png_ptr) +{ + png_byte crc_bytes[4]; + png_uint_32 crc; + int need_crc = 1; + + if (PNG_CHUNK_ANCILLARY(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 != 0) + { + crc = png_get_uint_32(crc_bytes); + return ((int)(crc != png_ptr->crc)); + } + + else + return (0); +} + +#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ + defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ + defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ + defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) +/* Manage the read buffer; this simply reallocates the buffer if it is not small + * enough (or if it is not allocated). The routine returns a pointer to the + * buffer; if an error occurs and 'warn' is set the routine returns NULL, else + * it will call png_error (via png_malloc) on failure. (warn == 2 means + * 'silent'). + */ +static png_bytep +png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) +{ + png_bytep buffer = png_ptr->read_buffer; + + if (buffer != NULL && new_size > png_ptr->read_buffer_size) + { + png_ptr->read_buffer = NULL; + png_ptr->read_buffer = NULL; + png_ptr->read_buffer_size = 0; + png_free(png_ptr, buffer); + buffer = NULL; + } + + if (buffer == NULL) + { + buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); + + if (buffer != NULL) + { + png_ptr->read_buffer = buffer; + png_ptr->read_buffer_size = new_size; + } + + else if (warn < 2) /* else silent */ + { + if (warn != 0) + png_chunk_warning(png_ptr, "insufficient memory to read chunk"); + + else + png_chunk_error(png_ptr, "insufficient memory to read chunk"); + } + } + + return buffer; +} +#endif /* PNG_READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ + +/* png_inflate_claim: claim the zstream for some nefarious purpose that involves + * decompression. Returns Z_OK on success, else a zlib error code. It checks + * the owner but, in final release builds, just issues a warning if some other + * chunk apparently owns the stream. Prior to release it does a png_error. + */ +static int +png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) +{ + if (png_ptr->zowner != 0) + { + char msg[64]; + + PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); + /* So the message that results is " using zstream"; this is an + * internal error, but is very useful for debugging. i18n requirements + * are minimal. + */ + (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); +# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC + png_chunk_warning(png_ptr, msg); + png_ptr->zowner = 0; +# else + png_chunk_error(png_ptr, msg); +# endif + } + + /* Implementation note: unlike 'png_deflate_claim' this internal function + * does not take the size of the data as an argument. Some efficiency could + * be gained by using this when it is known *if* the zlib stream itself does + * not record the number; however, this is an illusion: the original writer + * of the PNG may have selected a lower window size, and we really must + * follow that because, for systems with with limited capabilities, we + * would otherwise reject the application's attempts to use a smaller window + * size (zlib doesn't have an interface to say "this or lower"!). + * + * inflateReset2 was added to zlib 1.2.4; before this the window could not be + * reset, therefore it is necessary to always allocate the maximum window + * size with earlier zlibs just in case later compressed chunks need it. + */ + { + int ret; /* zlib return code */ +# if PNG_ZLIB_VERNUM >= 0x1240 + +# if defined(PNG_SET_OPTION_SUPPORTED) && \ + defined(PNG_MAXIMUM_INFLATE_WINDOW) + int window_bits; + + if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == + PNG_OPTION_ON) + window_bits = 15; + + else + window_bits = 0; +# else +# define window_bits 0 +# endif +# endif + + /* Set this for safety, just in case the previous owner left pointers to + * memory allocations. + */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->zstream.avail_out = 0; + + if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) + { +# if PNG_ZLIB_VERNUM < 0x1240 + ret = inflateReset(&png_ptr->zstream); +# else + ret = inflateReset2(&png_ptr->zstream, window_bits); +# endif + } + + else + { +# if PNG_ZLIB_VERNUM < 0x1240 + ret = inflateInit(&png_ptr->zstream); +# else + ret = inflateInit2(&png_ptr->zstream, window_bits); +# endif + + if (ret == Z_OK) + png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; + } + + if (ret == Z_OK) + png_ptr->zowner = owner; + + else + png_zstream_error(png_ptr, ret); + + return ret; + } + +# ifdef window_bits +# undef window_bits +# endif +} + +#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED +/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to + * allow the caller to do multiple calls if required. If the 'finish' flag is + * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must + * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and + * Z_OK or Z_STREAM_END will be returned on success. + * + * The input and output sizes are updated to the actual amounts of data consumed + * or written, not the amount available (as in a z_stream). The data pointers + * are not changed, so the next input is (data+input_size) and the next + * available output is (output+output_size). + */ +static int +png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, + /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, + /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) +{ + if (png_ptr->zowner == owner) /* Else not claimed */ + { + int ret; + png_alloc_size_t avail_out = *output_size_ptr; + png_uint_32 avail_in = *input_size_ptr; + + /* 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 reduces the amount of data accessed + * at each step and that may give the OS more time to page it in. + */ + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); + /* avail_in and avail_out are set below from 'size' */ + png_ptr->zstream.avail_in = 0; + png_ptr->zstream.avail_out = 0; + + /* Read directly into the output if it is available (this is set to + * a local buffer below if output is NULL). + */ + if (output != NULL) + png_ptr->zstream.next_out = output; + + do + { + uInt avail; + Byte local_buffer[PNG_INFLATE_BUF_SIZE]; + + /* zlib INPUT BUFFER */ + /* 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 of 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. + */ + avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ + + avail = ZLIB_IO_MAX; + + if (avail_in < avail) + avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ + + avail_in -= avail; + png_ptr->zstream.avail_in = avail; + + /* zlib OUTPUT BUFFER */ + avail_out += png_ptr->zstream.avail_out; /* not written last time */ + + avail = ZLIB_IO_MAX; /* maximum zlib can process */ + + if (output == NULL) + { + /* Reset the output buffer each time round if output is NULL and + * make available the full buffer, up to 'remaining_space' + */ + png_ptr->zstream.next_out = local_buffer; + if ((sizeof local_buffer) < avail) + avail = (sizeof local_buffer); + } + + if (avail_out < avail) + avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ + + png_ptr->zstream.avail_out = avail; + avail_out -= avail; + + /* zlib inflate call */ + /* In fact 'avail_out' may be 0 at this point, that happens at the end + * of the read when the final LZ end code was not passed at the end of + * the previous chunk of input data. Tell zlib if we have reached the + * end of the output buffer. + */ + ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : + (finish ? Z_FINISH : Z_SYNC_FLUSH)); + } while (ret == Z_OK); + + /* For safety kill the local buffer pointer now */ + if (output == NULL) + png_ptr->zstream.next_out = NULL; + + /* Claw back the 'size' and 'remaining_space' byte counts. */ + avail_in += png_ptr->zstream.avail_in; + avail_out += png_ptr->zstream.avail_out; + + /* Update the input and output sizes; the updated values are the amount + * consumed or written, effectively the inverse of what zlib uses. + */ + if (avail_out > 0) + *output_size_ptr -= avail_out; + + if (avail_in > 0) + *input_size_ptr -= avail_in; + + /* Ensure png_ptr->zstream.msg is set (even in the success case!) */ + png_zstream_error(png_ptr, ret); + return ret; + } + + else + { + /* This is a bad internal error. The recovery assigns to the zstream msg + * pointer, which is not owned by the caller, but this is safe; it's only + * used on errors! + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); + return Z_STREAM_ERROR; + } +} + +/* + * Decompress trailing data in a chunk. The assumption is that read_buffer + * 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). + */ +static int +png_decompress_chunk(png_structrp png_ptr, + png_uint_32 chunklength, png_uint_32 prefix_size, + png_alloc_size_t *newlength /* must be initialized to the maximum! */, + int terminate /*add a '\0' to the end of the uncompressed data*/) +{ + /* TODO: implement different limits for different types of chunk. + * + * The caller supplies *newlength set to the maximum length of the + * uncompressed data, but this routine allocates space for the prefix and + * maybe a '\0' terminator too. We have to assume that 'prefix_size' is + * limited only by the maximum chunk size. + */ + png_alloc_size_t limit = PNG_SIZE_MAX; + +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < limit) + limit = png_ptr->user_chunk_malloc_max; +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 + if (PNG_USER_CHUNK_MALLOC_MAX < limit) + limit = PNG_USER_CHUNK_MALLOC_MAX; +# endif + + if (limit >= prefix_size + (terminate != 0)) + { + int ret; + + limit -= prefix_size + (terminate != 0); + + if (limit < *newlength) + *newlength = limit; + + /* Now try to claim the stream. */ + ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); + + if (ret == Z_OK) + { + png_uint_32 lzsize = chunklength - prefix_size; + + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, + /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, + /* output: */ NULL, newlength); + + if (ret == Z_STREAM_END) + { + /* Use 'inflateReset' here, not 'inflateReset2' because this + * preserves the previously decided window size (otherwise it would + * be necessary to store the previous window size.) In practice + * this doesn't matter anyway, because png_inflate will call inflate + * with Z_FINISH in almost all cases, so the window will not be + * maintained. + */ + if (inflateReset(&png_ptr->zstream) == Z_OK) + { + /* Because of the limit checks above we know that the new, + * expanded, size will fit in a size_t (let alone an + * png_alloc_size_t). Use png_malloc_base here to avoid an + * extra OOM message. + */ + png_alloc_size_t new_size = *newlength; + png_alloc_size_t buffer_size = prefix_size + new_size + + (terminate != 0); + png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, + buffer_size)); + + if (text != NULL) + { + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, + png_ptr->read_buffer + prefix_size, &lzsize, + text + prefix_size, newlength); + + if (ret == Z_STREAM_END) + { + if (new_size == *newlength) + { + if (terminate != 0) + text[prefix_size + *newlength] = 0; + + if (prefix_size > 0) + memcpy(text, png_ptr->read_buffer, prefix_size); + + { + png_bytep old_ptr = png_ptr->read_buffer; + + png_ptr->read_buffer = text; + png_ptr->read_buffer_size = buffer_size; + text = old_ptr; /* freed below */ + } + } + + else + { + /* The size changed on the second read, there can be no + * guarantee that anything is correct at this point. + * The 'msg' pointer has been set to "unexpected end of + * LZ stream", which is fine, but return an error code + * that the caller won't accept. + */ + ret = PNG_UNEXPECTED_ZLIB_RETURN; + } + } + + else if (ret == Z_OK) + ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ + + /* Free the text pointer (this is the old read_buffer on + * success) + */ + png_free(png_ptr, text); + + /* This really is very benign, but it's still an error because + * the extra space may otherwise be used as a Trojan Horse. + */ + if (ret == Z_STREAM_END && + chunklength - prefix_size != lzsize) + png_chunk_benign_error(png_ptr, "extra compressed data"); + } + + else + { + /* Out of memory allocating the buffer */ + ret = Z_MEM_ERROR; + png_zstream_error(png_ptr, Z_MEM_ERROR); + } + } + + else + { + /* inflateReset failed, store the error message */ + png_zstream_error(png_ptr, ret); + + if (ret == Z_STREAM_END) + ret = PNG_UNEXPECTED_ZLIB_RETURN; + } + } + + else if (ret == Z_OK) + ret = PNG_UNEXPECTED_ZLIB_RETURN; + + /* Release the claimed stream */ + png_ptr->zowner = 0; + } + + else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ + ret = PNG_UNEXPECTED_ZLIB_RETURN; + + return ret; + } + + else + { + /* Application/configuration limits exceeded */ + png_zstream_error(png_ptr, Z_MEM_ERROR); + return Z_MEM_ERROR; + } +} +#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ + +#ifdef PNG_READ_iCCP_SUPPORTED +/* Perform a partial read and decompress, producing 'avail_out' bytes and + * reading from the current chunk as required. + */ +static int +png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, + png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, + int finish) +{ + if (png_ptr->zowner == png_ptr->chunk_name) + { + int ret; + + /* next_in and avail_in must have been initialized by the caller. */ + png_ptr->zstream.next_out = next_out; + png_ptr->zstream.avail_out = 0; /* set in the loop */ + + do + { + if (png_ptr->zstream.avail_in == 0) + { + if (read_size > *chunk_bytes) + read_size = (uInt)*chunk_bytes; + *chunk_bytes -= read_size; + + if (read_size > 0) + png_crc_read(png_ptr, read_buffer, read_size); + + png_ptr->zstream.next_in = read_buffer; + png_ptr->zstream.avail_in = read_size; + } + + if (png_ptr->zstream.avail_out == 0) + { + uInt avail = ZLIB_IO_MAX; + if (avail > *out_size) + avail = (uInt)*out_size; + *out_size -= avail; + + png_ptr->zstream.avail_out = avail; + } + + /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all + * the available output is produced; this allows reading of truncated + * streams. + */ + ret = inflate(&png_ptr->zstream, + *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); + } + while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); + + *out_size += png_ptr->zstream.avail_out; + png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ + + /* Ensure the error message pointer is always set: */ + png_zstream_error(png_ptr, ret); + return ret; + } + + else + { + png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); + return Z_STREAM_ERROR; + } +} +#endif + +/* Read and check the IDHR chunk */ +void /* PRIVATE */ +png_handle_IHDR(png_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "out of place"); + + /* Check the length */ + if (length != 13) + png_chunk_error(png_ptr, "invalid"); + + 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_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "missing IHDR"); + + /* Moved to before the 'after IDAT' check below because otherwise duplicate + * PLTE chunks are potentially ignored (the spec says there shall not be more + * than one PLTE, the error is not treated as benign, so this check trumps + * the requirement that PLTE appears before IDAT.) + */ + else if (png_ptr->mode & PNG_HAVE_PLTE) + png_chunk_error(png_ptr, "duplicate"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + /* This is benign because the non-benign error happened before, when an + * IDAT was encountered in a color-mapped image with no PLTE. + */ + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + png_ptr->mode |= PNG_HAVE_PLTE; + + if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); + 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) + { + png_crc_finish(png_ptr, length); + + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + png_chunk_benign_error(png_ptr, "invalid"); + + else + png_chunk_error(png_ptr, "invalid"); + + return; + } + + /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ + 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). + * + * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the + * chunk type to determine whether to check the ancillary or the critical + * flags. + */ + if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) + { + if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) + return; + + else + png_chunk_error(png_ptr, "CRC error"); + } + + /* 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 + + /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its + * own copy of the palette. This has the side effect that when png_start_row + * is called (this happens after any call to png_read_update_info) the + * info_ptr palette gets changed. This is extremely unexpected and + * confusing. + * + * Fix this by not sharing the palette in this way. + */ + png_set_PLTE(png_ptr, info_ptr, palette, num); + + /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before + * IDAT. Prior to 1.6.0 this was not checked; instead the code merely + * checked the apparent validity of a tRNS chunk inserted before PLTE on a + * palette PNG. 1.6.0 attempts to rigorously follow the standard and + * therefore does a benign error if the erroneous condition is detected *and* + * cancels the tRNS if the benign error returns. The alternative is to + * amend the standard since it would be rather hypocritical of the standards + * maintainers to ignore it. + */ +#ifdef PNG_READ_tRNS_SUPPORTED + if (png_ptr->num_trans > 0 || + (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) + { + /* Cancel this because otherwise it would be used if the transforms + * require it. Don't cancel the 'valid' flag because this would prevent + * detection of duplicate chunks. + */ + png_ptr->num_trans = 0; + + if (info_ptr != NULL) + info_ptr->num_trans = 0; + + png_chunk_benign_error(png_ptr, "tRNS must be after"); + } +#endif + +#ifdef PNG_READ_hIST_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) + png_chunk_benign_error(png_ptr, "hIST must be after"); +#endif + +#ifdef PNG_READ_bKGD_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) + png_chunk_benign_error(png_ptr, "bKGD must be after"); +#endif +} + +void /* PRIVATE */ +png_handle_IEND(png_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "out of place"); + + png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); + + png_crc_finish(png_ptr, length); + + if (length != 0) + png_chunk_benign_error(png_ptr, "invalid"); + + PNG_UNUSED(info_ptr) +} + +#ifdef PNG_READ_gAMA_SUPPORTED +void /* PRIVATE */ +png_handle_gAMA(png_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + if (length != 4) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_crc_read(png_ptr, buf, 4); + + if (png_crc_finish(png_ptr, 0)) + return; + + igamma = png_get_fixed_point(NULL, buf); + + png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); + png_colorspace_sync(png_ptr, info_ptr); +} +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED +void /* PRIVATE */ +png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + unsigned int truelen, i; + png_byte sample_depth; + png_byte buf[4]; + + png_debug(1, "in png_handle_sBIT"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + truelen = 3; + sample_depth = 8; + } + + else + { + truelen = png_ptr->channels; + sample_depth = png_ptr->bit_depth; + } + + if (length != truelen || length > 4) + { + png_chunk_benign_error(png_ptr, "invalid"); + png_crc_finish(png_ptr, length); + return; + } + + buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; + png_crc_read(png_ptr, buf, truelen); + + if (png_crc_finish(png_ptr, 0)) + return; + + for (i=0; i sample_depth) + { + png_chunk_benign_error(png_ptr, "invalid"); + 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_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[32]; + png_xy xy; + + png_debug(1, "in png_handle_cHRM"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + if (length != 32) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_crc_read(png_ptr, buf, 32); + + if (png_crc_finish(png_ptr, 0)) + return; + + xy.whitex = png_get_fixed_point(NULL, buf); + xy.whitey = png_get_fixed_point(NULL, buf + 4); + xy.redx = png_get_fixed_point(NULL, buf + 8); + xy.redy = png_get_fixed_point(NULL, buf + 12); + xy.greenx = png_get_fixed_point(NULL, buf + 16); + xy.greeny = png_get_fixed_point(NULL, buf + 20); + xy.bluex = png_get_fixed_point(NULL, buf + 24); + xy.bluey = png_get_fixed_point(NULL, buf + 28); + + if (xy.whitex == PNG_FIXED_ERROR || + xy.whitey == PNG_FIXED_ERROR || + xy.redx == PNG_FIXED_ERROR || + xy.redy == PNG_FIXED_ERROR || + xy.greenx == PNG_FIXED_ERROR || + xy.greeny == PNG_FIXED_ERROR || + xy.bluex == PNG_FIXED_ERROR || + xy.bluey == PNG_FIXED_ERROR) + { + png_chunk_benign_error(png_ptr, "invalid values"); + return; + } + + /* If a colorspace error has already been output skip this chunk */ + if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) + return; + + if (png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) + { + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; + png_colorspace_sync(png_ptr, info_ptr); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; + (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, + 1/*prefer cHRM values*/); + png_colorspace_sync(png_ptr, info_ptr); +} +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED +void /* PRIVATE */ +png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte intent; + + png_debug(1, "in png_handle_sRGB"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + if (length != 1) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_crc_read(png_ptr, &intent, 1); + + if (png_crc_finish(png_ptr, 0)) + return; + + /* If a colorspace error has already been output skip this chunk */ + if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) + return; + + /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect + * this. + */ + if (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) + { + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; + png_colorspace_sync(png_ptr, info_ptr); + png_chunk_benign_error(png_ptr, "too many profiles"); + return; + } + + (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); + png_colorspace_sync(png_ptr, info_ptr); +} +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef PNG_READ_iCCP_SUPPORTED +void /* PRIVATE */ +png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +/* Note: this does not properly handle profiles that are > 64K under DOS */ +{ + png_const_charp errmsg = NULL; /* error message output, or no error */ + int finished = 0; /* crc checked */ + + png_debug(1, "in png_handle_iCCP"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + /* Consistent with all the above colorspace handling an obviously *invalid* + * chunk is just ignored, so does not invalidate the color space. An + * alternative is to set the 'invalid' flags at the start of this routine + * and only clear them in they were not set before and all the tests pass. + * The minimum 'deflate' stream is assumed to be just the 2 byte header and 4 + * byte checksum. The keyword must be one character and there is a + * terminator (0) byte and the compression method. + */ + if (length < 9) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too short"); + return; + } + + /* If a colorspace error has already been output skip this chunk */ + if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) + { + png_crc_finish(png_ptr, length); + return; + } + + /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect + * this. + */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) + { + uInt read_length, keyword_length; + char keyword[81]; + + /* Find the keyword; the keyword plus separator and compression method + * bytes can be at most 81 characters long. + */ + read_length = 81; /* maximum */ + if (read_length > length) + read_length = (uInt)length; + + png_crc_read(png_ptr, (png_bytep)keyword, read_length); + length -= read_length; + + keyword_length = 0; + while (keyword_length < 80 && keyword_length < read_length && + keyword[keyword_length] != 0) + ++keyword_length; + + /* TODO: make the keyword checking common */ + if (keyword_length >= 1 && keyword_length <= 79) + { + /* We only understand '0' compression - deflate - so if we get a + * different value we can't safely decode the chunk. + */ + if (keyword_length+1 < read_length && + keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) + { + read_length -= keyword_length+2; + + if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) + { + Byte profile_header[132]; + Byte local_buffer[PNG_INFLATE_BUF_SIZE]; + png_alloc_size_t size = (sizeof profile_header); + + png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); + png_ptr->zstream.avail_in = read_length; + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, profile_header, &size, + 0/*finish: don't, because the output is too small*/); + + if (size == 0) + { + /* We have the ICC profile header; do the basic header checks. + */ + const png_uint_32 profile_length = + png_get_uint_32(profile_header); + + if (png_icc_check_length(png_ptr, &png_ptr->colorspace, + keyword, profile_length)) + { + /* The length is apparently ok, so we can check the 132 + * byte header. + */ + if (png_icc_check_header(png_ptr, &png_ptr->colorspace, + keyword, profile_length, profile_header, + png_ptr->color_type)) + { + /* Now read the tag table; a variable size buffer is + * needed at this point, allocate one for the whole + * profile. The header check has already validated + * that none of these stuff will overflow. + */ + const png_uint_32 tag_count = png_get_uint_32( + profile_header+128); + png_bytep profile = png_read_buffer(png_ptr, + profile_length, 2/*silent*/); + + if (profile != NULL) + { + memcpy(profile, profile_header, + (sizeof profile_header)); + + size = 12 * tag_count; + + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, + profile + (sizeof profile_header), &size, 0); + + /* Still expect a buffer error because we expect + * there to be some tag data! + */ + if (size == 0) + { + if (png_icc_check_tag_table(png_ptr, + &png_ptr->colorspace, keyword, profile_length, + profile)) + { + /* The profile has been validated for basic + * security issues, so read the whole thing in. + */ + size = profile_length - (sizeof profile_header) + - 12 * tag_count; + + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, + profile + (sizeof profile_header) + + 12 * tag_count, &size, 1/*finish*/); + + if (length > 0 && !(png_ptr->flags & + PNG_FLAG_BENIGN_ERRORS_WARN)) + errmsg = "extra compressed data"; + + /* But otherwise allow extra data: */ + else if (size == 0) + { + if (length > 0) + { + /* This can be handled completely, so + * keep going. + */ + png_chunk_warning(png_ptr, + "extra compressed data"); + } + + png_crc_finish(png_ptr, length); + finished = 1; + +# ifdef PNG_sRGB_SUPPORTED + /* Check for a match against sRGB */ + png_icc_set_sRGB(png_ptr, + &png_ptr->colorspace, profile, + png_ptr->zstream.adler); +# endif + + /* Steal the profile for info_ptr. */ + if (info_ptr != NULL) + { + png_free_data(png_ptr, info_ptr, + PNG_FREE_ICCP, 0); + + info_ptr->iccp_name = png_voidcast(char*, + png_malloc_base(png_ptr, + keyword_length+1)); + if (info_ptr->iccp_name != NULL) + { + memcpy(info_ptr->iccp_name, keyword, + keyword_length+1); + info_ptr->iccp_proflen = + profile_length; + info_ptr->iccp_profile = profile; + png_ptr->read_buffer = NULL; /*steal*/ + info_ptr->free_me |= PNG_FREE_ICCP; + info_ptr->valid |= PNG_INFO_iCCP; + } + + else + { + png_ptr->colorspace.flags |= + PNG_COLORSPACE_INVALID; + errmsg = "out of memory"; + } + } + + /* else the profile remains in the read + * buffer which gets reused for subsequent + * chunks. + */ + + if (info_ptr != NULL) + png_colorspace_sync(png_ptr, info_ptr); + + if (errmsg == NULL) + { + png_ptr->zowner = 0; + return; + } + } + + else if (size > 0) + errmsg = "truncated"; + + else + errmsg = png_ptr->zstream.msg; + } + + /* else png_icc_check_tag_table output an error */ + } + + else /* profile truncated */ + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "out of memory"; + } + + /* else png_icc_check_header output an error */ + } + + /* else png_icc_check_length output an error */ + } + + else /* profile truncated */ + errmsg = png_ptr->zstream.msg; + + /* Release the stream */ + png_ptr->zowner = 0; + } + + else /* png_inflate_claim failed */ + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "bad compression method"; /* or missing */ + } + + else + errmsg = "bad keyword"; + } + + else + errmsg = "too many profiles"; + + /* Failure: the reason is in 'errmsg' */ + if (finished == 0) + png_crc_finish(png_ptr, length); + + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; + png_colorspace_sync(png_ptr, info_ptr); + if (errmsg != NULL) /* else already output */ + png_chunk_benign_error(png_ptr, errmsg); +} +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#ifdef PNG_READ_sPLT_SUPPORTED +void /* PRIVATE */ +png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_bytep entry_start, buffer; + png_sPLT_t new_palette; + png_sPLT_entryp pp; + png_uint_32 data_length; + int entry_size, i; + png_uint_32 skip = 0; + 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) + { + /* Warn the first time */ + png_chunk_benign_error(png_ptr, "chunk cache full"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > 65535U) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too large to fit in memory"); + return; + } +#endif + + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + + + /* 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. + */ + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, skip)) + return; + + buffer[length] = 0; + + for (entry_start = buffer; *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 > buffer + length - 2) + { + 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. + */ + data_length = length - (png_uint_32)(entry_start - buffer); + + /* Integrity-check the data length */ + if (data_length % entry_size) + { + png_warning(png_ptr, "sPLT chunk has bad length"); + return; + } + + dl = (png_int_32)(data_length / entry_size); + max_dl = PNG_SIZE_MAX / (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 * (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_charp)buffer; + + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); + + png_free(png_ptr, new_palette.entries); +} +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#ifdef PNG_READ_tRNS_SUPPORTED +void /* PRIVATE */ +png_handle_tRNS(png_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + png_byte buf[2]; + + if (length != 2) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + 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_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_crc_read(png_ptr, buf, 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)) + { + /* TODO: is this actually an error in the ISO spec? */ + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH || + length == 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_crc_read(png_ptr, readbuf, length); + png_ptr->num_trans = (png_uint_16)length; + } + + else + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid with alpha channel"); + return; + } + + if (png_crc_finish(png_ptr, 0)) + { + png_ptr->num_trans = 0; + return; + } + + /* TODO: this is a horrible side effect in the palette case because the + * png_struct ends up with a pointer to the tRNS buffer owned by the + * png_info. Fix this. + */ + png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, + &(png_ptr->trans_color)); + + png_ptr->trans_alpha = info_ptr->trans_alpha; +} +#endif + +#ifdef PNG_READ_bKGD_SUPPORTED +void /* PRIVATE */ +png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + unsigned int truelen; + png_byte buf[6]; + png_color_16 background; + + png_debug(1, "in png_handle_bKGD"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + else if ((png_ptr->mode & PNG_HAVE_IDAT) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE))) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + 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_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + 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_chunk_benign_error(png_ptr, "invalid index"); + 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_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "missing IHDR"); + + else if ((png_ptr->mode & PNG_HAVE_IDAT) || !(png_ptr->mode & PNG_HAVE_PLTE)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + num = length / 2 ; + + if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + 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_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + if (length != 9) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + 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_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + if (length != 9) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + 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_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_int_32 X0, X1; + png_byte type, nparams; + png_bytep buffer, buf, units, endptr; + png_charpp params; + int i; + + png_debug(1, "in png_handle_pCAL"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", + length + 1); + + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, 0)) + return; + + buffer[length] = 0; /* Null terminate the last string */ + + png_debug(3, "Finding end of pCAL purpose string"); + for (buf = buffer; *buf; buf++) + /* Empty loop */ ; + + endptr = buffer + length; + + /* We need to have at least 12 bytes after the purpose string + * in order to get the parameter information. + */ + if (endptr <= buf + 12) + { + png_chunk_benign_error(png_ptr, "invalid"); + 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_chunk_benign_error(png_ptr, "invalid parameter count"); + return; + } + + else if (type >= PNG_EQUATION_LAST) + { + png_chunk_benign_error(png_ptr, "unrecognized equation type"); + } + + for (buf = units; *buf; buf++) + /* Empty loop to move past the units string. */ ; + + png_debug(3, "Allocating pCAL parameters array"); + + params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, + nparams * (sizeof (png_charp)))); + + if (params == NULL) + { + png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + + /* Get pointers to the start of each parameter string. */ + for (i = 0; i < nparams; i++) + { + buf++; /* Skip the null string terminator from previous parameter. */ + + png_debug1(3, "Reading pCAL parameter %d", i); + + for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) + /* Empty loop to move past each parameter string */ ; + + /* Make sure we haven't run out of data yet */ + if (buf > endptr) + { + png_free(png_ptr, params); + png_chunk_benign_error(png_ptr, "invalid data"); + return; + } + } + + png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, + (png_charp)units, params); + + png_free(png_ptr, params); +} +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED +/* Read the sCAL chunk */ +void /* PRIVATE */ +png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_bytep buffer; + png_size_t i; + int state; + + png_debug(1, "in png_handle_sCAL"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + /* Need unit type, width, \0, height: minimum 4 bytes */ + else if (length < 4) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", + length + 1); + + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); + + if (buffer == NULL) + { + png_chunk_benign_error(png_ptr, "out of memory"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buffer, length); + buffer[length] = 0; /* Null terminate the last string */ + + if (png_crc_finish(png_ptr, 0)) + return; + + /* Validate the unit. */ + if (buffer[0] != 1 && buffer[0] != 2) + { + png_chunk_benign_error(png_ptr, "invalid unit"); + 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_const_charp)buffer, length, &state, &i) || + i >= length || buffer[i++] != 0) + png_chunk_benign_error(png_ptr, "bad width format"); + + else if (!PNG_FP_IS_POSITIVE(state)) + png_chunk_benign_error(png_ptr, "non-positive width"); + + else + { + png_size_t heighti = i; + + state = 0; + if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) || + i != length) + png_chunk_benign_error(png_ptr, "bad height format"); + + else if (!PNG_FP_IS_POSITIVE(state)) + png_chunk_benign_error(png_ptr, "non-positive height"); + + else + /* This is the (only) success case. */ + png_set_sCAL_s(png_ptr, info_ptr, buffer[0], + (png_charp)buffer+1, (png_charp)buffer+heighti); + } +} +#endif + +#ifdef PNG_READ_tIME_SUPPORTED +void /* PRIVATE */ +png_handle_tIME(png_structrp png_ptr, png_inforp 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_chunk_error(png_ptr, "missing IHDR"); + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + + if (length != 7) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + 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_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_text text_info; + png_bytep buffer; + png_charp key; + png_charp text; + png_uint_32 skip = 0; + + 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_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "chunk cache full"); + return; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + if (length > 65535U) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too large to fit in memory"); + return; + } +#endif + + buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); + + if (buffer == NULL) + { + png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, skip)) + return; + + key = (png_charp)buffer; + key[length] = 0; + + for (text = key; *text; text++) + /* Empty loop to find end of key */ ; + + if (text != key + length) + text++; + + text_info.compression = PNG_TEXT_COMPRESSION_NONE; + text_info.key = key; + text_info.lang = NULL; + text_info.lang_key = NULL; + text_info.itxt_length = 0; + text_info.text = text; + text_info.text_length = strlen(text); + + if (png_set_text_2(png_ptr, info_ptr, &text_info, 1)) + 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_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_const_charp errmsg = NULL; + png_bytep buffer; + png_uint_32 keyword_length; + + 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_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "chunk cache full"); + return; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + + buffer = png_read_buffer(png_ptr, length, 2/*silent*/); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, 0)) + return; + + /* TODO: also check that the keyword contents match the spec! */ + for (keyword_length = 0; + keyword_length < length && buffer[keyword_length] != 0; + ++keyword_length) + /* Empty loop to find end of name */ ; + + if (keyword_length > 79 || keyword_length < 1) + errmsg = "bad keyword"; + + /* zTXt must have some LZ data after the keyword, although it may expand to + * zero bytes; we need a '\0' at the end of the keyword, the compression type + * then the LZ data: + */ + else if (keyword_length + 3 > length) + errmsg = "truncated"; + + else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) + errmsg = "unknown compression type"; + + else + { + png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; + + /* TODO: at present png_decompress_chunk imposes a single application + * level memory limit, this should be split to different values for iCCP + * and text chunks. + */ + if (png_decompress_chunk(png_ptr, length, keyword_length+2, + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) + { + png_text text; + + /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except + * for the extra compression type byte and the fact that it isn't + * necessarily '\0' terminated. + */ + buffer = png_ptr->read_buffer; + buffer[uncompressed_length+(keyword_length+2)] = 0; + + text.compression = PNG_TEXT_COMPRESSION_zTXt; + text.key = (png_charp)buffer; + text.text = (png_charp)(buffer + keyword_length+2); + text.text_length = uncompressed_length; + text.itxt_length = 0; + text.lang = NULL; + text.lang_key = NULL; + + if (png_set_text_2(png_ptr, info_ptr, &text, 1)) + errmsg = "insufficient memory"; + } + + else + errmsg = png_ptr->zstream.msg; + } + + if (errmsg != NULL) + png_chunk_benign_error(png_ptr, errmsg); +} +#endif + +#ifdef PNG_READ_iTXt_SUPPORTED +/* Note: this does not correctly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_const_charp errmsg = NULL; + png_bytep buffer; + png_uint_32 prefix_length; + + 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_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "chunk cache full"); + return; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_chunk_error(png_ptr, "missing IHDR"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + + buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, 0)) + return; + + /* First the keyword. */ + for (prefix_length=0; + prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) + /* Empty loop */ ; + + /* Perform a basic check on the keyword length here. */ + if (prefix_length > 79 || prefix_length < 1) + errmsg = "bad keyword"; + + /* Expect keyword, compression flag, compression type, language, translated + * keyword (both may be empty but are 0 terminated) then the text, which may + * be empty. + */ + else if (prefix_length + 5 > length) + errmsg = "truncated"; + + else if (buffer[prefix_length+1] == 0 || + (buffer[prefix_length+1] == 1 && + buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) + { + int compressed = buffer[prefix_length+1] != 0; + png_uint_32 language_offset, translated_keyword_offset; + png_alloc_size_t uncompressed_length = 0; + + /* Now the language tag */ + prefix_length += 3; + language_offset = prefix_length; + + for (; prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) + /* Empty loop */ ; + + /* WARNING: the length may be invalid here, this is checked below. */ + translated_keyword_offset = ++prefix_length; + + for (; prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) + /* Empty loop */ ; + + /* prefix_length should now be at the trailing '\0' of the translated + * keyword, but it may already be over the end. None of this arithmetic + * can overflow because chunks are at most 2^31 bytes long, but on 16-bit + * systems the available allocaton may overflow. + */ + ++prefix_length; + + if (!compressed && prefix_length <= length) + uncompressed_length = length - prefix_length; + + else if (compressed && prefix_length < length) + { + uncompressed_length = PNG_SIZE_MAX; + + /* TODO: at present png_decompress_chunk imposes a single application + * level memory limit, this should be split to different values for + * iCCP and text chunks. + */ + if (png_decompress_chunk(png_ptr, length, prefix_length, + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) + buffer = png_ptr->read_buffer; + + else + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "truncated"; + + if (errmsg == NULL) + { + png_text text; + + buffer[uncompressed_length+prefix_length] = 0; + + if (compressed != 0) + text.compression = PNG_ITXT_COMPRESSION_NONE; + + else + text.compression = PNG_ITXT_COMPRESSION_zTXt; + + text.key = (png_charp)buffer; + text.lang = (png_charp)buffer + language_offset; + text.lang_key = (png_charp)buffer + translated_keyword_offset; + text.text = (png_charp)buffer + prefix_length; + text.text_length = 0; + text.itxt_length = uncompressed_length; + + if (png_set_text_2(png_ptr, info_ptr, &text, 1)) + errmsg = "insufficient memory"; + } + } + + else + errmsg = "bad compression info"; + + if (errmsg != NULL) + png_chunk_benign_error(png_ptr, errmsg); +} +#endif + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ +static int +png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) +{ + png_alloc_size_t limit = PNG_SIZE_MAX; + + if (png_ptr->unknown_chunk.data != NULL) + { + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < limit) + limit = png_ptr->user_chunk_malloc_max; + +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 + if (PNG_USER_CHUNK_MALLOC_MAX < limit) + limit = PNG_USER_CHUNK_MALLOC_MAX; +# endif + + if (length <= limit) + { + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); + /* The following is safe because of the PNG_SIZE_MAX init above */ + png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/; + /* 'mode' is a flag array, only the bottom four bits matter here */ + png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; + + if (length == 0) + png_ptr->unknown_chunk.data = NULL; + + else + { + /* Do a 'warn' here - it is handled below. */ + png_ptr->unknown_chunk.data = png_voidcast(png_bytep, + png_malloc_warn(png_ptr, length)); + } + } + + if (png_ptr->unknown_chunk.data == NULL && length > 0) + { + /* This is benign because we clean up correctly */ + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); + return 0; + } + + else + { + if (length > 0) + png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); + png_crc_finish(png_ptr, 0); + return 1; + } +} +#endif /* PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ + +/* Handle an unknown, or known but disabled, chunk */ +void /* PRIVATE */ +png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, + png_uint_32 length, int keep) +{ + int handled = 0; /* the chunk was handled */ + + png_debug(1, "in png_handle_unknown"); + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing + * the bug which meant that setting a non-default behavior for a specific + * chunk would be ignored (the default was always used unless a user + * callback was installed). + * + * 'keep' is the value from the png_chunk_unknown_handling, the setting for + * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it + * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. + * This is just an optimization to avoid multiple calls to the lookup + * function. + */ +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); +# endif +# endif + + /* One of the following methods will read the chunk or skip it (at least one + * of these is always defined because this is the only way to switch on + * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + */ +# ifdef PNG_READ_USER_CHUNKS_SUPPORTED + /* The user callback takes precedence over the chunk keep value, but the + * keep value is still required to validate a save of a critical chunk. + */ + if (png_ptr->read_user_chunk_fn != NULL) + { + if (png_cache_unknown_chunk(png_ptr, length)) + { + /* Callback to user unknown chunk handler */ + int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, + &png_ptr->unknown_chunk); + + /* ret is: + * negative: An error occured, png_chunk_error will be called. + * zero: The chunk was not handled, the chunk will be discarded + * unless png_set_keep_unknown_chunks has been used to set + * a 'keep' behavior for this particular chunk, in which + * case that will be used. A critical chunk will cause an + * error at this point unless it is to be saved. + * positive: The chunk was handled, libpng will ignore/discard it. + */ + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + + else if (ret == 0) + { + /* Use the default handling, note that if there is per-chunk + * handling specified it has already been set into 'keep'. + * + * NOTE: this is an API change in 1.7.0. Prior to 1.7.0 libpng + * would force keep to PNG_HANDLE_CHUNK_IF_SAFE at this point, + * and 1.6.0 would issue a warning if this caused a default of + * discarding the chunk to be changed. + */ + if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) + keep = png_ptr->unknown_default; + } + + else /* chunk was handled */ + { + handled = 1; + /* Critical chunks can be safely discarded at this point. */ + keep = PNG_HANDLE_CHUNK_NEVER; + } + } + + else + keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ + } + + else + /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ +# endif /* PNG_READ_USER_CHUNKS_SUPPORTED */ + +# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED + { + /* keep is currently just the per-chunk setting, if there was no + * setting change it to the global default now (not that this may + * still be AS_DEFAULT) then obtain the cache of the chunk if required, + * if not simply skip the chunk. + */ + if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) + keep = png_ptr->unknown_default; + + if (keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_IF_SAFE && + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) + { + if (!png_cache_unknown_chunk(png_ptr, length)) + keep = PNG_HANDLE_CHUNK_NEVER; + } + + else + png_crc_finish(png_ptr, length); + } +# else +# ifndef PNG_READ_USER_CHUNKS_SUPPORTED +# error no method to support READ_UNKNOWN_CHUNKS +# endif + + { + /* If here there is no read callback pointer set and no support is + * compiled in to just save the unknown chunks, so simply skip this + * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then + * the app has erroneously asked for unknown chunk saving when there + * is no support. + */ + if (keep > PNG_HANDLE_CHUNK_NEVER) + png_app_error(png_ptr, "no unknown chunk support available"); + + png_crc_finish(png_ptr, length); + } +# endif + +# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + /* Now store the chunk in the chunk list if appropriate, and if the limits + * permit it. + */ + if (keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_IF_SAFE && + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) + { +# ifdef PNG_USER_LIMITS_SUPPORTED + switch (png_ptr->user_chunk_cache_max) + { + case 2: + png_ptr->user_chunk_cache_max = 1; + png_chunk_benign_error(png_ptr, "chunk cache full"); + /* FALL THROUGH */ + case 1: + /* NOTE: prior to 1.6.0 this case resulted in an unknown critical + * chunk being skipped, now there will be a hard error below. + */ + break; + + default: /* not at limit */ + --(png_ptr->user_chunk_cache_max); + /* FALL THROUGH */ + case 0: /* no limit */ +# endif /* PNG_USER_LIMITS_SUPPORTED */ + /* Here when the limit isn't reached or when limits are compiled + * out; store the chunk. + */ + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + handled = 1; +# ifdef PNG_USER_LIMITS_SUPPORTED + break; + } +# endif + } +# else /* no store support: the chunk must be handled by the user callback */ + PNG_UNUSED(info_ptr) +# endif + + /* Regardless of the error handling below the cached data (if any) can be + * freed now. Notice that the data is not freed if there is a png_error, but + * it will be freed by destroy_read_struct. + */ + if (png_ptr->unknown_chunk.data != NULL) + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + +#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ + /* There is no support to read an unknown chunk, so just skip it. */ + png_crc_finish(png_ptr, length); + PNG_UNUSED(info_ptr) + PNG_UNUSED(keep) +#endif /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ + + /* Check for unhandled critical chunks */ + if (!handled && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + png_chunk_error(png_ptr, "unhandled critical chunk"); +} + +/* 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_structrp 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_const_structrp 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 memcpy(). A 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), B_MASK(3,d,s), B_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 != 0) + { + /* 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 memcpy there. + */ + if (bytes_to_copy < 16 /*else use 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_aligncast(png_uint_32p,dp); + png_const_uint_32p sp32 = png_aligncastconst( + png_const_uint_32p, sp); + size_t 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_aligncast(png_uint_16p, dp); + png_const_uint_16p sp16 = png_aligncastconst( + png_const_uint_16p, sp); + size_t 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 memcpy: */ + for (;;) + { + 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 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.) + */ + 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++) + { + unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); + tmp |= v << dshift; + *dp = (png_byte)(tmp & 0xff); + + 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++) + { + unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); + tmp |= v << dshift; + *dp = (png_byte)(tmp & 0xff); + + 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++) + { + unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); + tmp |= v << dshift; + *dp = (png_byte)(tmp & 0xff); + + 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]; /* SAFE; pixel_depth does not exceed 64 */ + int j; + + memcpy(v, sp, pixel_bytes); + + for (j = 0; j < jstop; j++) + { + 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; + + a += *row; + *row++ = (png_byte)a; + } +} + +static void +png_init_filter_functions(png_structrp pp) + /* This function is called once for every PNG image (except for PNG images + * that only use PNG_FILTER_VALUE_NONE for all rows) to set the + * implementations required to reverse the filtering of PNG rows. Reversing + * the filter is the first transformation performed on the row data. It is + * performed in place, therefore an implementation can be selected based on + * the image pixel format. If the implementation depends on image width then + * take care to ensure that it works correctly if the image is interlaced - + * interlacing causes the actual row width to vary. + */ +{ + 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_FILTER_OPTIMIZATIONS + /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to + * call to install hardware optimizations for the above functions; simply + * replace whatever elements of the pp->read_filter[] array with a hardware + * specific (or, for that matter, generic) optimization. + * + * To see an example of this examine what configure.ac does when + * --enable-arm-neon is specified on the command line. + */ + PNG_FILTER_OPTIMIZATIONS(pp, bpp); +#endif +} + +void /* PRIVATE */ +png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, + png_const_bytep prev_row, int filter) +{ + /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define + * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic + * implementations. See png_init_filter_functions above. + */ + if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) + { + if (pp->read_filter[0] == NULL) + png_init_filter_functions(pp); + + pp->read_filter[filter-1](row_info, row, prev_row); + } +} + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +void /* PRIVATE */ +png_read_IDAT_data(png_structrp png_ptr, png_bytep output, + png_alloc_size_t avail_out) +{ + /* Loop reading IDATs and decompressing the result into output[avail_out] */ + png_ptr->zstream.next_out = output; + png_ptr->zstream.avail_out = 0; /* safety: set below */ + + if (output == NULL) + avail_out = 0; + + do + { + int ret; + png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; + + if (png_ptr->zstream.avail_in == 0) + { + uInt avail_in; + png_bytep buffer; + + while (png_ptr->idat_size == 0) + { + png_crc_finish(png_ptr, 0); + + png_ptr->idat_size = png_read_chunk_header(png_ptr); + /* This is an error even in the 'check' case because the code just + * consumed a non-IDAT header. + */ + if (png_ptr->chunk_name != png_IDAT) + png_error(png_ptr, "Not enough image data"); + } + + avail_in = png_ptr->IDAT_read_size; + + if (avail_in > png_ptr->idat_size) + avail_in = (uInt)png_ptr->idat_size; + + /* A PNG with a gradually increasing IDAT size will defeat this attempt + * to minimize memory usage by causing lots of re-allocs, but + * realistically doing IDAT_read_size re-allocs is not likely to be a + * big problem. + */ + buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/); + + png_crc_read(png_ptr, buffer, avail_in); + png_ptr->idat_size -= avail_in; + + png_ptr->zstream.next_in = buffer; + png_ptr->zstream.avail_in = avail_in; + } + + /* And set up the output side. */ + if (output != NULL) /* standard read */ + { + uInt out = ZLIB_IO_MAX; + + if (out > avail_out) + out = (uInt)avail_out; + + avail_out -= out; + png_ptr->zstream.avail_out = out; + } + + else /* after last row, checking for end */ + { + png_ptr->zstream.next_out = tmpbuf; + png_ptr->zstream.avail_out = (sizeof tmpbuf); + } + + /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the + * process. If the LZ stream is truncated the sequential reader will + * terminally damage the stream, above, by reading the chunk header of the + * following chunk (it then exits with png_error). + * + * TODO: deal more elegantly with truncated IDAT lists. + */ + ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); + + /* Take the unconsumed output back. */ + if (output != NULL) + avail_out += png_ptr->zstream.avail_out; + + else /* avail_out counts the extra bytes */ + avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out; + + png_ptr->zstream.avail_out = 0; + + if (ret == Z_STREAM_END) + { + /* Do this for safety; we won't read any more into this row. */ + png_ptr->zstream.next_out = NULL; + + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + + if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) + png_chunk_benign_error(png_ptr, "Extra compressed data"); + break; + } + + if (ret != Z_OK) + { + png_zstream_error(png_ptr, ret); + + if (output != NULL) + png_chunk_error(png_ptr, png_ptr->zstream.msg); + + else /* checking */ + { + png_chunk_benign_error(png_ptr, png_ptr->zstream.msg); + return; + } + } + } while (avail_out > 0); + + if (avail_out > 0) + { + /* The stream ended before the image; this is the same as too few IDATs so + * should be handled the same way. + */ + if (output != NULL) + png_error(png_ptr, "Not enough image data"); + + else /* the deflate stream contained extra data */ + png_chunk_benign_error(png_ptr, "Too much image data"); + } +} + +void /* PRIVATE */ +png_read_finish_IDAT(png_structrp png_ptr) +{ + /* We don't need any more data and the stream should have ended, however the + * LZ end code may actually not have been processed. In this case we must + * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk + * may still remain to be consumed. + */ + if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) + { + /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in + * the compressed stream, but the stream may be damaged too, so even after + * this call we may need to terminate the zstream ownership. + */ + png_read_IDAT_data(png_ptr, NULL, 0); + png_ptr->zstream.next_out = NULL; /* safety */ + + /* Now clear everything out for safety; the following may not have been + * done. + */ + if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) + { + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + } + } + + /* If the zstream has not been released do it now *and* terminate the reading + * of the final IDAT chunk. + */ + if (png_ptr->zowner == png_IDAT) + { + /* Always do this; the pointers otherwise point into the read buffer. */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + + /* Now we no longer own the zstream. */ + png_ptr->zowner = 0; + + /* The slightly weird semantics of the sequential IDAT reading is that we + * are always in or at the end of an IDAT chunk, so we always need to do a + * crc_finish here. If idat_size is non-zero we also need to read the + * spurious bytes at the end of the chunk now. + */ + (void)png_crc_finish(png_ptr, png_ptr->idat_size); + } +} + +void /* PRIVATE */ +png_read_finish_row(png_structrp 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. + */ + 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 */ + + /* Here after at the end of the last row of the last pass. */ + png_read_finish_IDAT(png_ptr); +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +void /* PRIVATE */ +png_read_start_row(png_structrp 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"); + +#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->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->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"); + + 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); + + /* The sequential reader needs a buffer for IDAT, but the progressive reader + * does not, so free the read buffer now regardless; the sequential reader + * reallocates it on demand. + */ + if (png_ptr->read_buffer) + { + png_bytep buffer = png_ptr->read_buffer; + + png_ptr->read_buffer_size = 0; + png_ptr->read_buffer = NULL; + png_free(png_ptr, buffer); + } + + /* Finally claim the zstream for the inflate of the IDAT data, use the bits + * value from the stream (note that this will result in a fatal error if the + * IDAT stream has a bogus deflate header window_bits value, but this should + * not be happening any longer!) + */ + if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + png_ptr->flags |= PNG_FLAG_ROW_INIT; +} +#endif /* PNG_READ_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngset.c b/ext/native/ext/libpng17/pngset.c new file mode 100644 index 0000000000..f784fbf08b --- /dev/null +++ b/ext/native/ext/libpng17/pngset.c @@ -0,0 +1,1641 @@ + +/* pngset.c - storage of image information into info struct + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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_const_structrp png_ptr, png_inforp info_ptr, + png_const_color_16p background) +{ + png_debug1(1, "in %s storage function", "bKGD"); + + if (png_ptr == NULL || info_ptr == NULL || background == NULL) + return; + + info_ptr->background = *background; + info_ptr->valid |= PNG_INFO_bKGD; +} +#endif + +#ifdef PNG_cHRM_SUPPORTED +void PNGFAPI +png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp 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_xy xy; + + png_debug1(1, "in %s storage function", "cHRM fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + xy.redx = red_x; + xy.redy = red_y; + xy.greenx = green_x; + xy.greeny = green_y; + xy.bluex = blue_x; + xy.bluey = blue_y; + xy.whitex = white_x; + xy.whitey = white_y; + + if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, + 2/* override with app values*/)) + info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; + + png_colorspace_sync_info(png_ptr, info_ptr); +} + +void PNGFAPI +png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp 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_debug1(1, "in %s storage function", "cHRM XYZ fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + XYZ.red_X = int_red_X; + XYZ.red_Y = int_red_Y; + XYZ.red_Z = int_red_Z; + XYZ.green_X = int_green_X; + XYZ.green_Y = int_green_Y; + XYZ.green_Z = int_green_Z; + XYZ.blue_X = int_blue_X; + XYZ.blue_Y = int_blue_Y; + XYZ.blue_Z = int_blue_Z; + + if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, &XYZ, 2)) + info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; + + png_colorspace_sync_info(png_ptr, info_ptr); +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_cHRM(png_const_structrp png_ptr, png_inforp 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_const_structrp png_ptr, png_inforp 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_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point file_gamma) +{ + png_debug1(1, "in %s storage function", "gAMA"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); + png_colorspace_sync_info(png_ptr, info_ptr); +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gAMA(png_const_structrp png_ptr, png_inforp 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_const_structrp png_ptr, png_inforp 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 + */ + info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); + + if (info_ptr->hist == NULL) + { + png_warning(png_ptr, "Insufficient memory for hIST chunk data"); + return; + } + + info_ptr->free_me |= PNG_FREE_HIST; + + for (i = 0; i < info_ptr->num_palette; i++) + info_ptr->hist[i] = hist[i]; + + info_ptr->valid |= PNG_INFO_hIST; +} +#endif + +void PNGAPI +png_set_IHDR(png_const_structrp png_ptr, png_inforp 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); + + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); +} + +#ifdef PNG_oFFs_SUPPORTED +void PNGAPI +png_set_oFFs(png_const_structrp png_ptr, png_inforp 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_const_structrp png_ptr, png_inforp 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 || purpose == NULL || units == NULL + || (nparams > 0 && params == NULL)) + return; + + length = 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"); + + if (nparams < 0 || nparams > 255) + png_error(png_ptr, "Invalid pCAL parameter count"); + + /* Validate params[nparams] */ + for (i=0; ipcal_purpose = png_voidcast(png_charp, + png_malloc_warn(png_ptr, length)); + + if (info_ptr->pcal_purpose == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL purpose"); + return; + } + + 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 = strlen(units) + 1; + png_debug1(3, "allocating units for info (%lu bytes)", + (unsigned long)length); + + info_ptr->pcal_units = png_voidcast(png_charp, + png_malloc_warn(png_ptr, length)); + + if (info_ptr->pcal_units == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL units"); + return; + } + + memcpy(info_ptr->pcal_units, units, length); + + info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, + (png_size_t)((nparams + 1) * (sizeof (png_charp))))); + + if (info_ptr->pcal_params == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL params"); + return; + } + + memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp))); + + for (i = 0; i < nparams; i++) + { + length = 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; + } + + 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_const_structrp png_ptr, png_inforp 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 = strlen(swidth)) == 0 || + swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) + png_error(png_ptr, "Invalid sCAL width"); + + if (sheight == NULL || (lengthh = 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_voidcast(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; + } + + 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_voidcast(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; + } + + memcpy(info_ptr->scal_s_height, sheight, lengthh); + + info_ptr->valid |= PNG_INFO_sCAL; + info_ptr->free_me |= PNG_FREE_SCAL; +} + +# if defined(PNG_FLOATING_POINT_SUPPORTED) &&\ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) +void PNGAPI +png_set_sCAL(png_const_structrp png_ptr, png_inforp 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_const_structrp png_ptr, png_inforp 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_const_structrp png_ptr, png_inforp 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_structrp png_ptr, png_inforp 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; + } + } + + if ((num_palette > 0 && palette == NULL) || + (num_palette == 0 +# ifdef PNG_MNG_FEATURES_SUPPORTED + && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 +# endif + )) + { + png_error(png_ptr, "Invalid palette"); + 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. + * + * 1.6.0: the above statement appears to be incorrect; something has to set + * the palette inside png_struct on read. + */ + 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_voidcast(png_colorp, png_calloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); + + if (num_palette > 0) + memcpy(png_ptr->palette, palette, num_palette * (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_const_structrp png_ptr, png_inforp info_ptr, + png_const_color_8p sig_bit) +{ + png_debug1(1, "in %s storage function", "sBIT"); + + if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) + return; + + info_ptr->sig_bit = *sig_bit; + info_ptr->valid |= PNG_INFO_sBIT; +} +#endif + +#ifdef PNG_sRGB_SUPPORTED +void PNGAPI +png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) +{ + png_debug1(1, "in %s storage function", "sRGB"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); + png_colorspace_sync_info(png_ptr, info_ptr); +} + +void PNGAPI +png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, + int srgb_intent) +{ + png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent)) + { + /* This causes the gAMA and cHRM to be written too */ + info_ptr->colorspace.flags |= + PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; + } + + png_colorspace_sync_info(png_ptr, info_ptr); +} +#endif /* sRGB */ + + +#ifdef PNG_iCCP_SUPPORTED +void PNGAPI +png_set_iCCP(png_const_structrp png_ptr, png_inforp 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; + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + png_app_error(png_ptr, "Invalid iCCP compression method"); + + /* Set the colorspace first because this validates the profile; do not + * override previously set app cHRM or gAMA here (because likely as not the + * application knows better than libpng what the correct values are.) Pass + * the info_ptr color_type field to png_colorspace_set_ICC because in the + * write case it has not yet been stored in png_ptr. + */ + { + int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, + proflen, profile, info_ptr->color_type); + + png_colorspace_sync_info(png_ptr, info_ptr); + + /* Don't do any of the copying if the profile was bad, or inconsistent. */ + if (result == 0) + return; + + /* But do write the gAMA and cHRM chunks from the profile. */ + info_ptr->colorspace.flags |= + PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; + } + + length = strlen(name)+1; + new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); + + if (new_iccp_name == NULL) + { + png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); + return; + } + + memcpy(new_iccp_name, name, length); + new_iccp_profile = png_voidcast(png_bytep, + png_malloc_warn(png_ptr, proflen)); + + if (new_iccp_profile == NULL) + { + png_free(png_ptr, new_iccp_name); + png_benign_error(png_ptr, + "Insufficient memory to process iCCP profile"); + return; + } + + memcpy(new_iccp_profile, profile, 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; + info_ptr->free_me |= PNG_FREE_ICCP; + info_ptr->valid |= PNG_INFO_iCCP; +} +#endif + +#ifdef PNG_TEXT_SUPPORTED +void PNGAPI +png_set_text(png_structrp png_ptr, png_inforp 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 != 0) + png_error(png_ptr, "Insufficient memory to store text"); +} + +int /* PRIVATE */ +png_set_text_2(png_structrp png_ptr, png_inforp 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 || text_ptr == NULL) + return(0); + + /* Make sure we have enough space in the "text" array in info_struct + * to hold all of the incoming text_ptr objects. This compare can't overflow + * because max_text >= num_text (anyway, subtract of two positive integers + * can't overflow in any case.) + */ + if (num_text > info_ptr->max_text - info_ptr->num_text) + { + int old_num_text = info_ptr->num_text; + int max_text; + png_textp new_text = NULL; + + /* Calculate an appropriate max_text, checking for overflow. */ + max_text = old_num_text; + if (num_text <= INT_MAX - max_text) + { + max_text += num_text; + + /* Round up to a multiple of 8 */ + if (max_text < INT_MAX-8) + max_text = (max_text + 8) & ~0x7; + + else + max_text = INT_MAX; + + /* Now allocate a new array and copy the old members in, this does all + * the overflow checks. + */ + new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, + info_ptr->text, old_num_text, max_text-old_num_text, + sizeof *new_text)); + } + + if (new_text == NULL) + { + png_chunk_report(png_ptr, "too many text chunks", + PNG_CHUNK_WRITE_ERROR); + + return 1; + } + + png_free(png_ptr, info_ptr->text); + + info_ptr->text = new_text; + info_ptr->free_me |= PNG_FREE_TEXT; + info_ptr->max_text = max_text; + /* num_text is adjusted below as the entries are copied in */ + + png_debug1(3, "allocated %d entries for info_ptr->text", max_text); + } + + for (i = 0; i < num_text; i++) + { + size_t text_length, key_len; + 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_chunk_report(png_ptr, "text compression mode is out of range", + PNG_CHUNK_WRITE_ERROR); + continue; + } + + key_len = 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 = strlen(text_ptr[i].lang); + + else + lang_len = 0; + + if (text_ptr[i].lang_key != NULL) + lang_key_len = strlen(text_ptr[i].lang_key); + + else + lang_key_len = 0; + } +# else /* PNG_iTXt_SUPPORTED */ + { + png_chunk_report(png_ptr, "iTXt chunk not supported", + PNG_CHUNK_WRITE_ERROR); + 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 = strlen(text_ptr[i].text); + textp->compression = text_ptr[i].compression; + } + + textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, + key_len + text_length + lang_len + lang_key_len + 4)); + + if (textp->key == NULL) + { + png_chunk_report(png_ptr, "text chunk: out of memory", + PNG_CHUNK_WRITE_ERROR); + 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); + + memcpy(textp->key, text_ptr[i].key, key_len); + *(textp->key + key_len) = '\0'; + + if (text_ptr[i].compression > 0) + { + textp->lang = textp->key + key_len + 1; + memcpy(textp->lang, text_ptr[i].lang, lang_len); + *(textp->lang + lang_len) = '\0'; + textp->lang_key = textp->lang + lang_len + 1; + 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 != 0) + memcpy(textp->text, text_ptr[i].text, 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_const_structrp png_ptr, png_inforp info_ptr, + png_const_timep mod_time) +{ + png_debug1(1, "in %s storage function", "tIME"); + + if (png_ptr == NULL || info_ptr == NULL || mod_time == 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; + } + + info_ptr->mod_time = *mod_time; + info_ptr->valid |= PNG_INFO_tIME; +} +#endif + +#ifdef PNG_tRNS_SUPPORTED +void PNGAPI +png_set_tRNS(png_structrp png_ptr, png_inforp 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 (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + png_chunk_report(png_ptr, + "png_set_tRNS: invalid on PNG with alpha channel", PNG_CHUNK_ERROR); + + else if (info_ptr->color_type & PNG_COLOR_MASK_PALETTE) + { + int max_num; + + /* Free the old data; num_trans 0 can be used to kill the tRNS */ + png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); + + /* Do this just in case the old data was not owned by libpng: */ + info_ptr->valid &= ~PNG_INFO_tRNS; + info_ptr->trans_alpha = NULL; + info_ptr->num_trans = 0; + + /* Expect png_set_PLTE to happen before png_set_tRNS, so num_palette will + * be set, but this is not a requirement of the API. + */ + if (png_ptr->num_palette) + max_num = png_ptr->num_palette; + + else + max_num = 1 << png_ptr->bit_depth; + + if (num_trans > max_num) + { + png_chunk_report(png_ptr, "png_set_tRNS: num_trans too large", + PNG_CHUNK_ERROR); + /* If control returns simply limit it; the behavior prior to 1.7 was to + * issue a warning and skip the palette in png_write_tRNS. + */ + num_trans = max_num; + } + + /* But only attempt a malloc if there is something to do; so the app can + * set a tRNS array then later delete it. + */ + if (num_trans > 0 && trans_alpha != NULL) + { + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1, + * this avoids issues where a palette image contains out of range + * indices. + */ + info_ptr->trans_alpha = png_voidcast(png_bytep, png_malloc(png_ptr, + PNG_MAX_PALETTE_LENGTH)); + info_ptr->free_me |= PNG_FREE_TRNS; + + memcpy(info_ptr->trans_alpha, trans_alpha, + (unsigned)/*SAFE*/num_trans); + info_ptr->valid |= PNG_INFO_tRNS; + info_ptr->num_trans = (png_uint_16)num_trans; /* SAFE */ + } + } + + else /* not a PALETTE image */ + { + /* Invalidate any prior transparent color, set num_trans too, it is not + * used internally in this case but png_get_tRNS still returns it. + */ + info_ptr->valid &= ~PNG_INFO_tRNS; + info_ptr->num_trans = 0; /* for png_get_tRNS */ + + if (trans_color != NULL) + { + int sample_max = (1 << info_ptr->bit_depth); + + if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && + trans_color->gray <= sample_max) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB && + trans_color->red <= sample_max && + trans_color->green <= sample_max && + trans_color->blue <= sample_max)) + { + info_ptr->trans_color = *trans_color; + info_ptr->valid |= PNG_INFO_tRNS; + info_ptr->num_trans = 1; /* for png_get_tRNS */ + } + + else + png_chunk_report(png_ptr, + "tRNS chunk has out-of-range samples for bit_depth", + PNG_CHUNK_ERROR); + } + } +} +#endif + +#ifdef PNG_sPLT_SUPPORTED +void PNGAPI +png_set_sPLT(png_structrp png_ptr, + png_inforp 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; + + if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) + return; + + /* Use the internal realloc function, which checks for all the possible + * overflows. Notice that the parameters are (int) and (size_t) + */ + np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, + info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, + sizeof *np)); + + if (np == NULL) + { + /* Out of memory or too many chunks */ + png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); + + return; + } + + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes = np; + info_ptr->free_me |= PNG_FREE_SPLT; + + np += info_ptr->splt_palettes_num; + + do + { + png_size_t length; + + /* Skip invalid input entries */ + if (entries->name == NULL || entries->entries == NULL) + { + /* png_handle_sPLT doesn't do this, so this is an app error */ + png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); + /* Just skip the invalid entry */ + continue; + } + + np->depth = entries->depth; + + /* In the even of out-of-memory just return - there's no point keeping on + * trying to add sPLT chunks. + */ + length = strlen(entries->name) + 1; + np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); + + if (np->name == NULL) + break; + + memcpy(np->name, entries->name, length); + + /* IMPORTANT: we have memory now that won't get freed if something else + * goes wrong, this code must free it. png_malloc_array produces no + * warnings, use a png_chunk_report (below) if there is an error. + */ + np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, + entries->nentries, sizeof (png_sPLT_entry))); + + if (np->entries == NULL) + { + png_free(png_ptr, np->name); + break; + } + + np->nentries = entries->nentries; + /* This multiply can't overflow because png_malloc_array has already + * checked it when doing the allocation. + */ + memcpy(np->entries, entries->entries, + entries->nentries * sizeof (png_sPLT_entry)); + + /* Note that 'continue' skips the advance of the out pointer and out + * count, so an invalid entry is not added. + */ + info_ptr->valid |= PNG_INFO_sPLT; + ++(info_ptr->splt_palettes_num); + ++np; + } + while (++entries, --nentries); + + if (nentries > 0) + png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); +} +#endif /* PNG_sPLT_SUPPORTED */ + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +static png_byte +check_location(png_const_structrp png_ptr, int location) +{ + location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); + + /* New in 1.6.0; copy the location and check it. This is an API + * change, previously the app had to use the + * png_set_unknown_chunk_location API below for each chunk. + */ + if (location == 0 && !(png_ptr->mode & PNG_IS_READ_STRUCT)) + { + /* Write struct, so unknown chunks come from the app */ + png_app_warning(png_ptr, + "png_set_unknown_chunks now expects a valid location"); + /* Use the old behavior */ + location = (png_byte)(png_ptr->mode & + (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); + } + + /* This need not be an internal error - if the app calls + * png_set_unknown_chunks on a read pointer it must get the location right. + */ + if (location == 0) + png_error(png_ptr, "invalid location in png_set_unknown_chunks"); + + /* Now reduce the location to the top-most set bit by removing each least + * significant bit in turn. + */ + while (location != (location & -location)) + location &= ~(location & -location); + + /* The cast is safe because 'location' is a bit mask and only the low four + * bits are significant. + */ + return (png_byte)location; +} + +void PNGAPI +png_set_unknown_chunks(png_structrp png_ptr, + png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) +{ + png_unknown_chunkp np; + + if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || + unknowns == NULL) + return; + + /* Check for the failure cases where support has been disabled at compile + * time. This code is hardly ever compiled - it's here because + * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this + * code) but may be meaningless if the read or write handling of unknown + * chunks is not compiled in. + */ +# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ + defined(PNG_READ_SUPPORTED) + if (png_ptr->mode & PNG_IS_READ_STRUCT) + { + png_app_error(png_ptr, "no unknown chunk support on read"); + return; + } +# endif +# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ + defined(PNG_WRITE_SUPPORTED) + if (!(png_ptr->mode & PNG_IS_READ_STRUCT)) + { + png_app_error(png_ptr, "no unknown chunk support on write"); + return; + } +# endif + + /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that + * unknown critical chunks could be lost with just a warning resulting in + * undefined behavior. Now png_chunk_report is used to provide behavior + * appropriate to read or write. + */ + np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, + info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, + sizeof *np)); + + if (np == NULL) + { + png_chunk_report(png_ptr, "too many unknown chunks", + PNG_CHUNK_WRITE_ERROR); + + return; + } + + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks = np; /* safe because it is initialized */ + info_ptr->free_me |= PNG_FREE_UNKN; + + np += info_ptr->unknown_chunks_num; + + /* Increment unknown_chunks_num each time round the loop to protect the + * just-allocated chunk data. + */ + for (; num_unknowns > 0; --num_unknowns, ++unknowns) + { + memcpy(np->name, unknowns->name, (sizeof np->name)); + np->name[(sizeof np->name)-1] = '\0'; + np->location = check_location(png_ptr, unknowns->location); + + if (unknowns->size == 0) + { + np->data = NULL; + np->size = 0; + } + + else + { + np->data = png_voidcast(png_bytep, + png_malloc_base(png_ptr, unknowns->size)); + + if (np->data == NULL) + { + png_chunk_report(png_ptr, "unknown chunk: out of memory", + PNG_CHUNK_WRITE_ERROR); + /* But just skip storing the unknown chunk */ + continue; + } + + memcpy(np->data, unknowns->data, unknowns->size); + np->size = unknowns->size; + } + + /* These increments are skipped on out-of-memory for the data - the + * unknown chunk entry gets overwritten if the png_chunk_report returns. + * This is correct in the read case (the chunk is just dropped.) + */ + ++np; + ++(info_ptr->unknown_chunks_num); + } +} + +void PNGAPI +png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, + int chunk, int location) +{ + /* This API is pretty pointless in 1.6.0 because the location can be set + * before the call to png_set_unknown_chunks. + */ + if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && + chunk < info_ptr->unknown_chunks_num) + { + if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) + { + png_app_error(png_ptr, "invalid unknown chunk location"); + /* Fake out the pre 1.6.0 behavior: */ + if ((location & PNG_HAVE_IDAT)) /* undocumented! */ + location = PNG_AFTER_IDAT; + + else + location = PNG_HAVE_IHDR; /* also undocumented */ + } + + info_ptr->unknown_chunks[chunk].location = + check_location(png_ptr, location); + } + + /* TODO: make this an error in 1.8 (or maybe it will become one in 1.7!) */ + else if (png_ptr != NULL) + png_app_warning(png_ptr, "unknown chunk index out of range"); +} +#endif + + +#ifdef PNG_MNG_FEATURES_SUPPORTED +png_uint_32 PNGAPI +png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features) +{ + png_debug(1, "in png_permit_mng_features"); + + if (png_ptr == NULL) + return 0; + + png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES; + + return png_ptr->mng_features_permitted; +} +#endif + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +static unsigned int +add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep) +{ + unsigned int i; + + /* Utility function: update the 'keep' state of a chunk if it is already in + * the list, otherwise add it to the list. + */ + for (i=0; i= PNG_HANDLE_CHUNK_LAST) + { + png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); + return; + } + + if (num_chunks_in <= 0) + { + png_ptr->unknown_default = keep; + + /* '0' means just set the flags, so stop here */ + if (num_chunks_in == 0) + return; + } + + if (num_chunks_in < 0) + { + /* Ignore all unknown chunks and all chunks recognized by + * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND + */ + static PNG_CONST png_byte chunks_to_ignore[] = { + 98, 75, 71, 68, '\0', /* bKGD */ + 99, 72, 82, 77, '\0', /* cHRM */ + 103, 65, 77, 65, '\0', /* gAMA */ + 104, 73, 83, 84, '\0', /* hIST */ + 105, 67, 67, 80, '\0', /* iCCP */ + 105, 84, 88, 116, '\0', /* iTXt */ + 111, 70, 70, 115, '\0', /* oFFs */ + 112, 67, 65, 76, '\0', /* pCAL */ + 112, 72, 89, 115, '\0', /* pHYs */ + 115, 66, 73, 84, '\0', /* sBIT */ + 115, 67, 65, 76, '\0', /* sCAL */ + 115, 80, 76, 84, '\0', /* sPLT */ + 115, 84, 69, 82, '\0', /* sTER */ + 115, 82, 71, 66, '\0', /* sRGB */ + 116, 69, 88, 116, '\0', /* tEXt */ + 116, 73, 77, 69, '\0', /* tIME */ + 122, 84, 88, 116, '\0' /* zTXt */ + }; + + chunk_list = chunks_to_ignore; + num_chunks = (sizeof chunks_to_ignore)/5; + } + + else /* num_chunks_in > 0 */ + { + if (chunk_list == NULL) + { + /* Prior to 1.6.0 this was silently ignored, now it is an app_error + * which can be switched off. + */ + png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); + return; + } + + num_chunks = num_chunks_in; + } + + old_num_chunks = png_ptr->num_chunk_list; + if (png_ptr->chunk_list == NULL) + old_num_chunks = 0; + + /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. + */ + if (num_chunks + old_num_chunks > UINT_MAX/5) + { + png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); + return; + } + + /* If these chunks are being reset to the default then no more memory is + * required because add_one_chunk above doesn't extend the list if the 'keep' + * parameter is the default. + */ + if (keep != 0) + { + new_list = png_voidcast(png_bytep, png_malloc(png_ptr, + 5 * (num_chunks + old_num_chunks))); + + if (old_num_chunks > 0) + memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); + } + + else if (old_num_chunks > 0) + new_list = png_ptr->chunk_list; + + else + new_list = NULL; + + /* Add the new chunks together with each one's handling code. If the chunk + * already exists the code is updated, otherwise the chunk is added to the + * end. (In libpng 1.6.0 order no longer matters because this code enforces + * the earlier convention that the last setting is the one that is used.) + */ + if (new_list != NULL) + { + png_const_bytep inlist; + png_bytep outlist; + unsigned int i; + + for (i=0; ichunk_list != new_list) + png_free(png_ptr, new_list); + + new_list = NULL; + } + } + + else + num_chunks = 0; + + png_ptr->num_chunk_list = num_chunks; + + if (png_ptr->chunk_list != new_list) + { + if (png_ptr->chunk_list != NULL) + png_free(png_ptr, png_ptr->chunk_list); + + png_ptr->chunk_list = new_list; + } +} +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +void PNGAPI +png_set_read_user_chunk_fn(png_structrp 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_const_structrp png_ptr, png_inforp 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 != NULL) + info_ptr->valid |= PNG_INFO_IDAT; +} +#endif + +void PNGAPI +png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size) +{ + if (png_ptr == NULL) + return; + + if (size == 0 || size > PNG_UINT_31_MAX) + png_error(png_ptr, "invalid compression buffer size"); + +# ifdef PNG_SEQUENTIAL_READ_SUPPORTED + if (png_ptr->mode & PNG_IS_READ_STRUCT) + { + png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ + return; + } +# endif + +# ifdef PNG_WRITE_SUPPORTED + if (!(png_ptr->mode & PNG_IS_READ_STRUCT)) + { + if (png_ptr->zowner != 0) + { + png_warning(png_ptr, + "Compression buffer size cannot be changed because it is in use"); + return; + } + + if (size > ZLIB_IO_MAX) + { + png_warning(png_ptr, + "Compression buffer size limited to system maximum"); + size = ZLIB_IO_MAX; /* must fit */ + } + + else if (size < 6) + { + /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH + * if this is permitted. + */ + png_warning(png_ptr, + "Compression buffer size cannot be reduced below 6"); + return; + } + + if (png_ptr->zbuffer_size != size) + { + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); + png_ptr->zbuffer_size = (uInt)size; + } + } +# endif +} + +void PNGAPI +png_set_invalid(png_const_structrp png_ptr, png_inforp 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_structrp 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) + { + 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_structrp png_ptr, png_uint_32 user_chunk_cache_max) +{ + if (png_ptr != NULL) + 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_structrp png_ptr, + png_alloc_size_t user_chunk_malloc_max) +{ + if (png_ptr != NULL) + 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_structrp png_ptr, int allowed) +{ + png_debug(1, "in png_set_benign_errors"); + + /* If allowed is 1, png_benign_error() is treated as a warning. + * + * If allowed is 0, png_benign_error() is treated as an error (which + * is the default behavior if png_set_benign_errors() is not called). + */ + + if (allowed != 0) + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN | + PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN; + + else + png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN | + PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN); +} +#endif /* PNG_BENIGN_ERRORS_SUPPORTED */ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Whether to report invalid palette index; added at libng-1.5.10. + * It is possible for an indexed (color-type==3) PNG file to contain + * pixels with invalid (out-of-range) indexes if the PLTE chunk has + * fewer entries than the image's bit-depth would allow. We recover + * from this gracefully by filling any incomplete palette with zeroes + * (opaque black). By default, when this occurs libpng will issue + * a benign error. This API can be used to override that behavior. + */ +void PNGAPI +png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) +{ + png_debug(1, "in png_set_check_for_invalid_index"); + + if (allowed > 0) + png_ptr->num_palette_max = 0; + + else + png_ptr->num_palette_max = -1; +} +#endif +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngstruct.h b/ext/native/ext/libpng17/pngstruct.h new file mode 100644 index 0000000000..e4341eede6 --- /dev/null +++ b/ext/native/ext/libpng17/pngstruct.h @@ -0,0 +1,560 @@ + +/* pngstruct.h - header file for PNG reference library + * + * Copyright (c) 1998-2014 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.7.0 [(PENDING RELEASE)] + * + * 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. + */ +#ifndef ZLIB_CONST + /* We must ensure that zlib uses 'const' in declarations. */ +# define ZLIB_CONST +#endif + +#include PNG_ZLIB_HEADER + +#ifdef const + /* zlib.h sometimes #defines const to nothing, undo this. */ +# undef const +#endif + +/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility + * with older builds. + */ +#if ZLIB_VERNUM < 0x1260 +# define PNGZ_MSG_CAST(s) png_constcast(char*,s) +# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) +#else +# define PNGZ_MSG_CAST(s) (s) +# define PNGZ_INPUT_CAST(b) (b) +#endif + +/* 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 + * maximum for size_t. The value can be overridden 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 + +#ifdef PNG_WRITE_SUPPORTED +/* The type of a compression buffer list used by the write code. */ +typedef struct png_compression_buffer +{ + struct png_compression_buffer *next; + png_byte output[1]; /* actually zbuf_size */ +} png_compression_buffer, *png_compression_bufferp; + +#define PNG_COMPRESSION_BUFFER_SIZE(pp)\ + (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size) +#endif + +/* Colorspace support; structures used in png_struct, png_info and in internal + * functions to hold and communicate information about the color space. + * + * PNG_COLORSPACE_SUPPORTED is only required if the application will perform + * colorspace corrections, otherwise all the colorspace information can be + * skipped and the size of libpng can be reduced (significantly) by compiling + * out the colorspace support. + */ +#ifdef PNG_COLORSPACE_SUPPORTED +/* The chromaticities of the red, green and blue colorants and the chromaticity + * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). + */ +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; + +/* The same data as above but encoded as CIE XYZ values. When this data comes + * from chromaticities the sum of the Y values is assumed to be 1.0 + */ +typedef struct png_XYZ +{ + png_fixed_point red_X, red_Y, red_Z; + png_fixed_point green_X, green_Y, green_Z; + png_fixed_point blue_X, blue_Y, blue_Z; +} png_XYZ; +#endif /* COLORSPACE */ + +#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) +/* A colorspace is all the above plus, potentially, profile information, + * however at present libpng does not use the profile internally so it is only + * stored in the png_info struct (if iCCP is supported.) The rendering intent + * is retained here and is checked. + * + * The file gamma encoding information is also stored here and gamma correction + * is done by libpng, whereas color correction must currently be done by the + * application. + */ +typedef struct png_colorspace +{ +#ifdef PNG_GAMMA_SUPPORTED + png_fixed_point gamma; /* File gamma */ +#endif + +#ifdef PNG_COLORSPACE_SUPPORTED + png_xy end_points_xy; /* End points as chromaticities */ + png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */ + png_uint_16 rendering_intent; /* Rendering intent of a profile */ +#endif + + /* Flags are always defined to simplify the code. */ + png_uint_16 flags; /* As defined below */ +} png_colorspace, * PNG_RESTRICT png_colorspacerp; + +typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp; + +/* General flags for the 'flags' field */ +#define PNG_COLORSPACE_HAVE_GAMMA 0x0001 +#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002 +#define PNG_COLORSPACE_HAVE_INTENT 0x0004 +#define PNG_COLORSPACE_FROM_gAMA 0x0008 +#define PNG_COLORSPACE_FROM_cHRM 0x0010 +#define PNG_COLORSPACE_FROM_sRGB 0x0020 +#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040 +#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */ +#define PNG_COLORSPACE_RGB_TO_GRAY_SET 0x0100 /* user specified coeffs */ +#define PNG_COLORSPACE_INVALID 0x8000 +#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags)) +#endif /* COLORSPACE || GAMMA */ + +struct png_struct_def +{ + /* Rearranged in libpng 1.7 to attempt to lessen padding; in general + * (char), (short), (int) and pointer types are kept separate, however + * associated members under the control of the same #define are still + * together. + */ +#ifdef PNG_SETJMP_SUPPORTED + /* jmp_buf can have very high alignment requirements on some systems, so put + * it first (the other setjmp members are later as they are infrequently + * accesed.) + */ + jmp_buf jmp_buf_local; +#endif + + /* Next the frequently accessed fields. Many processors perform arithmetic + * in the address pipeline, but frequently the amount of addition or + * subtraction is limited. By putting these fields at the head of png_struct + * the hope is that such processors will generate code that is both smaller + * and faster. + */ + png_colorp palette; /* palette from the input file */ + size_t rowbytes; /* size of row in bytes */ + size_t info_rowbytes; /* cache of updated row bytes */ + 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_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_uint_32 crc; /* current chunk CRC value */ + 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 */ + png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ + png_uint_32 free_me; /* items libpng is responsible for freeing */ + + int maximum_pixel_depth; /* pixel depth used for the row buffers */ +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + int num_palette_max; /* maximum palette index found in IDAT */ +#endif + + png_uint_16 num_palette; /* number of color entries in palette */ + png_uint_16 num_trans; /* number of transparency values */ + + /* Single byte values, typically used either to save space or to hold 1-byte + * values from the PNG chunk specifications. + */ + png_byte compression_type; /* 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 pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ + png_byte sig_bytes; /* magic bytes read/written from start of file */ + png_byte transformed_pixel_depth; + /* pixel depth after read/write transforms */ + + /* ERROR HANDLING */ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ + png_longjmp_ptr longjmp_fn; /* setjmp non-local goto function. */ + size_t jmp_buf_size; /* size of *jmp_buf_ptr, if allocated */ +#endif + + /* Error/warning callbacks */ + png_error_ptr error_fn; /* print an error message and abort */ +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; /* print a warning and continue */ +#endif + png_voidp error_ptr; /* user supplied data for the above */ + + /* MEMORY ALLOCATION */ +#ifdef PNG_USER_MEM_SUPPORTED + png_malloc_ptr malloc_fn; /* allocate memory */ + png_free_ptr free_fn; /* free memory */ + png_voidp mem_ptr; /* user supplied data for the above */ +#endif + + /* IO and BASIC READ/WRITE SUPPORT */ + png_voidp io_ptr; /* user supplied data for IO callbacks */ + +#ifdef PNG_READ_SUPPORTED + png_rw_ptr read_data_fn; /* read some bytes (must succeed) */ + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_bytep read_buffer; /* buffer for reading chunk data */ + + /* During read the following array is set up to point to the appropriate + * un-filter function, this allows per-image and per-processor optimization. + */ + void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row); + +#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) + /* The png_struct colorspace structure is only required on read - on write it + * is in (just) the info_struct. + */ + png_colorspace colorspace; +#endif +#endif /* PNG_READ_SUPPORTED */ + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; /* Maximum width on read */ + png_uint_32 user_height_max; /* Maximum height on read */ + /* Total memory that a single zTXt, sPLT, iTXt, iCCP, or unknown chunk + * can occupy when decompressed. 0 means unlimited. This field is a counter + * - it is decremented as memory is allocated. + */ + png_alloc_size_t user_chunk_malloc_max; +#endif +#ifdef PNG_USER_LIMITS_SUPPORTED + /* limit on total *number* of sPLT, text and unknown chunks that can be + * stored. 0 means unlimited. This field is a counter - it is decremented + * as chunks are encountered. + */ + png_uint_32 user_chunk_cache_max; +#endif + + /* The progressive reader gets passed data and calls application handling + * functions when appropriate. + */ +#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 row is decoded */ + png_progressive_end_ptr end_fn; /* called after image is complete */ + + /* Progressive read control data */ + 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 */ + + size_t save_buffer_size; /* amount of data now in save_buffer */ + size_t save_buffer_max; /* total size of save_buffer */ + size_t buffer_size; /* total amount of available input data */ + size_t current_buffer_size; /* amount of data now in current_buffer */ + + png_uint_32 push_length; /* size of current input chunk */ + png_uint_32 skip_length; /* bytes to skip in input data */ + + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ +#endif + +#ifdef PNG_WRITE_SUPPORTED + png_rw_ptr write_data_fn;/* write some bytes (must succeed) */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ +#endif + +#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_WRITE_WEIGHTED_FILTER_SUPPORTED + 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 */ + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ +#endif + +#ifdef PNG_WRITE_SUPPORTED + png_byte usr_bit_depth; /* bit depth of users row */ + png_byte usr_channels; /* channels at start of write */ +#endif + +#ifdef PNG_IO_STATE_SUPPORTED + png_uint_32 io_state; /* tells the app read/write progress */ +#endif + + /* ROW BUFFERS + * + * Members that hold pointers to the decompressed image rows. + */ + png_bytep row_buf; /* buffer for the current (unfiltered) row */ +#if defined(PNG_WRITE_FILTER_SUPPORTED) || defined(PNG_READ_SUPPORTED) + png_bytep prev_row; /* buffer to save the previous (unfiltered) row */ +#endif + +#ifdef PNG_READ_SUPPORTED + /* The row_buf and prev_row pointers are misaligned so that the start of the + * row - after the filter byte - is aligned, the 'big_' pointers record the + * original allocated pointer. + */ + png_bytep big_row_buf; + png_bytep big_prev_row; + size_t big_row_buf_size; /* Actual size of both */ +#endif + +#ifdef PNG_WRITE_SUPPORTED + /* This is somewhat excessive, there is no obvious reason on write to + * allocate a buffer for each possible filtered row, only for the one being + * tested and the current best. + * + * TODO: fix this + */ + 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 */ +#endif + + /* UNKNOWN CHUNK HANDLING */ + /* TODO: this is excessively complicated, there are multiple ways of doing + * the same thing. It should be cleaned up, possibly by finding out which + * APIs applications really use. + */ +#ifdef PNG_USER_CHUNKS_SUPPORTED + /* General purpose pointer for all user/unknown chunk handling; points to + * application supplied data for use in the read_user_chunk_fn callback + * (currently there is no write side support - the write side must use the + * set_unknown_chunks interface.) + */ + png_voidp user_chunk_ptr; +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + /* This is called back from the unknown chunk handling */ + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* Temporary storage for unknown chunk that the library doesn't recognize, + * used while reading the chunk. + */ + png_unknown_chunk unknown_chunk; +#endif + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name + * followed by a PNG_HANDLE_* byte */ + int unknown_default; /* As PNG_HANDLE_* */ + unsigned int num_chunk_list; /* Number of entries in the list */ +#endif + + /* USER TRANSFORM SUPPORT */ +#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 +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + png_voidp user_transform_ptr; /* user supplied data for the above */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ +#endif + + /* READ TRANSFORM SUPPORT + * + * Quite a lot of things can be done to the original image data on read, and + * most of these are configurable. The data required by the configurable + * read transforms should be stored here. The png_color_16 and png_color_8 + * structures have low alignment requirements and odd sizes, so may cause + * misalignment when present. Member alignment is as follows: + * + * png_color_16 png_uint_16 + * png_color_8 png_byte + */ + /* GAMMA/BACKGROUND/ALPHA-MODE/RGB-TO-GRAY/tRNS/sBIT + * + * These things are all interrelated because they need some or all of the + * gamma tables. Some attempt has been made below to order these members by + * size, so that as little padding as possible is required. + */ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_uint_16p 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_uint_16p gamma_to_1; /* converts from file to 1.0 */ + png_uint_16p gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16p gamma_16_to_1; /* converts from file to 1.0 */ +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +#endif /* PNG_READ_GAMMA_SUPPORTED */ + +#if defined(PNG_READ_tRNS_SUPPORTED) || \ + defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_EXPAND_SUPPORTED) + png_bytep trans_alpha; /* alpha values for paletted files */ +#endif + + /* Integer values */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + png_fixed_point background_gamma; +#endif +#ifdef PNG_READ_GAMMA_SUPPORTED + png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ + int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ +#endif + + /* png_color_16 */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + png_color_16 background; /* background color in screen gamma space */ + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) || \ + defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_EXPAND_SUPPORTED) + png_color_16 trans_color; /* transparent color for non-paletted files */ +#endif + + /* png_uint_16 */ +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + /* The blue coefficient is calculated from the above */ +#endif + + /* png_color_8 */ +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_sBIT_SUPPORTED) + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif + + /* png_byte */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + png_byte background_gamma_type; +#endif +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_byte rgb_to_gray_status; +#endif + + /* SHIFT - both READ_SHIFT and WRITE_SHIFT */ +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift; /* shift for significant bit tranformation */ +#endif + + /* FILLER SUPPORT (pixel expansion or read, contraction on write) */ +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif + + /* QUANTIZE (convert to color-mapped) */ +#ifdef PNG_READ_QUANTIZE_SUPPORTED + png_bytep palette_lookup; /* lookup table for quantizing */ + png_bytep quantize_index; /* index translation for palette files */ + 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 + + /* MNG SUPPORT */ +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_uint_32 mng_features_permitted; + png_byte filter_type; +#endif + + /* Options */ +#ifdef PNG_SET_OPTION_SUPPORTED + png_byte options; /* On/off state (up to 4 options) */ +#endif + + /* COMPRESSION AND DECOMPRESSION SUPPORT. + * + * zlib expects a 'zstream' as the fundamental control structure, it allows + * all the parameters to be passed as one pointer. + */ + z_stream zstream; /* decompression structure */ + +#ifdef PNG_READ_SUPPORTED + /* These, and IDAT_read_size below, control how much input and output (at + * most) is available to zlib. + */ + png_uint_32 idat_size; /* current IDAT size for read */ + png_alloc_size_t read_buffer_size; /* current size of the buffer */ +#endif + +#ifdef 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 + +#ifdef PNG_WRITE_SUPPORTED + 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 */ + + int zlib_set_level; /* Actual values set into the zstream on write */ + int zlib_set_method; + int zlib_set_window_bits; + int zlib_set_mem_level; + int zlib_set_strategy; + + png_compression_bufferp zbuffer_list; /* Created on demand during write */ + uInt zbuffer_size; /* size of the actual zlib buffer */ +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED + uInt IDAT_read_size; /* limit on read buffer size for IDAT */ +#endif +}; +#endif /* PNGSTRUCT_H */ diff --git a/ext/native/ext/libpng17/pngtest.c b/ext/native/ext/libpng17/pngtest.c new file mode 100644 index 0000000000..9add642142 --- /dev/null +++ b/ext/native/ext/libpng17/pngtest.c @@ -0,0 +1,1999 @@ + +/* pngtest.c - a simple test program to test libpng + * + * Last changed in libpng 1.6.11 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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 ..." + */ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#define _POSIX_SOURCE 1 + +#include +#include +#include + +/* Defined so I can write to a file on gui/windowing platforms */ +/* #define STDERR stderr */ +#define STDERR stdout /* For DOS */ + +#include "png.h" + +/* Known chunks that exist in pngtest.png must be supported or pngtest will fail + * simply as a result of re-ordering them. This may be fixed in 1.7 + * + * pngtest allocates a single row buffer for each row and overwrites it, + * therefore if the write side doesn't support the writing of interlaced images + * nothing can be done for an interlaced image (and the code below will fail + * horribly trying to write extra data after writing garbage). + */ +#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\ + defined PNG_READ_bKGD_SUPPORTED &&\ + defined PNG_READ_cHRM_SUPPORTED &&\ + defined PNG_READ_gAMA_SUPPORTED &&\ + defined PNG_READ_oFFs_SUPPORTED &&\ + defined PNG_READ_pCAL_SUPPORTED &&\ + defined PNG_READ_pHYs_SUPPORTED &&\ + defined PNG_READ_sBIT_SUPPORTED &&\ + defined PNG_READ_sCAL_SUPPORTED &&\ + defined PNG_READ_sRGB_SUPPORTED &&\ + defined PNG_READ_tEXt_SUPPORTED &&\ + defined PNG_READ_tIME_SUPPORTED &&\ + defined PNG_READ_zTXt_SUPPORTED &&\ + defined PNG_WRITE_INTERLACING_SUPPORTED + +#ifdef PNG_ZLIB_HEADER +# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ +#else +# include "zlib.h" +#endif + +/* Copied from pngpriv.h but only used in error messages below. */ +#ifndef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 8192 +#endif +#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 + +/* 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; +static int relaxed = 0; +static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ +static int error_count = 0; /* count calls to png_error */ +static int warning_count = 0; /* count calls to png_warning */ + +/* 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 + +/* Defines for unknown chunk handling if required. */ +#ifndef PNG_HANDLE_CHUNK_ALWAYS +# define PNG_HANDLE_CHUNK_ALWAYS 3 +#endif +#ifndef PNG_HANDLE_CHUNK_IF_SAFE +# define PNG_HANDLE_CHUNK_IF_SAFE 2 +#endif + +/* Utility to save typing/errors, the argument must be a name */ +#define MEMZERO(var) ((void)memset(&var, 0, sizeof var)) + +/* 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; + +static 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"); +} + +#ifdef PNG_WRITE_SUPPORTED +static 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"); +} +#endif + + +#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]; +static 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; + +static 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 */ + +#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 != 0) + png_error(png_ptr, "Bad I/O state or buffer size"); +} +#endif + +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 +} + +#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. + */ +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 +} +#endif /* !PNG_STDIO_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 to. In the default configuration, png_ptr is + * not used, but it is passed in case it may be useful. + */ +typedef struct +{ + PNG_CONST char *file_name; +} pngtest_error_parameters; + +static void PNGCBAPI +pngtest_warning(png_structp png_ptr, png_const_charp message) +{ + PNG_CONST char *name = "UNKNOWN (ERROR!)"; + pngtest_error_parameters *test = + (pngtest_error_parameters*)png_get_error_ptr(png_ptr); + + ++warning_count; + + if (test != NULL && test->file_name != NULL) + name = test->file_name; + + fprintf(STDERR, "%s: libpng warning: %s\n", name, 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) +{ + ++error_count; + + pngtest_warning(png_ptr, message); + /* We can return because png_error calls the default handler, which is + * actually OK in this case. + */ +} + +/* 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 *next; +} memory_information; +typedef memory_information *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, + (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. */ + memset(pinfo->pointer, 0xdd, pinfo->size); + + if (verbose != 0) + 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 *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. */ + memset(ptr, 0x55, pinfo->size); + if (pinfo != NULL) + free(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 != 0) + printf("Freeing %p\n", ptr); + + if (ptr != NULL) + free(ptr); + ptr = NULL; +} +#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ +/* END of code to test memory allocation/deallocation */ + + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +/* Demonstration of user chunk support of the sTER and vpAg chunks */ + +/* (sTER is a public chunk not yet known by libpng. vpAg is a private +chunk used in ImageMagick to store "virtual page" size). */ + +static struct user_chunk_data +{ + png_const_infop info_ptr; + png_uint_32 vpAg_width, vpAg_height; + png_byte vpAg_units; + png_byte sTER_mode; + int location[2]; +} +user_chunk_data; + +/* Used for location and order; zero means nothing. */ +#define have_sTER 0x01 +#define have_vpAg 0x02 +#define before_PLTE 0x10 +#define before_IDAT 0x20 +#define after_IDAT 0x40 + +static void +init_callback_info(png_const_infop info_ptr) +{ + MEMZERO(user_chunk_data); + user_chunk_data.info_ptr = info_ptr; +} + +static int +set_location(png_structp png_ptr, struct user_chunk_data *data, int what) +{ + int location; + + if ((data->location[0] & what) || (data->location[1] & what)) + return 0; /* already have one of these */ + + /* Find where we are (the code below zeros info_ptr to indicate that the + * chunks before the first IDAT have been read.) + */ + if (data->info_ptr == NULL) /* after IDAT */ + location = what | after_IDAT; + + else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE)) + location = what | before_IDAT; + + else + location = what | before_PLTE; + + if (data->location[0] == 0) + data->location[0] = location; + + else + data->location[1] = location; + + return 1; /* handled */ +} + +static int PNGCBAPI +read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) +{ + struct user_chunk_data *my_user_chunk_data = + (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr); + + if (my_user_chunk_data == NULL) + png_error(png_ptr, "lost user chunk pointer"); + + /* 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 */ + + if (set_location(png_ptr, my_user_chunk_data, have_sTER)) + { + my_user_chunk_data->sTER_mode=chunk->data[0]; + return (1); + } + + else + return (0); /* duplicate sTER - give it to libpng */ + } + + 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 */ + + if (!set_location(png_ptr, my_user_chunk_data, have_vpAg)) + return (0); /* duplicate vpAg */ + + my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); + my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4); + my_user_chunk_data->vpAg_units = chunk->data[8]; + + return (1); +} + +#ifdef PNG_WRITE_SUPPORTED +static void +write_sTER_chunk(png_structp write_ptr) +{ + png_byte sTER[5] = {115, 84, 69, 82, '\0'}; + + if (verbose != 0) + fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode); + + png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1); +} + +static void +write_vpAg_chunk(png_structp write_ptr) +{ + png_byte vpAg[5] = {118, 112, 65, 103, '\0'}; + + png_byte vpag_chunk_data[9]; + + if (verbose != 0) + fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", + (unsigned long)user_chunk_data.vpAg_width, + (unsigned long)user_chunk_data.vpAg_height, + user_chunk_data.vpAg_units); + + png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width); + png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height); + vpag_chunk_data[8] = user_chunk_data.vpAg_units; + png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9); +} + +static void +write_chunks(png_structp write_ptr, int location) +{ + int i; + + /* Notice that this preserves the original chunk order, however chunks + * intercepted by the callback will be written *after* chunks passed to + * libpng. This will actually reverse a pair of sTER chunks or a pair of + * vpAg chunks, resulting in an error later. This is not worth worrying + * about - the chunks should not be duplicated! + */ + for (i=0; i<2; ++i) + { + if (user_chunk_data.location[i] == (location | have_sTER)) + write_sTER_chunk(write_ptr); + + else if (user_chunk_data.location[i] == (location | have_vpAg)) + write_vpAg_chunk(write_ptr); + } +} +#endif /* PNG_WRITE_SUPPORTED */ +#else /* !PNG_READ_USER_CHUNKS_SUPPORTED */ +# define write_chunks(pp,loc) ((void)0) +#endif +/* END of code to demonstrate user chunk support */ + +/* START of code to check that libpng has the required text support; this only + * checks for the write support because if read support is missing the chunk + * will simply not be reported back to pngtest. + */ +#ifdef PNG_TEXT_SUPPORTED +static void +pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr, + int num_text) +{ + while (num_text > 0) + { + switch (text_ptr[--num_text].compression) + { + case PNG_TEXT_COMPRESSION_NONE: + break; + + case PNG_TEXT_COMPRESSION_zTXt: +# ifndef PNG_WRITE_zTXt_SUPPORTED + ++unsupported_chunks; +# endif + break; + + case PNG_ITXT_COMPRESSION_NONE: + case PNG_ITXT_COMPRESSION_zTXt: +# ifndef PNG_WRITE_iTXt_SUPPORTED + ++unsupported_chunks; +# endif + break; + + default: + /* This is an error */ + png_error(png_ptr, "invalid text chunk compression field"); + break; + } + } +} +#endif +/* END of code to check that libpng has the required text support */ + +/* Test one file */ +static 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 */ + pngtest_error_parameters error_parameters; + 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; + int interlace_preserved = 1; +#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 = 1, pass; + int bit_depth, color_type; + + row_buf = NULL; + error_parameters.file_name = inname; + + 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 + png_set_error_fn(read_ptr, &error_parameters, pngtest_error, + pngtest_warning); + +#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 + png_set_error_fn(write_ptr, &error_parameters, pngtest_error, + pngtest_warning); +#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_READ_USER_CHUNKS_SUPPORTED + init_callback_info(read_info_ptr); + png_set_read_user_chunk_fn(read_ptr, &user_chunk_data, + read_user_chunk_callback); +#endif + +#ifdef PNG_SETJMP_SUPPORTED + pngtest_debug("Setting jmpbuf for read struct"); + if (setjmp(png_jmpbuf(read_ptr))) + { + 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 PNG_WRITE_SUPPORTED + pngtest_debug("Setting jmpbuf for write struct"); + + if (setjmp(png_jmpbuf(write_ptr))) + { + 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); + } +#endif +#endif + + if (strict != 0) + { + /* Treat png_benign_error() as errors on read */ + png_set_benign_errors(read_ptr, 0); + +#ifdef PNG_WRITE_SUPPORTED + /* Treat them as errors on write */ + png_set_benign_errors(write_ptr, 0); +#endif + + /* if strict is not set, then app warnings and errors are treated as + * warnings in release builds, but not in unstable builds; this can be + * changed with '--relaxed'. + */ + } + + else if (relaxed != 0) + { + /* Allow application (pngtest) errors and warnings to pass */ + png_set_benign_errors(read_ptr, 1); + +#ifdef PNG_WRITE_SUPPORTED + png_set_benign_errors(write_ptr, 1); +#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 + + 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_SET_UNKNOWN_CHUNKS_SUPPORTED + /* Preserve all the unknown chunks, if possible. If this is disabled then, + * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use + * libpng to *save* the unknown chunks on read (because we can't switch the + * save option on!) + * + * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all + * unknown chunks and write will write them all. + */ +#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED + png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, + NULL, 0); +#endif +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, + NULL, 0); +#endif +#endif + + pngtest_debug("Reading info struct"); + png_read_info(read_ptr, read_info_ptr); + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + /* This is a bit of a hack; there is no obvious way in the callback function + * to determine that the chunks before the first IDAT have been read, so + * remove the info_ptr (which is only used to determine position relative to + * PLTE) here to indicate that we are after the IDAT. + */ + user_chunk_data.info_ptr = NULL; +#endif + + 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, + color_type, interlace_type, compression_type, filter_type); +#ifndef PNG_READ_INTERLACING_SUPPORTED + /* num_pass will not be set below, set it here if the image is + * interlaced: what happens is that write interlacing is *not* turned + * on an the partial interlaced rows are written directly. + */ + switch (interlace_type) + { + case PNG_INTERLACE_NONE: + num_pass = 1; + break; + + case PNG_INTERLACE_ADAM7: + num_pass = 7; + break; + + default: + png_error(read_ptr, "invalid interlace type"); + /*NOT REACHED*/ + } +#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 +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + defined(PNG_FLOATING_ARITHMETIC_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); + + pngtest_check_text_support(read_ptr, text_ptr, num_text); + + if (verbose != 0) + { + int i; + + printf("\n"); + for (i=0; igray > 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 != 0) + { + png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, + num_unknowns); +#if PNG_LIBPNG_VER < 10600 + /* Copy the locations from the read_info_ptr. The automatically + * generated locations in write_end_info_ptr are wrong prior to 1.6.0 + * because they are reset from the write pointer (removed in 1.6.0). + */ + { + int i; + for (i = 0; i < num_unknowns; i++) + png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, + unknowns[i].location); + } +#endif + } + } +#endif + +#ifdef PNG_WRITE_SUPPORTED + pngtest_debug("Writing info struct"); + + /* Write the info in two steps so that if we write the 'unknown' chunks here + * they go to the correct place. + */ + png_write_info_before_PLTE(write_ptr, write_info_ptr); + + write_chunks(write_ptr, before_PLTE); /* before PLTE */ + + png_write_info(write_ptr, write_info_ptr); + + write_chunks(write_ptr, before_IDAT); /* after PLTE */ +#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"); + +#ifdef PNG_READ_INTERLACING_SUPPORTED + num_pass = png_set_interlace_handling(read_ptr); + if (png_set_interlace_handling(write_ptr) != num_pass) + png_error(write_ptr, "png_set_interlace_handling: inconsistent num_pass"); +#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_STORE_UNKNOWN_CHUNKS_SUPPORTED +# 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 +#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); + + pngtest_check_text_support(read_ptr, text_ptr, num_text); + + if (verbose != 0) + { + int i; + + printf("\n"); + for (i=0; i 0) + { + /* We don't really expect to get here because of the setjmp handling + * above, but this is safe. + */ + fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", + inname, error_count, warning_count); + + if (strict != 0) + return (1); + } + +# ifdef PNG_WRITE_SUPPORTED + /* If there we no write support nothing was written! */ + else if (unsupported_chunks > 0) + { + fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", + inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); + } +# endif + + else if (warning_count > 0) + { + fprintf(STDERR, "\n %s: %d libpng warnings found", + inname, warning_count); + + if (strict != 0) + return (1); + } + + 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); + } + +#ifdef PNG_WRITE_SUPPORTED /* else nothing was written */ + if (interlace_preserved != 0) /* else the files will be changed */ + { + for (;;) + { + static int wrote_question = 0; + png_size_t num_in, num_out; + char inbuf[256], outbuf[256]; + + num_in = fread(inbuf, 1, sizeof inbuf, fpin); + num_out = fread(outbuf, 1, sizeof outbuf, fpout); + + if (num_in != num_out) + { + fprintf(STDERR, "\nFiles %s and %s are of a different size\n", + inname, outname); + + if (wrote_question == 0 && unsupported_chunks == 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 && unsupported_chunks == 0) + return (1); + + else + return (0); + } + + if (num_in == 0) + break; + + if (memcmp(inbuf, outbuf, num_in)) + { + fprintf(STDERR, "\nFiles %s and %s are different\n", inname, + outname); + + if (wrote_question == 0 && unsupported_chunks == 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); + + /* NOTE: the unsupported_chunks escape is permitted here because + * unsupported text chunk compression will result in the compression + * mode being changed (to NONE) yet, in the test case, the result + * can be exactly the same size! + */ + if (strict != 0 && unsupported_chunks == 0) + return (1); + + else + return (0); + } + } + } +#endif /* PNG_WRITE_SUPPORTED */ + + 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++; + relaxed = 0; + } + + else if (strcmp(argv[1], "--relaxed") == 0) + { + status_dots_requested = 0; + verbose = 1; + inname = argv[2]; + strict = 0; + relaxed++; + } + + 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 != 0) + { + 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); +} +#else +int +main(void) +{ + fprintf(STDERR, + " test ignored because libpng was not built with read support\n"); + /* And skip this test */ + return PNG_LIBPNG_VER < 10600 ? 0 : 77; +} +#endif + +/* Generate a compiler error if there is an old png.h in the search path. */ +typedef png_libpng_version_1_7_0beta35 Your_png_h_is_not_version_1_7_0beta35; diff --git a/ext/native/ext/libpng17/pngtrans.c b/ext/native/ext/libpng17/pngtrans.c new file mode 100644 index 0000000000..22499e49c2 --- /dev/null +++ b/ext/native/ext/libpng17/pngtrans.c @@ -0,0 +1,843 @@ + +/* pngtrans.c - transforms the data in a row (used by both readers and writers) + * + * Last changed in libpng 1.6.11 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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_structrp 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_structrp 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_structrp 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; +# ifdef PNG_WRITE_SUPPORTED + png_ptr->usr_bit_depth = 8; +# endif + } +} +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Turn on packed pixel swapping */ +void PNGAPI +png_set_packswap(png_structrp 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_structrp 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_structrp 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_structrp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_filler"); + + if (png_ptr == NULL) + return; + + /* In libpng 1.6 it is possible to determine whether this is a read or write + * operation and therefore to do more checking here for a valid call. + */ + if (png_ptr->mode & PNG_IS_READ_STRUCT) + { +# ifdef PNG_READ_FILLER_SUPPORTED + /* On read png_set_filler is always valid, regardless of the base PNG + * format, because other transformations can give a format where the + * filler code can execute (basically an 8 or 16-bit component RGB or G + * format.) + * + * NOTE: usr_channels is not used by the read code! (This has led to + * confusion in the past.) The filler is only used in the read code. + */ + png_ptr->filler = (png_uint_16)filler; +# else + png_app_error(png_ptr, "png_set_filler not supported on read"); + PNG_UNUSED(filler) /* not used in the write case */ + return; +# endif + } + + else /* write */ + { +# ifdef PNG_WRITE_FILLER_SUPPORTED + /* On write the usr_channels parameter must be set correctly at the + * start to record the number of channels in the app-supplied data. + */ + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_RGB: + png_ptr->usr_channels = 4; + break; + + case PNG_COLOR_TYPE_GRAY: + if (png_ptr->bit_depth >= 8) + { + png_ptr->usr_channels = 2; + break; + } + + else + { + /* There simply isn't any code in libpng to strip out bits + * from bytes when the components are less than a byte in + * size! + */ + png_app_error(png_ptr, + "png_set_filler is invalid for low bit depth gray output"); + return; + } + + default: + png_app_error(png_ptr, + "png_set_filler: inappropriate color type"); + return; + } +# else + png_app_error(png_ptr, "png_set_filler not supported on write"); + return; +# endif + } + + /* Here on success - libpng supports the operation, set the transformation + * and the flag to say where the filler channel is. + */ + png_ptr->transformations |= PNG_FILLER; + + if (filler_loc == PNG_FILLER_AFTER) + png_ptr->flags |= PNG_FLAG_FILLER_AFTER; + + else + png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; +} + +/* Added to libpng-1.2.7 */ +void PNGAPI +png_set_add_alpha(png_structrp 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); + /* The above may fail to do anything. */ + if (png_ptr->transformations & PNG_FILLER) + 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_structrp 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_structrp 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_structrp 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 != 0) /* 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 != 0) /* 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 != 0) /* 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 != 0) /* 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_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ + defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) +/* Added at libpng-1.5.10 */ +void /* PRIVATE */ +png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) +{ + if (png_ptr->num_palette < (1 << row_info->bit_depth) && + png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ + { + /* Calculations moved outside switch in an attempt to stop different + * compiler warnings. 'padding' is in *bits* within the last byte, it is + * an 'int' because pixel_depth becomes an 'int' in the expression below, + * and this calculation is used because it avoids warnings that other + * forms produced on either GCC or MSVC. + */ + int padding = (-row_info->pixel_depth * row_info->width) & 7; + png_bytep rp = png_ptr->row_buf + row_info->rowbytes; + + switch (row_info->bit_depth) + { + case 1: + { + /* in this case, all bytes must be 0 so we don't need + * to unpack the pixels except for the rightmost one. + */ + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp >> padding != 0) + png_ptr->num_palette_max = 1; + padding = 0; + } + + break; + } + + case 2: + { + for (; rp > png_ptr->row_buf; rp--) + { + int i = ((*rp >> padding) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 2) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 4) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 6) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + padding = 0; + } + + break; + } + + case 4: + { + for (; rp > png_ptr->row_buf; rp--) + { + int i = ((*rp >> padding) & 0x0f); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 4) & 0x0f); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + padding = 0; + } + + break; + } + + case 8: + { + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp > png_ptr->num_palette_max) + png_ptr->num_palette_max = (int) *rp; + } + + break; + } + + default: + break; + } + } +} +#endif /* PNG_CHECK_FOR_INVALID_INDEX_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_structrp 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; + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) + { + png_app_error(png_ptr, + "info change after png_start_read_image or png_read_update_info"); + return; + } +#endif + + 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_structrp png_ptr) +{ + if (png_ptr == NULL) + return (NULL); + + return png_ptr->user_transform_ptr; +} +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +png_uint_32 PNGAPI +png_get_current_row_number(png_const_structrp 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_structrp 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/ext/native/ext/libpng17/pngwio.c b/ext/native/ext/libpng17/pngwio.c new file mode 100644 index 0000000000..1b525f9484 --- /dev/null +++ b/ext/native/ext/libpng17/pngwio.c @@ -0,0 +1,168 @@ + +/* pngwio.c - functions for data output + * + * Last changed in libpng 1.6.9 [February 6, 2014] + * Copyright (c) 1998-2014 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_structrp 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_constcast(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. + */ +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"); +} +#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_structrp 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_voidcast(png_FILE_p, (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_structrp 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 +#else + PNG_UNUSED(output_flush_fn) +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ + +#ifdef PNG_READ_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"); + } +#endif +} +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngwrite.c b/ext/native/ext/libpng17/pngwrite.c new file mode 100644 index 0000000000..b43a16fc07 --- /dev/null +++ b/ext/native/ext/libpng17/pngwrite.c @@ -0,0 +1,2427 @@ + +/* pngwrite.c - general routines to write a PNG file + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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 + */ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include "pngpriv.h" +#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) +# include +#endif + +#ifdef PNG_WRITE_SUPPORTED + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +/* Write out all the unknown chunks for the current given location */ +static void +write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, + unsigned int where) +{ + if (info_ptr->unknown_chunks_num) + { + png_const_unknown_chunkp up; + + png_debug(5, "writing extra chunks"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + ++up) + if (up->location & where) + { + /* If per-chunk unknown chunk handling is enabled use it, otherwise + * just write the chunks the application has set. + */ +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + int keep = png_handle_as_unknown(png_ptr, up->name); + + /* NOTE: this code is radically different from the read side in the + * matter of handling an ancillary unknown chunk. In the read side + * the default behavior is to discard it, in the code below the default + * behavior is to write it. Critical chunks are, however, only + * written if explicitly listed or if the default is set to write all + * unknown chunks. + * + * The default handling is also slightly weird - it is not possible to + * stop the writing of all unsafe-to-copy chunks! + * + * TODO: REVIEW: this would seem to be a bug. + */ + if (keep != PNG_HANDLE_CHUNK_NEVER && + ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ || + keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_AS_DEFAULT && + png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS))) +#endif + { + /* TODO: review, what is wrong with a zero length unknown chunk? */ + 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_WRITE_UNKNOWN_CHUNKS_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_structrp png_ptr, png_const_inforp 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. + * + * 1.6.0: COLORSPACE support controls the writing of these chunks too, and + * the chunks will be written if the WRITE routine is there and information + * is available in the COLORSPACE. (See png_colorspace_sync_info in png.c + * for where the valid flags get set.) + * + * Under certain circumstances the colorspace can be invalidated without + * syncing the info_struct 'valid' flags; this happens if libpng detects and + * error and calls png_error while the color space is being set, yet the + * application continues writing the PNG. So check the 'invalid' flag here + * too. + */ +#ifdef PNG_GAMMA_SUPPORTED +# ifdef PNG_WRITE_gAMA_SUPPORTED + if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) && + (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) && + (info_ptr->valid & PNG_INFO_gAMA)) + png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma); +# endif +#endif + +#ifdef PNG_COLORSPACE_SUPPORTED + /* Write only one of sRGB or an ICC profile. If a profile was supplied + * and it matches one of the known sRGB ones issue a warning. + */ +# ifdef PNG_WRITE_iCCP_SUPPORTED + if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) && + (info_ptr->valid & PNG_INFO_iCCP)) + { +# ifdef PNG_WRITE_sRGB_SUPPORTED + if (info_ptr->valid & PNG_INFO_sRGB) + png_app_warning(png_ptr, + "profile matches sRGB but writing iCCP instead"); +# endif + + png_write_iCCP(png_ptr, info_ptr->iccp_name, + info_ptr->iccp_profile); + } +# ifdef PNG_WRITE_sRGB_SUPPORTED + else +# endif +# endif + +# ifdef PNG_WRITE_sRGB_SUPPORTED + if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) && + (info_ptr->valid & PNG_INFO_sRGB)) + png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); +# endif /* WRITE_sRGB */ +#endif /* COLORSPACE */ + +#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_COLORSPACE_SUPPORTED +# ifdef PNG_WRITE_cHRM_SUPPORTED + if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) && + (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) && + (info_ptr->valid & PNG_INFO_cHRM)) + png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); +# endif +#endif + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); +#endif + + png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; + } +} + +void PNGAPI +png_write_info(png_structrp png_ptr, png_const_inforp 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, jend; + + jend = info_ptr->num_trans; + if (jend > PNG_MAX_PALETTE_LENGTH) + jend = PNG_MAX_PALETTE_LENGTH; + + for (j = 0; jtrans_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 + write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE); +#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_structrp png_ptr, png_inforp 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"); + +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED + if (png_ptr->num_palette_max > png_ptr->num_palette) + png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); +#endif + + /* 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 + write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); +#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 +void PNGAPI +png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * 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) +{ +#ifndef PNG_USER_MEM_SUPPORTED + png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, NULL, NULL, NULL); +#else + 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 */ +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) +{ + png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); +#endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr != NULL) + { + /* Set the zlib control values to defaults; they can be overridden by the + * application after the struct has been created. + */ + png_ptr->zbuffer_size = PNG_ZBUF_SIZE; + + /* The 'zlib_strategy' setting is irrelevant because png_default_claim in + * pngwutil.c defaults it according to whether or not filters will be + * used, and ignores this setting. + */ + png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY; + png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION; + png_ptr->zlib_mem_level = 8; + png_ptr->zlib_window_bits = 15; + png_ptr->zlib_method = 8; + +#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED + png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY; + png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION; + png_ptr->zlib_text_mem_level = 8; + png_ptr->zlib_text_window_bits = 15; + png_ptr->zlib_text_method = 8; +#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ + + /* This is a highly dubious configuration option; by default it is off, + * but it may be appropriate for private builds that are testing + * extensions not conformant to the current specification, or of + * applications that must not fail to write at all costs! + */ +#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; + /* In stable builds only warn if an application error can be completely + * handled. + */ +#endif + + /* App warnings are warnings in release (or release candidate) builds but + * are errors during development. + */ +#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC + png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; +#endif + + /* TODO: delay this, it can be done in png_init_io() (if the app doesn't + * do it itself) avoiding setting the default function if it is not + * required. + */ + png_set_write_fn(png_ptr, NULL, NULL, NULL); + } + + 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_structrp 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_structrp 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); + } + } +} + +#ifdef PNG_MNG_FEATURES_SUPPORTED +/* Performs intrapixel differencing */ +static void +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 */ + +/* Called by user to write a row of image data */ +void PNGAPI +png_write_row(png_structrp 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. */ + 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 == 0) + { + 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 + +/* Added at libpng-1.5.10 */ +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Check for out-of-range palette index */ + if (row_info.color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, &row_info); +#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_structrp 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_structrp png_ptr) +{ + 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; + + png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH); + png_ptr->flush_rows = 0; + png_flush(png_ptr); +} +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */ +#endif + +/* Free any memory used in png_ptr struct without freeing the struct itself. */ +static void +png_write_destroy(png_structrp png_ptr) +{ + png_debug(1, "in png_write_destroy"); + + /* Free any memory zlib uses */ + if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) + deflateEnd(&png_ptr->zstream); + + /* Free our memory. png_free checks NULL for us. */ + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); + 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_SET_UNKNOWN_CHUNKS_SUPPORTED + png_free(png_ptr, png_ptr->chunk_list); +#endif + + /* The error handling and memory handling information is left intact at this + * point: the jmp_buf may still have to be freed. See png_destroy_png_struct + * for how this happens. + */ +} + +/* Free all memory used by the write. + * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for + * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free + * the passed in info_structs but it would quietly fail to free any of the data + * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it + * has no png_ptr.) + */ +void PNGAPI +png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) +{ + png_debug(1, "in png_destroy_write_struct"); + + if (png_ptr_ptr != NULL) + { + png_structrp png_ptr = *png_ptr_ptr; + + if (png_ptr != NULL) /* added in libpng 1.6.0 */ + { + png_destroy_info_struct(png_ptr, info_ptr_ptr); + + *png_ptr_ptr = NULL; + png_write_destroy(png_ptr); + png_destroy_png_struct(png_ptr); + } + } +} + +/* Allow the application to select one or more row filters to use. */ +void PNGAPI +png_set_filter(png_structrp 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 + + /* The only supported method, except for the check above, is + * PNG_FILTER_TYPE_BASE. The code below does not use 'method' other than + * for the check, so just keep going if png_app_error returns. + */ + if (method != PNG_FILTER_TYPE_BASE) + png_app_error(png_ptr, "Unknown custom filter method"); + + /* If filter writing is not supported the 'filters' value must be zero, + * otherwise the value must be a single, valid, filter value or a set of the + * mask values. The defines in png.h are such that the filter masks used in + * this API and internally are 1<<(3+value), value is in the range 0..4, so + * this fits in a byte. + */ +# ifdef PNG_WRITE_FILTER_SUPPORTED + /* Notice that PNG_NO_FILTERS is 0 and passes this test; this is OK + * because filters then gets set to PNG_FILTER_NONE, as is required. + */ + if (filters < PNG_FILTER_VALUE_LAST) + filters = 0x08 << filters; + + else if ((filters & ~PNG_ALL_FILTERS) != 0) + { + png_app_error(png_ptr, "png_set_filter: invalid filters mask/value"); + + /* For compatibility with the previous behavior assume a mask value was + * passed and ignore the non-mask bits. + */ + filters &= PNG_ALL_FILTERS; + + /* For a possibly foolish consistency (it shouldn't matter) set + * PNG_FILTER_NONE rather than 0. + */ + if (filters == 0) + filters = PNG_FILTER_NONE; + } +# else + /* PNG_FILTER_VALUE_NONE and PNG_NO_FILTERS are both 0. */ + if (filters != 0 && filters != PNG_FILTER_NONE) + png_app_error(png_ptr, "png_set_filter: no filters supported"); + + filters = PNG_FILTER_NONE; +# endif + +# ifdef 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. + * + * NOTE: this is a nasty constraint on the code, because it means that the + * prev_row buffer must be maintained even if there are currently no + * 'prev_row' requiring filters active. + */ + if (png_ptr->row_buf != NULL) + { + /* Repeat the checks in png_write_start_row; 1 pixel high or wide + * images cannot benefit from certain filters. If this isn't done here + * the check below will fire on 1 pixel high images. + */ + if (png_ptr->height == 1) + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (png_ptr->width == 1) + filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0 + && png_ptr->prev_row == NULL) + { + /* This is the error case, however it is benign - the previous row + * is not available so the filter can't be used. Just warn here. + */ + png_app_warning(png_ptr, + "png_set_filter: UP/AVG/PAETH cannot be added after start"); + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); + } + + /* Allocate any required buffers that have not already been allocated. + */ + png_write_alloc_filter_row_buffers(png_ptr, filters); + } +# endif /* PNG_WRITE_FILTER_SUPPORTED */ + + /* Finally store the value. + * TODO: this field could probably be removed if neither READ nor + * WRITE_FILTER are supported. + */ + png_ptr->do_filter = (png_byte)filters; /* SAFE: checked above */ +} + +/* 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_structrp 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_structrp 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)((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)((sizeof (png_uint_16)) * num_weights)); + + png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)((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)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); + + png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)((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_structrp 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_structrp 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_structrp png_ptr, int level) +{ + png_debug(1, "in png_set_compression_level"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_level = level; +} + +void PNGAPI +png_set_compression_mem_level(png_structrp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_compression_mem_level"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_mem_level = mem_level; +} + +void PNGAPI +png_set_compression_strategy(png_structrp png_ptr, int strategy) +{ + png_debug(1, "in png_set_compression_strategy"); + + if (png_ptr == NULL) + return; + + /* The flag setting here prevents the libpng dynamic selection of strategy. + */ + 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_structrp png_ptr, int window_bits) +{ + if (png_ptr == NULL) + return; + + /* Prior to 1.6.0 this would warn but then set the window_bits value, this + * meant that negative window bits values could be selected which would cause + * libpng to write a non-standard PNG file with raw deflate or gzip + * compressed IDAT or ancillary chunks. Such files can be read and there is + * no warning on read, so this seems like a very bad idea. + */ + if (window_bits > 15) + { + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + window_bits = 15; + } + + else if (window_bits < 8) + { + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + window_bits = 8; + } + + png_ptr->zlib_window_bits = window_bits; +} + +void PNGAPI +png_set_compression_method(png_structrp png_ptr, int method) +{ + png_debug(1, "in png_set_compression_method"); + + if (png_ptr == NULL) + return; + + /* This would produce an invalid PNG file if it worked, but it doesn't and + * deflate will fault it, so it is harmless to just warn here. + */ + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + + 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_structrp png_ptr, int level) +{ + png_debug(1, "in png_set_text_compression_level"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_text_level = level; +} + +void PNGAPI +png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_text_compression_mem_level"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_text_mem_level = mem_level; +} + +void PNGAPI +png_set_text_compression_strategy(png_structrp png_ptr, int strategy) +{ + png_debug(1, "in png_set_text_compression_strategy"); + + if (png_ptr == NULL) + return; + + 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_structrp 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"); + window_bits = 15; + } + + else if (window_bits < 8) + { + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + window_bits = 8; + } + + png_ptr->zlib_text_window_bits = window_bits; +} + +void PNGAPI +png_set_text_compression_method(png_structrp 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->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_structrp 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_structrp 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_structrp png_ptr, png_inforp info_ptr, + int transforms, voidp params) +{ + if (png_ptr == NULL || info_ptr == NULL) + return; + + if ((info_ptr->valid & PNG_INFO_IDAT) == 0) + { + png_app_error(png_ptr, "no rows for png_write_image to write"); + return; + } + + /* Write the file header information. */ + png_write_info(png_ptr, info_ptr); + + /* ------ these transformations don't touch the info structure ------- */ + + /* Invert monochrome pixels */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) +#ifdef PNG_WRITE_INVERT_SUPPORTED + png_set_invert_mono(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); +#endif + + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ + if (transforms & PNG_TRANSFORM_SHIFT) +#ifdef PNG_WRITE_SHIFT_SUPPORTED + if (info_ptr->valid & PNG_INFO_sBIT) + png_set_shift(png_ptr, &info_ptr->sig_bit); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); +#endif + + /* Pack pixels into bytes */ + if (transforms & PNG_TRANSFORM_PACKING) +#ifdef PNG_WRITE_PACK_SUPPORTED + png_set_packing(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); +#endif + + /* Swap location of alpha bytes from ARGB to RGBA */ + if (transforms & PNG_TRANSFORM_SWAP_ALPHA) +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED + png_set_swap_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); +#endif + + /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into + * RGB, note that the code expects the input color type to be G or RGB; no + * alpha channel. + */ + if (transforms & + (PNG_TRANSFORM_STRIP_FILLER_AFTER|PNG_TRANSFORM_STRIP_FILLER_BEFORE)) + { +#ifdef PNG_WRITE_FILLER_SUPPORTED + if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) + { + if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) + png_app_error(png_ptr, + "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); + + /* Continue if ignored - this is the pre-1.6.10 behavior */ + 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); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported"); +#endif + } + + /* Flip BGR pixels to RGB */ + if (transforms & PNG_TRANSFORM_BGR) +#ifdef PNG_WRITE_BGR_SUPPORTED + png_set_bgr(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); +#endif + + /* Swap bytes of 16-bit files to most significant byte first */ + if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) +#ifdef PNG_WRITE_SWAP_SUPPORTED + png_set_swap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); +#endif + + /* Swap bits of 1, 2, 4 bit packed pixel formats */ + if (transforms & PNG_TRANSFORM_PACKSWAP) +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED + png_set_packswap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); +#endif + + /* Invert the alpha channel from opacity to transparency */ + if (transforms & PNG_TRANSFORM_INVERT_ALPHA) +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + png_set_invert_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); +#endif + + /* ----------------------- end of transformations ------------------- */ + + /* Write the bits */ + 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(params) +} +#endif + + +#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED +#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */ +/* Initialize the write structure - general purpose utility. */ +static int +png_image_write_init(png_imagep image) +{ + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, + png_safe_error, png_safe_warning); + + if (png_ptr != NULL) + { + png_infop info_ptr = png_create_info_struct(png_ptr); + + if (info_ptr != NULL) + { + png_controlp control = png_voidcast(png_controlp, + png_malloc_warn(png_ptr, (sizeof *control))); + + if (control != NULL) + { + memset(control, 0, (sizeof *control)); + + control->png_ptr = png_ptr; + control->info_ptr = info_ptr; + control->for_write = 1; + + image->opaque = control; + return 1; + } + + /* Error clean up */ + png_destroy_info_struct(png_ptr, &info_ptr); + } + + png_destroy_write_struct(&png_ptr, NULL); + } + + return png_image_error(image, "png_image_write_: out of memory"); +} + +/* Arguments to png_image_write_main: */ +typedef struct +{ + /* Arguments: */ + png_imagep image; + png_const_voidp buffer; + png_int_32 row_stride; + png_const_voidp colormap; + int convert_to_8bit; + /* Local variables: */ + png_const_voidp first_row; + ptrdiff_t row_bytes; + png_voidp local_row; +} png_image_write_control; + +/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to + * do any necessary byte swapping. The component order is defined by the + * png_image format value. + */ +static int +png_write_image_16bit(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + + png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, + display->first_row); + png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); + png_uint_16p row_end; + const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1; + int aindex = 0; + png_uint_32 y = image->height; + + if (image->format & PNG_FORMAT_FLAG_ALPHA) + { +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if (image->format & PNG_FORMAT_FLAG_AFIRST) + { + aindex = -1; + ++input_row; /* To point to the first component */ + ++output_row; + } + + else +# endif + aindex = channels; + } + + else + png_error(png_ptr, "png_write_image: internal call error"); + + /* Work out the output row end and count over this, note that the increment + * above to 'row' means that row_end can actually be beyond the end of the + * row; this is correct. + */ + row_end = output_row + image->width * (channels+1); + + while (y-- > 0) + { + png_const_uint_16p in_ptr = input_row; + png_uint_16p out_ptr = output_row; + + while (out_ptr < row_end) + { + const png_uint_16 alpha = in_ptr[aindex]; + png_uint_32 reciprocal = 0; + int c; + + out_ptr[aindex] = alpha; + + /* Calculate a reciprocal. The correct calculation is simply + * component/alpha*65535 << 15. (I.e. 15 bits of precision); this + * allows correct rounding by adding .5 before the shift. 'reciprocal' + * is only initialized when required. + */ + if (alpha > 0 && alpha < 65535) + reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; + + c = channels; + do /* always at least one channel */ + { + png_uint_16 component = *in_ptr++; + + /* The following gives 65535 for an alpha of 0, which is fine, + * otherwise if 0/0 is represented as some other value there is more + * likely to be a discontinuity which will probably damage + * compression when moving from a fully transparent area to a + * nearly transparent one. (The assumption here is that opaque + * areas tend not to be 0 intensity.) + */ + if (component >= alpha) + component = 65535; + + /* component 0 && alpha < 65535) + { + png_uint_32 calc = component * reciprocal; + calc += 16384; /* round to nearest */ + component = (png_uint_16)(calc >> 15); + } + + *out_ptr++ = component; + } + while (--c > 0); + + /* Skip to next component (skip the intervening alpha channel) */ + ++in_ptr; + ++out_ptr; + } + + png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); + input_row += display->row_bytes/(sizeof (png_uint_16)); + } + + return 1; +} + +/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel + * is present it must be removed from the components, the components are then + * written in sRGB encoding. No components are added or removed. + * + * Calculate an alpha reciprocal to reverse pre-multiplication. As above the + * calculation can be done to 15 bits of accuracy; however, the output needs to + * be scaled in the range 0..255*65535, so include that scaling here. + */ +#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha) + +static png_byte +png_unpremultiply(png_uint_32 component, png_uint_32 alpha, + png_uint_32 reciprocal/*from the above macro*/) +{ + /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 + * is represented as some other value there is more likely to be a + * discontinuity which will probably damage compression when moving from a + * fully transparent area to a nearly transparent one. (The assumption here + * is that opaque areas tend not to be 0 intensity.) + * + * There is a rounding problem here; if alpha is less than 128 it will end up + * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the + * output change for this too. + */ + if (component >= alpha || alpha < 128) + return 255; + + /* component 0) + { + /* The test is that alpha/257 (rounded) is less than 255, the first value + * that becomes 255 is 65407. + * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore, + * be exact!) [Could also test reciprocal != 0] + */ + if (alpha < 65407) + { + component *= reciprocal; + component += 64; /* round to nearest */ + component >>= 7; + } + + else + component *= 255; + + /* Convert the component to sRGB. */ + return (png_byte)PNG_sRGB_FROM_LINEAR(component); + } + + else + return 0; +} + +static int +png_write_image_8bit(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + + png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, + display->first_row); + png_bytep output_row = png_voidcast(png_bytep, display->local_row); + png_uint_32 y = image->height; + const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1; + + if (image->format & PNG_FORMAT_FLAG_ALPHA) + { + png_bytep row_end; + int aindex; + +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if (image->format & PNG_FORMAT_FLAG_AFIRST) + { + aindex = -1; + ++input_row; /* To point to the first component */ + ++output_row; + } + + else +# endif + aindex = channels; + + /* Use row_end in place of a loop counter: */ + row_end = output_row + image->width * (channels+1); + + while (y-- > 0) + { + png_const_uint_16p in_ptr = input_row; + png_bytep out_ptr = output_row; + + while (out_ptr < row_end) + { + png_uint_16 alpha = in_ptr[aindex]; + png_byte alphabyte = (png_byte)PNG_DIV257(alpha); + png_uint_32 reciprocal = 0; + int c; + + /* Scale and write the alpha channel. */ + out_ptr[aindex] = alphabyte; + + if (alphabyte > 0 && alphabyte < 255) + reciprocal = UNP_RECIPROCAL(alpha); + + c = channels; + do /* always at least one channel */ + *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); + while (--c > 0); + + /* Skip to next component (skip the intervening alpha channel) */ + ++in_ptr; + ++out_ptr; + } /* while out_ptr < row_end */ + + png_write_row(png_ptr, png_voidcast(png_const_bytep, + display->local_row)); + input_row += display->row_bytes/(sizeof (png_uint_16)); + } /* while y */ + } + + else + { + /* No alpha channel, so the row_end really is the end of the row and it + * is sufficient to loop over the components one by one. + */ + png_bytep row_end = output_row + image->width * channels; + + while (y-- > 0) + { + png_const_uint_16p in_ptr = input_row; + png_bytep out_ptr = output_row; + + while (out_ptr < row_end) + { + png_uint_32 component = *in_ptr++; + + component *= 255; + *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component); + } + + png_write_row(png_ptr, output_row); + input_row += display->row_bytes/(sizeof (png_uint_16)); + } + } + + return 1; +} + +static void +png_image_set_PLTE(png_image_write_control *display) +{ + const png_imagep image = display->image; + const void *cmap = display->colormap; + const int entries = image->colormap_entries > 256 ? 256 : + (int)image->colormap_entries; + + /* NOTE: the caller must check for cmap != NULL and entries != 0 */ + const png_uint_32 format = image->format; + const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); + +# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ + defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) + const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && + (format & PNG_FORMAT_FLAG_ALPHA) != 0; +# else +# define afirst 0 +# endif + +# ifdef PNG_FORMAT_BGR_SUPPORTED + const int bgr = (format & PNG_FORMAT_FLAG_BGR) ? 2 : 0; +# else +# define bgr 0 +# endif + + int i, num_trans; + png_color palette[256]; + png_byte tRNS[256]; + + memset(tRNS, 255, (sizeof tRNS)); + memset(palette, 0, (sizeof palette)); + + for (i=num_trans=0; i= 3) /* RGB */ + { + palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[(2 ^ bgr)]); + palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[1]); + palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[bgr]); + } + + else /* Gray */ + palette[i].blue = palette[i].red = palette[i].green = + (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry); + } + + else /* alpha */ + { + png_uint_16 alpha = entry[afirst ? 0 : channels-1]; + png_byte alphabyte = (png_byte)PNG_DIV257(alpha); + png_uint_32 reciprocal = 0; + + /* Calculate a reciprocal, as in the png_write_image_8bit code above + * this is designed to produce a value scaled to 255*65535 when + * divided by 128 (i.e. asr 7). + */ + if (alphabyte > 0 && alphabyte < 255) + reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha; + + tRNS[i] = alphabyte; + if (alphabyte < 255) + num_trans = i+1; + + if (channels >= 3) /* RGB */ + { + palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], + alpha, reciprocal); + palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, + reciprocal); + palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, + reciprocal); + } + + else /* gray */ + palette[i].blue = palette[i].red = palette[i].green = + png_unpremultiply(entry[afirst], alpha, reciprocal); + } + } + + else /* Color-map has sRGB values */ + { + png_const_bytep entry = png_voidcast(png_const_bytep, cmap); + + entry += i * channels; + + switch (channels) + { + case 4: + tRNS[i] = entry[afirst ? 0 : 3]; + if (tRNS[i] < 255) + num_trans = i+1; + /* FALL THROUGH */ + case 3: + palette[i].blue = entry[afirst + (2 ^ bgr)]; + palette[i].green = entry[afirst + 1]; + palette[i].red = entry[afirst + bgr]; + break; + + case 2: + tRNS[i] = entry[1 ^ afirst]; + if (tRNS[i] < 255) + num_trans = i+1; + /* FALL THROUGH */ + case 1: + palette[i].blue = palette[i].red = palette[i].green = + entry[afirst]; + break; + + default: + break; + } + } + } + +# ifdef afirst +# undef afirst +# endif +# ifdef bgr +# undef bgr +# endif + + png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, + entries); + + if (num_trans > 0) + png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, + num_trans, NULL); + + image->colormap_entries = entries; +} + +static int +png_image_write_main(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + png_uint_32 format = image->format; + + int colormap = (format & PNG_FORMAT_FLAG_COLORMAP) != 0; + int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */ + int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0; + int write_16bit = linear && !colormap && !display->convert_to_8bit; + +# ifdef PNG_BENIGN_ERRORS_SUPPORTED + /* Make sure we error out on any bad situation */ + png_set_benign_errors(png_ptr, 0/*error*/); +# endif + + /* Default the 'row_stride' parameter if required. */ + if (display->row_stride == 0) + display->row_stride = PNG_IMAGE_ROW_STRIDE(*image); + + /* Set the required transforms then write the rows in the correct order. */ + if (format & PNG_FORMAT_FLAG_COLORMAP) + { + if (display->colormap != NULL && image->colormap_entries > 0) + { + png_uint_32 entries = image->colormap_entries; + + png_set_IHDR(png_ptr, info_ptr, image->width, image->height, + entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), + PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_image_set_PLTE(display); + } + + else + png_error(image->opaque->png_ptr, + "no color-map for color-mapped image"); + } + + else + png_set_IHDR(png_ptr, info_ptr, image->width, image->height, + write_16bit ? 16 : 8, + ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + + ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + /* Counter-intuitively the data transformations must be called *after* + * png_write_info, not before as in the read code, but the 'set' functions + * must still be called before. Just set the color space information, never + * write an interlaced image. + */ + + if (write_16bit != 0) + { + /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); + + if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB)) + png_set_cHRM_fixed(png_ptr, info_ptr, + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000 + ); + } + + else if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB)) + png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); + + /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit + * space must still be gamma encoded. + */ + else + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); + + /* Write the file header. */ + png_write_info(png_ptr, info_ptr); + + /* Now set up the data transformations (*after* the header is written), + * remove the handled transformations from the 'format' flags for checking. + * + * First check for a little endian system if writing 16 bit files. + */ + if (write_16bit != 0) + { + PNG_CONST png_uint_16 le = 0x0001; + + if (*(png_const_bytep)&le) + png_set_swap(png_ptr); + } + +# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED + if (format & PNG_FORMAT_FLAG_BGR) + { + if (!colormap && (format & PNG_FORMAT_FLAG_COLOR) != 0) + png_set_bgr(png_ptr); + format &= ~PNG_FORMAT_FLAG_BGR; + } +# endif + +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if (format & PNG_FORMAT_FLAG_AFIRST) + { + if (!colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0) + png_set_swap_alpha(png_ptr); + format &= ~PNG_FORMAT_FLAG_AFIRST; + } +# endif + + /* If there are 16 or fewer color-map entries we wrote a lower bit depth + * above, but the application data is still byte packed. + */ + if (colormap && image->colormap_entries <= 16) + png_set_packing(png_ptr); + + /* That should have handled all (both) the transforms. */ + if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR | + PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0) + png_error(png_ptr, "png_write_image: unsupported transformation"); + + { + png_const_bytep row = png_voidcast(png_const_bytep, display->buffer); + ptrdiff_t row_bytes = display->row_stride; + + if (linear != 0) + row_bytes *= (sizeof (png_uint_16)); + + if (row_bytes < 0) + row += (image->height-1) * (-row_bytes); + + display->first_row = row; + display->row_bytes = row_bytes; + } + + /* Apply 'fast' options if the flag is set. */ + if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0) + { + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS); + /* NOTE: determined by experiment using pngstest, this reflects some + * balance between the time to write the image once and the time to read + * it about 50 times. The speed-up in pngstest was about 10-20% of the + * total (user) time on a heavily loaded system. + */ + png_set_compression_level(png_ptr, 3); + } + + /* Check for the cases that currently require a pre-transform on the row + * before it is written. This only applies when the input is 16-bit and + * either there is an alpha channel or it is converted to 8-bit. + */ + if ((linear && alpha) || (!colormap && display->convert_to_8bit)) + { + png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, + png_get_rowbytes(png_ptr, info_ptr))); + int result; + + display->local_row = row; + if (write_16bit != 0) + result = png_safe_execute(image, png_write_image_16bit, display); + else + result = png_safe_execute(image, png_write_image_8bit, display); + display->local_row = NULL; + + png_free(png_ptr, row); + + /* Skip the 'write_end' on error: */ + if (result == 0) + return 0; + } + + /* Otherwise this is the case where the input is in a format currently + * supported by the rest of the libpng write code; call it directly. + */ + else + { + png_const_bytep row = png_voidcast(png_const_bytep, display->first_row); + ptrdiff_t row_bytes = display->row_bytes; + png_uint_32 y = image->height; + + while (y-- > 0) + { + png_write_row(png_ptr, row); + row += row_bytes; + } + } + + png_write_end(png_ptr, info_ptr); + return 1; +} + +int PNGAPI +png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, + const void *buffer, png_int_32 row_stride, const void *colormap) +{ + /* Write the image to the given (FILE*). */ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file != NULL) + { + if (png_image_write_init(image)) + { + png_image_write_control display; + int result; + + /* This is slightly evil, but png_init_io doesn't do anything other + * than this and we haven't changed the standard IO functions so + * this saves a 'safe' function. + */ + image->opaque->png_ptr->io_ptr = file; + + memset(&display, 0, (sizeof display)); + display.image = image; + display.buffer = buffer; + display.row_stride = row_stride; + display.colormap = colormap; + display.convert_to_8bit = convert_to_8bit; + + result = png_safe_execute(image, png_image_write_main, &display); + png_image_free(image); + return result; + } + + else + return 0; + } + + else + return png_image_error(image, + "png_image_write_to_stdio: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); + + else + return 0; +} + +int PNGAPI +png_image_write_to_file(png_imagep image, const char *file_name, + int convert_to_8bit, const void *buffer, png_int_32 row_stride, + const void *colormap) +{ + /* Write the image to the named file. */ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file_name != NULL) + { + FILE *fp = fopen(file_name, "wb"); + + if (fp != NULL) + { + if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, + row_stride, colormap)) + { + int error; /* from fflush/fclose */ + + /* Make sure the file is flushed correctly. */ + if (fflush(fp) == 0 && ferror(fp) == 0) + { + if (fclose(fp) == 0) + return 1; + + error = errno; /* from fclose */ + } + + else + { + error = errno; /* from fflush or ferror */ + (void)fclose(fp); + } + + (void)remove(file_name); + /* The image has already been cleaned up; this is just used to + * set the error (because the original write succeeded). + */ + return png_image_error(image, strerror(error)); + } + + else + { + /* Clean up: just the opened file. */ + (void)fclose(fp); + (void)remove(file_name); + return 0; + } + } + + else + return png_image_error(image, strerror(errno)); + } + + else + return png_image_error(image, + "png_image_write_to_file: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); + + else + return 0; +} +#endif /* PNG_STDIO_SUPPORTED */ +#endif /* SIMPLIFIED_WRITE */ +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngwtran.c b/ext/native/ext/libpng17/pngwtran.c new file mode 100644 index 0000000000..215bd68a9d --- /dev/null +++ b/ext/native/ext/libpng17/pngwtran.c @@ -0,0 +1,572 @@ + +/* pngwtran.c - transforms the data in a row for PNG writers + * + * Last changed in libpng 1.6.9 [February 6, 2014] + * Copyright (c) 1998-2014 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 + +#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). + */ +static void +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. + */ +static void +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; + unsigned int 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++) + { + int j; + unsigned int v, out; + + v = *bp; + out = 0; + + for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) + { + if (j > 0) + out |= v << j; + + else + out |= (v >> (-j)) & mask; + } + + *bp = (png_byte)(out & 0xff); + } + } + + 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++) + { + + const unsigned int c = i%channels; + int j; + unsigned int v, out; + + v = *bp; + out = 0; + + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + out |= v << j; + + else + out |= v >> (-j); + } + + *bp = (png_byte)(out & 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++) + { + const unsigned int c = i%channels; + int j; + unsigned int value, v; + + v = png_get_uint_16(bp); + value = 0; + + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + value |= v << j; + + else + value |= v >> (-j); + } + *bp++ = (png_byte)((value >> 8) & 0xff); + *bp++ = (png_byte)(value & 0xff); + } + } + } +} +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +static void +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 +static void +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 + +/* Transform the data according to the user's wishes. The order of + * transformations is significant. + */ +void /* PRIVATE */ +png_do_write_transformations(png_structrp 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 +} +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/ext/native/ext/libpng17/pngwutil.c b/ext/native/ext/libpng17/pngwutil.c new file mode 100644 index 0000000000..df2ffdb9df --- /dev/null +++ b/ext/native/ext/libpng17/pngwutil.c @@ -0,0 +1,3062 @@ + +/* pngwutil.c - utilities to write a PNG file + * + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] + * Copyright (c) 1998-2014 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); +} + +/* 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_structrp 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_31_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_structrp 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); +} + +/* This is used below to find the size of an image to pass to png_deflate_claim, + * so it only needs to be accurate if the size is less than 16384 bytes (the + * point at which a lower LZ window size can be used.) + */ +static png_alloc_size_t +png_image_size(png_structrp png_ptr) +{ + /* Only return sizes up to the maximum of a png_uint_32, do this by limiting + * the width and height used to 15 bits. + */ + png_uint_32 h = png_ptr->height; + + if (png_ptr->rowbytes < 32768 && h < 32768) + { + if (png_ptr->interlaced) + { + /* Interlacing makes the image larger because of the replication of + * both the filter byte and the padding to a byte boundary. + */ + png_uint_32 w = png_ptr->width; + unsigned int pd = png_ptr->pixel_depth; + png_alloc_size_t cb_base; + int pass; + + for (cb_base=0, pass=0; pass<=6; ++pass) + { + png_uint_32 pw = PNG_PASS_COLS(w, pass); + + if (pw > 0) + cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass); + } + + return cb_base; + } + + else + return (png_ptr->rowbytes+1) * h; + } + + else + return 0xffffffffU; +} + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + /* This is the code to hack the first two bytes of the deflate stream (the + * deflate header) to correct the windowBits value to match the actual data + * size. Note that the second argument is the *uncompressed* size but the + * first argument is the *compressed* data (and it must be deflate + * compressed.) + */ +static void +optimize_cmf(png_bytep data, png_alloc_size_t data_size) +{ + /* Optimize the CMF field in the zlib stream. The resultant zlib stream is + * still compliant to the stream specification. + */ + if (data_size <= 16384) /* else windowBits must be 15 */ + { + unsigned int z_cmf = data[0]; /* zlib compression method and flags */ + + if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + { + unsigned int z_cinfo; + unsigned int half_z_window_size; + + z_cinfo = z_cmf >> 4; + half_z_window_size = 1U << (z_cinfo + 7); + + if (data_size <= half_z_window_size) /* else no change */ + { + unsigned int tmp; + + do + { + half_z_window_size >>= 1; + --z_cinfo; + } + while (z_cinfo > 0 && data_size <= half_z_window_size); + + z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); + + data[0] = (png_byte)z_cmf; + tmp = data[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + data[1] = (png_byte)tmp; + } + } + } +} +#else +# define optimize_cmf(dp,dl) ((void)0) +#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ + +/* Initialize the compressor for the appropriate type of compression. */ +static int +png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, + png_alloc_size_t data_size) +{ + if (png_ptr->zowner != 0) + { + char msg[64]; + + PNG_STRING_FROM_CHUNK(msg, owner); + msg[4] = ':'; + msg[5] = ' '; + PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner); + /* So the message that results is " using zstream"; this is an + * internal error, but is very useful for debugging. i18n requirements + * are minimal. + */ + (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); +# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC + png_warning(png_ptr, msg); + + /* Attempt sane error recovery */ + if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */ + { + png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT"); + return Z_STREAM_ERROR; + } + + png_ptr->zowner = 0; +# else + png_error(png_ptr, msg); +# endif + } + + { + int level = png_ptr->zlib_level; + int method = png_ptr->zlib_method; + int windowBits = png_ptr->zlib_window_bits; + int memLevel = png_ptr->zlib_mem_level; + int strategy; /* set below */ + int ret; /* zlib return code */ + + if (owner == png_IDAT) + { + if (png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) + strategy = png_ptr->zlib_strategy; + + else if (png_ptr->do_filter != PNG_FILTER_NONE) + strategy = PNG_Z_DEFAULT_STRATEGY; + + else + strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; + } + + else + { +# ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + level = png_ptr->zlib_text_level; + method = png_ptr->zlib_text_method; + windowBits = png_ptr->zlib_text_window_bits; + memLevel = png_ptr->zlib_text_mem_level; + strategy = png_ptr->zlib_text_strategy; +# else + /* If customization is not supported the values all come from the + * IDAT values except for the strategy, which is fixed to the + * default. (This is the pre-1.6.0 behavior too, although it was + * implemented in a very different way.) + */ + strategy = Z_DEFAULT_STRATEGY; +# endif + } + + /* Adjust 'windowBits' down if larger than 'data_size'; to stop this + * happening just pass 32768 as the data_size parameter. Notice that zlib + * requires an extra 262 bytes in the window in addition to the data to be + * able to see the whole of the data, so if data_size+262 takes us to the + * next windowBits size we need to fix up the value later. (Because even + * though deflate needs the extra window, inflate does not!) + */ + if (data_size <= 16384) + { + /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to + * work round a Microsoft Visual C misbehavior which, contrary to C-90, + * widens the result of the following shift to 64-bits if (and, + * apparently, only if) it is used in a test. + */ + unsigned int half_window_size = 1U << (windowBits-1); + + while (data_size + 262 <= half_window_size) + { + half_window_size >>= 1; + --windowBits; + } + } + + /* Check against the previous initialized values, if any. */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) && + (png_ptr->zlib_set_level != level || + png_ptr->zlib_set_method != method || + png_ptr->zlib_set_window_bits != windowBits || + png_ptr->zlib_set_mem_level != memLevel || + png_ptr->zlib_set_strategy != strategy)) + { + if (deflateEnd(&png_ptr->zstream) != Z_OK) + png_warning(png_ptr, "deflateEnd failed (ignored)"); + + png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED; + } + + /* For safety clear out the input and output pointers (currently zlib + * doesn't use them on Init, but it might in the future). + */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->zstream.avail_out = 0; + + /* Now initialize if required, setting the new parameters, otherwise just + * to a simple reset to the previous parameters. + */ + if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) + ret = deflateReset(&png_ptr->zstream); + + else + { + ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, + memLevel, strategy); + + if (ret == Z_OK) + png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; + } + + /* The return code is from either deflateReset or deflateInit2; they have + * pretty much the same set of error codes. + */ + if (ret == Z_OK) + png_ptr->zowner = owner; + + else + png_zstream_error(png_ptr, ret); + + return ret; + } +} + +/* Clean up (or trim) a linked list of compression buffers. */ +void /* PRIVATE */ +png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) +{ + png_compression_bufferp list = *listp; + + if (list != NULL) + { + *listp = NULL; + + do + { + png_compression_bufferp next = list->next; + + png_free(png_ptr, list); + list = next; + } + while (list != NULL); + } +} + +#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 to allow access to the relevant local variables. + * + * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size + * temporary buffers. From 1.6.0 it is retained in png_struct so that it will + * be correctly freed in the event of a write error (previous implementations + * just leaked memory.) + */ +typedef struct +{ + png_const_bytep input; /* The uncompressed input data */ + png_alloc_size_t input_len; /* Its length */ + png_uint_32 output_len; /* Final compressed length */ + png_byte output[1024]; /* First block of output */ +} compression_state; + +static void +png_text_compress_init(compression_state *comp, png_const_bytep input, + png_alloc_size_t input_len) +{ + comp->input = input; + comp->input_len = input_len; + comp->output_len = 0; +} + +/* Compress the data in the compression state input */ +static int +png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, + compression_state *comp, png_uint_32 prefix_len) +{ + int ret; + + /* To find the length of the output it is necessary to first compress the + * input, the result is buffered rather than using the two-pass algorithm + * that is used on the inflate side; deflate is assumed to be slower and a + * PNG writer is assumed to have more memory available than a PNG reader. + * + * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an + * upper limit on the output size, but it is always bigger than the input + * size so it is likely to be more efficient to use this linked-list + * approach. + */ + ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len); + + if (ret != Z_OK) + return ret; + + /* Set up the compression buffers, we need a loop here to avoid overflowing a + * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited + * by the output buffer size, so there is no need to check that. Since this + * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits + * in size. + */ + { + png_compression_bufferp *end = &png_ptr->zbuffer_list; + png_alloc_size_t input_len = comp->input_len; /* may be zero! */ + png_uint_32 output_len; + + /* zlib updates these for us: */ + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input); + png_ptr->zstream.avail_in = 0; /* Set below */ + png_ptr->zstream.next_out = comp->output; + png_ptr->zstream.avail_out = (sizeof comp->output); + + output_len = png_ptr->zstream.avail_out; + + do + { + uInt avail_in = ZLIB_IO_MAX; + + if (avail_in > input_len) + avail_in = (uInt)input_len; + + input_len -= avail_in; + + png_ptr->zstream.avail_in = avail_in; + + if (png_ptr->zstream.avail_out == 0) + { + png_compression_buffer *next; + + /* Chunk data is limited to 2^31 bytes in length, so the prefix + * length must be counted here. + */ + if (output_len + prefix_len > PNG_UINT_31_MAX) + { + ret = Z_MEM_ERROR; + break; + } + + /* Need a new (malloc'ed) buffer, but there may be one present + * already. + */ + next = *end; + if (next == NULL) + { + next = png_voidcast(png_compression_bufferp, png_malloc_base + (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); + + if (next == NULL) + { + ret = Z_MEM_ERROR; + break; + } + + /* Link in this buffer (so that it will be freed later) */ + next->next = NULL; + *end = next; + } + + png_ptr->zstream.next_out = next->output; + png_ptr->zstream.avail_out = png_ptr->zbuffer_size; + output_len += png_ptr->zstream.avail_out; + + /* Move 'end' to the next buffer pointer. */ + end = &next->next; + } + + /* Compress the data */ + ret = deflate(&png_ptr->zstream, + input_len > 0 ? Z_NO_FLUSH : Z_FINISH); + + /* Claw back input data that was not consumed (because avail_in is + * reset above every time round the loop). + */ + input_len += png_ptr->zstream.avail_in; + png_ptr->zstream.avail_in = 0; /* safety */ + } + while (ret == Z_OK); + + /* There may be some space left in the last output buffer, this needs to + * be subtracted from output_len. + */ + output_len -= png_ptr->zstream.avail_out; + png_ptr->zstream.avail_out = 0; /* safety */ + comp->output_len = output_len; + + /* Now double check the output length, put in a custom message if it is + * too long. Otherwise ensure the z_stream::msg pointer is set to + * something. + */ + if (output_len + prefix_len >= PNG_UINT_31_MAX) + { + png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long"); + ret = Z_MEM_ERROR; + } + + else + png_zstream_error(png_ptr, ret); + + /* Reset zlib for another zTXt/iTXt or image data */ + png_ptr->zowner = 0; + + /* The only success case is Z_STREAM_END, input_len must be 0, if not this + * is an internal error. + */ + if (ret == Z_STREAM_END && input_len == 0) + { + /* Fix up the deflate header, if required */ + optimize_cmf(comp->output, comp->input_len); + + /* But Z_OK is returned, not Z_STREAM_END; this allows the claim + * function above to return Z_STREAM_END on an error (though it never + * does in the current versions of zlib.) + */ + return Z_OK; + } + + else + return ret; + } +} + +/* Ship the compressed text out via chunk writes */ +static void +png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) +{ + png_uint_32 output_len = comp->output_len; + png_const_bytep output = comp->output; + png_uint_32 avail = (sizeof comp->output); + png_compression_buffer *next = png_ptr->zbuffer_list; + + for (;;) + { + if (avail > output_len) + avail = output_len; + + png_write_chunk_data(png_ptr, output, avail); + + output_len -= avail; + + if (output_len == 0 || next == NULL) + break; + + avail = png_ptr->zbuffer_size; + output = next->output; + next = next->next; + } + + /* This is an internal error; 'next' must have been NULL! */ + if (output_len > 0) + png_error(png_ptr, "error writing ancillary chunked compressed data"); +} +#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ + +#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' buffer must be 80 characters in size (for the keyword plus a + * trailing '\0'). If this routine returns 0 then there was no keyword, or a + * valid one could not be generated, and the caller must png_error. + */ +static png_uint_32 +png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) +{ + png_const_charp orig_key = key; + png_uint_32 key_len = 0; + int bad_character = 0; + int space = 1; + + png_debug(1, "in png_check_keyword"); + + if (key == NULL) + { + *new_key = 0; + return 0; + } + + while (*key && key_len < 79) + { + png_byte ch = (png_byte)(0xff & *key++); + + if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) + *new_key++ = ch, ++key_len, space = 0; + + else if (space == 0) + { + /* A space or an invalid character when one wasn't seen immediately + * before; output just a space. + */ + *new_key++ = 32, ++key_len, space = 1; + + /* If the character was not a space then it is invalid. */ + if (ch != 32) + bad_character = ch; + } + + else if (bad_character == 0) + bad_character = ch; /* just skip it, record the first error */ + } + + if (key_len > 0 && space) /* trailing space */ + { + --key_len, --new_key; + if (bad_character == 0) + bad_character = 32; + } + + /* Terminate the keyword */ + *new_key = 0; + + if (key_len == 0) + return 0; + + /* Try to only output one warning per keyword: */ + if (*key) /* keyword too long */ + png_warning(png_ptr, "keyword truncated"); + + else if (bad_character != 0) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter(p, 1, orig_key); + png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); + + png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); + } + + return key_len; +} +#endif + +/* 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_structrp 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); + + if ((png_ptr->do_filter) == PNG_NO_FILTERS) + { + 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; + } + + 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_structrp 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; +} + +/* This is similar to png_text_compress, above, except that it does not require + * all of the data at once and, instead of buffering the compressed result, + * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out + * because it calls the write interface. As a result it does its own error + * reporting and does not return an error code. In the event of error it will + * just call png_error. The input data length may exceed 32-bits. The 'flush' + * parameter is exactly the same as that to deflate, with the following + * meanings: + * + * Z_NO_FLUSH: normal incremental output of compressed data + * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush + * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up + * + * The routine manages the acquire and release of the png_ptr->zstream by + * checking and (at the end) clearing png_ptr->zowner, it does some sanity + * checks on the 'mode' flags while doing this. + */ +void /* PRIVATE */ +png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, + png_alloc_size_t input_len, int flush) +{ + if (png_ptr->zowner != png_IDAT) + { + /* First time. Ensure we have a temporary buffer for compression and + * trim the buffer list if it has more than one entry to free memory. + * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been + * created at this point, but the check here is quick and safe. + */ + if (png_ptr->zbuffer_list == NULL) + { + png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, + png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); + png_ptr->zbuffer_list->next = NULL; + } + + else + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); + + /* It is a terminal error if we can't claim the zstream. */ + if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + /* The output state is maintained in png_ptr->zstream, so it must be + * initialized here after the claim. + */ + png_ptr->zstream.next_out = png_ptr->zbuffer_list->output; + png_ptr->zstream.avail_out = png_ptr->zbuffer_size; + } + + /* Now loop reading and writing until all the input is consumed or an error + * terminates the operation. The _out values are maintained across calls to + * this function, but the input must be reset each time. + */ + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); + png_ptr->zstream.avail_in = 0; /* set below */ + for (;;) + { + int ret; + + /* INPUT: from the row data */ + uInt avail = ZLIB_IO_MAX; + + if (avail > input_len) + avail = (uInt)input_len; /* safe because of the check */ + + png_ptr->zstream.avail_in = avail; + input_len -= avail; + + ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush); + + /* Include as-yet unconsumed input */ + input_len += png_ptr->zstream.avail_in; + png_ptr->zstream.avail_in = 0; + + /* OUTPUT: write complete IDAT chunks when avail_out drops to zero, note + * that these two zstream fields are preserved across the calls, therefore + * there is no need to set these up on entry to the loop. + */ + if (png_ptr->zstream.avail_out == 0) + { + png_bytep data = png_ptr->zbuffer_list->output; + uInt size = png_ptr->zbuffer_size; + + /* Write an IDAT containing the data then reset the buffer. The + * first IDAT may need deflate header optimization. + */ +# ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + if (!(png_ptr->mode & PNG_HAVE_IDAT) && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + optimize_cmf(data, png_image_size(png_ptr)); +# endif + + png_write_complete_chunk(png_ptr, png_IDAT, data, size); + png_ptr->mode |= PNG_HAVE_IDAT; + + png_ptr->zstream.next_out = data; + png_ptr->zstream.avail_out = size; + + /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with + * the same flush parameter until it has finished output, for NO_FLUSH + * it doesn't matter. + */ + if (ret == Z_OK && flush != Z_NO_FLUSH) + continue; + } + + /* The order of these checks doesn't matter much; it just effect which + * possible error might be detected if multiple things go wrong at once. + */ + if (ret == Z_OK) /* most likely return code! */ + { + /* If all the input has been consumed then just return. If Z_FINISH + * was used as the flush parameter something has gone wrong if we get + * here. + */ + if (input_len == 0) + { + if (flush == Z_FINISH) + png_error(png_ptr, "Z_OK on Z_FINISH with output space"); + + return; + } + } + + else if (ret == Z_STREAM_END && flush == Z_FINISH) + { + /* This is the end of the IDAT data; any pending output must be + * flushed. For small PNG files we may still be at the beginning. + */ + png_bytep data = png_ptr->zbuffer_list->output; + uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out; + +# ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + if (!(png_ptr->mode & PNG_HAVE_IDAT) && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + optimize_cmf(data, png_image_size(png_ptr)); +# endif + + png_write_complete_chunk(png_ptr, png_IDAT, data, size); + png_ptr->zstream.avail_out = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; + + png_ptr->zowner = 0; /* Release the stream */ + return; + } + + else + { + /* This is an error condition. */ + png_zstream_error(png_ptr, ret); + png_error(png_ptr, png_ptr->zstream.msg); + } + } +} + +/* Write an IEND chunk */ +void /* PRIVATE */ +png_write_IEND(png_structrp 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_structrp 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_structrp 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_structrp png_ptr, png_const_charp name, + png_const_bytep profile) +{ + png_uint_32 name_len; + png_uint_32 profile_len; + png_byte new_name[81]; /* 1 byte for the compression byte */ + compression_state comp; + + png_debug(1, "in png_write_iCCP"); + + /* These are all internal problems: the profile should have been checked + * before when it was stored. + */ + if (profile == NULL) + png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ + + profile_len = png_get_uint_32(profile); + + if (profile_len < 132) + png_error(png_ptr, "ICC profile too short"); + + if (profile_len & 0x03) + png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); + + { + png_uint_32 embedded_profile_len = png_get_uint_32(profile); + + if (profile_len != embedded_profile_len) + png_error(png_ptr, "Profile length does not match profile"); + } + + name_len = png_check_keyword(png_ptr, name, new_name); + + if (name_len == 0) + png_error(png_ptr, "iCCP: invalid keyword"); + + new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE; + + /* Make sure we include the NULL after the name and the compression type */ + ++name_len; + + png_text_compress_init(&comp, profile, profile_len); + + /* Allow for keyword terminator and compression byte */ + if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len); + + png_write_chunk_data(png_ptr, new_name, name_len); + + png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +/* Write a sPLT chunk */ +void /* PRIVATE */ +png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) +{ + png_uint_32 name_len; + png_byte new_name[80]; + 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"); + + name_len = png_check_keyword(png_ptr, spalette->name, new_name); + + if (name_len == 0) + png_error(png_ptr, "sPLT: invalid keyword"); + + /* 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, 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, entry_size); + } +#endif + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED +/* Write the sBIT chunk */ +void /* PRIVATE */ +png_write_sBIT(png_structrp 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_structrp png_ptr, const png_xy *xy) +{ + png_byte buf[32]; + + png_debug(1, "in png_write_cHRM"); + + /* Each value is saved in 1/100,000ths */ + png_save_int_32(buf, xy->whitex); + png_save_int_32(buf + 4, xy->whitey); + + png_save_int_32(buf + 8, xy->redx); + png_save_int_32(buf + 12, xy->redy); + + png_save_int_32(buf + 16, xy->greenx); + png_save_int_32(buf + 20, xy->greeny); + + png_save_int_32(buf + 24, xy->bluex); + png_save_int_32(buf + 28, xy->bluey); + + png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); +} +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +/* Write the tRNS chunk */ +void /* PRIVATE */ +png_write_tRNS(png_structrp 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 > png_ptr->num_palette) + { + /* This is an error which can only be reliably detected late. */ + png_app_error(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)) + { + /* This can no longer happen because it is checked in png_set_tRNS */ + png_app_error(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 + { + /* Also checked in png_set_tRNS */ + png_app_error(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 + { + /* Checked in png_set_tRNS */ + png_app_error(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_structrp 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_structrp 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 + +#ifdef PNG_WRITE_tEXt_SUPPORTED +/* Write a tEXt chunk */ +void /* PRIVATE */ +png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len) +{ + png_uint_32 key_len; + png_byte new_key[80]; + + png_debug(1, "in png_write_tEXt"); + + key_len = png_check_keyword(png_ptr, key, new_key); + + if (key_len == 0) + png_error(png_ptr, "tEXt: invalid keyword"); + + if (text == NULL || *text == '\0') + text_len = 0; + + else + text_len = strlen(text); + + if (text_len > PNG_UINT_31_MAX - (key_len+1)) + png_error(png_ptr, "tEXt: text too long"); + + /* Make sure we include the 0 after the key */ + png_write_chunk_header(png_ptr, png_tEXt, + (png_uint_32)/*checked above*/(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, new_key, key_len + 1); + + if (text_len != 0) + png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +/* Write a compressed text chunk */ +void /* PRIVATE */ +png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len, int compression) +{ + png_uint_32 key_len; + png_byte new_key[81]; + compression_state comp; + + png_debug(1, "in png_write_zTXt"); + PNG_UNUSED(text_len) /* Always use strlen */ + + if (compression == PNG_TEXT_COMPRESSION_NONE) + { + png_write_tEXt(png_ptr, key, text, 0); + return; + } + + if (compression != PNG_TEXT_COMPRESSION_zTXt) + png_error(png_ptr, "zTXt: invalid compression type"); + + key_len = png_check_keyword(png_ptr, key, new_key); + + if (key_len == 0) + png_error(png_ptr, "zTXt: invalid keyword"); + + /* Add the compression method and 1 for the keyword separator. */ + new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; + ++key_len; + + /* Compute the compressed data; do it now for the length */ + png_text_compress_init(&comp, (png_const_bytep)text, + text == NULL ? 0 : strlen(text)); + + if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + /* Write start of chunk */ + png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len); + + /* Write key */ + png_write_chunk_data(png_ptr, new_key, key_len); + + /* Write the compressed data */ + 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_structrp png_ptr, int compression, png_const_charp key, + png_const_charp lang, png_const_charp lang_key, png_const_charp text) +{ + png_uint_32 key_len, prefix_len; + png_size_t lang_len, lang_key_len; + png_byte new_key[82]; + compression_state comp; + + png_debug(1, "in png_write_iTXt"); + + key_len = png_check_keyword(png_ptr, key, new_key); + + if (key_len == 0) + png_error(png_ptr, "iTXt: invalid keyword"); + + /* Set the compression flag */ + switch (compression) + { + case PNG_ITXT_COMPRESSION_NONE: + case PNG_TEXT_COMPRESSION_NONE: + compression = new_key[++key_len] = 0; /* no compression */ + break; + + case PNG_TEXT_COMPRESSION_zTXt: + case PNG_ITXT_COMPRESSION_zTXt: + compression = new_key[++key_len] = 1; /* compressed */ + break; + + default: + png_error(png_ptr, "iTXt: invalid compression"); + } + + new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; + ++key_len; /* for the keywod separator */ + + /* 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, however, + * specifies that the text is UTF-8 and this really doesn't require any + * checking. + * + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + * + * TODO: validate the language tag correctly (see the spec.) + */ + if (lang == NULL) lang = ""; /* empty language is valid */ + lang_len = strlen(lang)+1; + if (lang_key == NULL) lang_key = ""; /* may be empty */ + lang_key_len = strlen(lang_key)+1; + if (text == NULL) text = ""; /* may be empty */ + + prefix_len = key_len; + if (lang_len > PNG_UINT_31_MAX-prefix_len) + prefix_len = PNG_UINT_31_MAX; + else + prefix_len = (png_uint_32)(prefix_len + lang_len); + + if (lang_key_len > PNG_UINT_31_MAX-prefix_len) + prefix_len = PNG_UINT_31_MAX; + else + prefix_len = (png_uint_32)(prefix_len + lang_key_len); + + png_text_compress_init(&comp, (png_const_bytep)text, strlen(text)); + + if (compression != 0) + { + if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + } + + else + { + if (comp.input_len > PNG_UINT_31_MAX-prefix_len) + png_error(png_ptr, "iTXt: uncompressed text too long"); + + /* So the string will fit in a chunk: */ + comp.output_len = (png_uint_32)/*SAFE*/comp.input_len; + } + + png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len); + + png_write_chunk_data(png_ptr, new_key, key_len); + + png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len); + + png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len); + + if (compression != 0) + png_write_compressed_data_out(png_ptr, &comp); + + else + png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len); + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED +/* Write the oFFs chunk */ +void /* PRIVATE */ +png_write_oFFs(png_structrp 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_structrp 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_uint_32 purpose_len; + png_size_t units_len, total_len; + png_size_tp params_len; + png_byte buf[10]; + png_byte new_purpose[80]; + int i; + + png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); + + if (type >= PNG_EQUATION_LAST) + png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); + + purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); + + if (purpose_len == 0) + png_error(png_ptr, "pCAL: invalid keyword"); + + ++purpose_len; /* terminator */ + + png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); + units_len = 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 * (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] = 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, 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); + + 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_structrp 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 = strlen(width); + hlen = 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; + memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ + 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_structrp 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_structrp 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 + +#ifdef PNG_WRITE_FILTER_SUPPORTED +void /* PRIVATE */ +png_write_alloc_filter_row_buffers(png_structrp png_ptr, int filters) + /* Allocate row buffers for any filters that need them, this is also called + * from png_set_filter if the filters are changed during write to ensure that + * the required buffers exist. png_set_filter ensures that up/avg/paeth are + * only set if png_ptr->prev_row is allocated. + */ +{ + /* The buffer size is determined just by the output row size, not any + * processing requirements. + */ + png_alloc_size_t buf_size = png_ptr->rowbytes + 1; + + if ((filters & PNG_FILTER_SUB) != 0 && png_ptr->sub_row == NULL) + { + png_ptr->sub_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + + if ((filters & PNG_FILTER_UP) != 0 && png_ptr->up_row == NULL) + { + png_ptr->up_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + + if ((filters & PNG_FILTER_AVG) != 0 && png_ptr->avg_row == NULL) + { + png_ptr->avg_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + + if ((filters & PNG_FILTER_PAETH) != 0 && png_ptr->paeth_row == NULL) + { + png_ptr->paeth_row = png_voidcast(png_bytep, png_malloc(png_ptr, + buf_size)); + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } +} +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + +/* Initializes the row writing capability of libpng */ +void /* PRIVATE */ +png_write_start_row(png_structrp 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 + +#ifdef PNG_WRITE_FILTER_SUPPORTED + int filters; +#endif + + png_alloc_size_t buf_size; + int usr_pixel_depth; + + png_debug(1, "in png_write_start_row"); + + if (png_ptr == NULL) + return; + + 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_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + + png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; + +#ifdef PNG_WRITE_FILTER_SUPPORTED + filters = png_ptr->do_filter; + + if (png_ptr->height == 1) + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (png_ptr->width == 1) + filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (filters == 0) + filters = PNG_FILTER_NONE; + + /* We only need to keep the previous row if we are using one of the following + * filters. + */ + if (filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) + png_ptr->prev_row = png_voidcast(png_bytep, png_calloc(png_ptr, + buf_size)); + + png_write_alloc_filter_row_buffers(png_ptr, filters); + + png_ptr->do_filter = (png_byte)filters; /* in case it was changed above */ +#else + png_ptr->do_filter = PNG_FILTER_NONE; +#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; + } +} + +/* Internal use only. Called when finished processing a row of data. */ +void /* PRIVATE */ +png_write_finish_row(png_structrp 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_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) + 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 */ + png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH); +} + +#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) + 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_structrp 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_structrp 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_structrp png_ptr, png_bytep filtered_row, + png_size_t full_row_length/*includes filter byte*/) +{ + png_debug(1, "in png_write_filtered_row"); + + png_debug1(2, "filter = %d", filtered_row[0]); + + png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); + +#ifdef PNG_WRITE_FILTER_SUPPORTED + /* 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; + } +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + + /* 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/ext/native/ext/libzip/Android.mk b/ext/native/ext/libzip/Android.mk new file mode 100644 index 0000000000..e05b292f44 --- /dev/null +++ b/ext/native/ext/libzip/Android.mk @@ -0,0 +1,77 @@ +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libzip +LOCAL_SRC_FILES :=\ + zip_add.c \ + zip_add_dir.c \ + zip_close.c \ + zip_delete.c \ + zip_dirent.c \ + zip_entry_free.c \ + zip_entry_new.c \ + zip_err_str.c \ + zip_error.c \ + zip_error_clear.c \ + zip_error_get.c \ + zip_error_get_sys_type.c \ + zip_error_strerror.c \ + zip_error_to_str.c \ + zip_fclose.c \ + zip_file_error_clear.c \ + zip_file_error_get.c \ + zip_file_get_offset.c \ + zip_file_strerror.c \ + zip_filerange_crc.c \ + zip_fopen.c \ + zip_fopen_index.c \ + zip_fread.c \ + zip_free.c \ + zip_get_archive_comment.c \ + zip_get_archive_flag.c \ + zip_get_file_comment.c \ + zip_get_num_files.c \ + zip_get_name.c \ + zip_memdup.c \ + zip_name_locate.c \ + zip_new.c \ + zip_open.c \ + zip_rename.c \ + zip_replace.c \ + zip_set_archive_comment.c \ + zip_set_archive_flag.c \ + zip_set_file_comment.c \ + zip_source_buffer.c \ + zip_source_file.c \ + zip_source_filep.c \ + zip_source_free.c \ + zip_source_function.c \ + zip_source_zip.c \ + zip_set_name.c \ + zip_stat.c \ + zip_stat_index.c \ + zip_stat_init.c \ + zip_strerror.c \ + zip_unchange.c \ + zip_unchange_all.c \ + zip_unchange_archive.c \ + zip_unchange_data.c + +LOCAL_CFLAGS := -O2 + +include $(BUILD_STATIC_LIBRARY) diff --git a/ext/native/ext/libzip/CMakeLists.txt b/ext/native/ext/libzip/CMakeLists.txt new file mode 100644 index 0000000000..c819364fb4 --- /dev/null +++ b/ext/native/ext/libzip/CMakeLists.txt @@ -0,0 +1,64 @@ +set(SRCS +mkstemp.c +zip_add.c +zip_add_dir.c +zip_close.c +zip_delete.c +zip_dirent.c +zip_entry_free.c +zip_entry_new.c +zip_err_str.c +zip_error.c +zip_error_clear.c +zip_error_get.c +zip_error_get_sys_type.c +zip_error_strerror.c +zip_error_to_str.c +zip_fclose.c +zip_file_error_clear.c +zip_file_error_get.c +zip_file_get_offset.c +zip_file_strerror.c +zip_filerange_crc.c +zip_fopen.c +zip_fopen_index.c +zip_fread.c +zip_free.c +zip_get_archive_comment.c +zip_get_archive_flag.c +zip_get_file_comment.c +zip_get_name.c +zip_get_num_files.c +zip_memdup.c +zip_name_locate.c +zip_new.c +zip_open.c +zip_rename.c +zip_replace.c +zip_set_archive_comment.c +zip_set_archive_flag.c +zip_set_file_comment.c +zip_set_name.c +zip_source_buffer.c +zip_source_file.c +zip_source_filep.c +zip_source_free.c +zip_source_function.c +zip_source_zip.c +zip_stat.c +zip_stat_index.c +zip_stat_init.c +zip_strerror.c +zip_unchange.c +zip_unchange_all.c +zip_unchange_archive.c +zip_unchange_data.c) + +set(SRCS ${SRCS}) + +add_library(zip STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) + diff --git a/ext/native/ext/libzip/config.h b/ext/native/ext/libzip/config.h new file mode 100644 index 0000000000..456884aff4 --- /dev/null +++ b/ext/native/ext/libzip/config.h @@ -0,0 +1,103 @@ +/* Config header for Android */ +/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. + */ +/* #undef HAVE_DECL_TZNAME */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 0 + +/* Define to 1 if you have the `fseeko' function. */ +#define HAVE_FSEEKO 0 + +/* Define to 1 if you have the `ftello' function. */ +#define HAVE_FTELLO 0 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 0 + +/* Define to 1 if you have the `z' library (-lz). */ +#define HAVE_LIBZ 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 0 + +/* Define to 1 if you have the `mkstemp' function. */ +#ifndef _WIN32 +#define HAVE_MKSTEMP 1 +#endif + +/* Define to 1 if you have the `MoveFileExA' function. */ +#ifdef _WIN32 +#define HAVE_MOVEFILEEXA 1 +#endif + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#ifndef _WIN32 +#define HAVE_STRINGS_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +// #define HAVE_STRUCT_TM_TM_ZONE 0 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use + `HAVE_STRUCT_TM_TM_ZONE' instead. */ +#define HAVE_TM_ZONE 1 + +/* Define to 1 if you don't have `tm_zone' but do have the external array + `tzname'. */ +/* #undef HAVE_TZNAME */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "libzip" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "libzip@nih.at" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libzip" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libzip 0.9.3" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libzip" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.9.3" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Version number of package */ +#define VERSION "0.9.3" diff --git a/ext/native/ext/libzip/libzip.la b/ext/native/ext/libzip/libzip.la new file mode 100644 index 0000000000..49b0cd7779 --- /dev/null +++ b/ext/native/ext/libzip/libzip.la @@ -0,0 +1,41 @@ +# libzip.la - a libtool library file +# Generated by ltmain.sh (GNU libtool) 2.2.6b +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libzip.so.1' + +# Names of this library. +library_names='libzip.so.1.0.0 libzip.so.1 libzip.so' + +# The name of the static archive. +old_library='libzip.a' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='' + +# Libraries that this one depends upon. +dependency_libs=' -lz' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libzip. +current=1 +age=0 +revision=0 + +# Is this an already installed library? +installed=no + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/local/lib' diff --git a/ext/native/ext/libzip/mkstemp.c b/ext/native/ext/libzip/mkstemp.c new file mode 100644 index 0000000000..0dbaaf0572 --- /dev/null +++ b/ext/native/ext/libzip/mkstemp.c @@ -0,0 +1,177 @@ +/* $NiH: mkstemp.c,v 1.3 2006/04/23 14:51:45 wiz Exp $ */ + +/* Adapted from NetBSB libc by Dieter Baron */ + +/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" +#ifndef HAVE_MKSTEMP +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +typedef int pid_t; +#define getpid rand +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +int +#ifdef UNICODE +_zip_mkstemp(wchar_t *path) +#else +_zip_mkstemp(char *path) +#endif +{ +#ifndef _WIN32 + int fd; +#endif +#ifdef UNICODE + wchar_t *start, *trv; + struct _stat sbuf; +#else + char *start, *trv; + struct stat sbuf; +#endif + + pid_t pid; + + /* To guarantee multiple calls generate unique names even if + the file is not created. 676 different possibilities with 7 + or more X's, 26 with 6 or less. */ + // Urgh, not threadsafe at all. +#ifdef UNICODE + static wchar_t xtra[3] = L"aa"; +#else + static char xtra[3] = "aa"; +#endif + int xcnt = 0; + + pid = getpid(); + + /* Move to end of path and count trailing X's. */ + for (trv = path; *trv; ++trv) + if (*trv == 'X') + xcnt++; + else + xcnt = 0; + + /* Use at least one from xtra. Use 2 if more than 6 X's. */ + if (*(trv - 1) == 'X') + *--trv = xtra[0]; + if (xcnt > 6 && *(trv - 1) == 'X') + *--trv = xtra[1]; + + /* Set remaining X's to pid digits with 0's to the left. */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* update xtra for next call. */ + if (xtra[0] != 'z') + xtra[0]++; + else { + xtra[0] = 'a'; + if (xtra[1] != 'z') + xtra[1]++; + else + xtra[1] = 'a'; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; +#ifdef UNICODE + if (_wstat(path, &sbuf)) +#else + if (stat(path, &sbuf)) +#endif + return (0); +#ifndef _WIN32 + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return (0); + } +#endif + *trv = '/'; + break; + } + } + + +#ifdef _WIN32 + return 0; +#else + + for (;;) { + if ((fd=open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0) + return (fd); + if (errno != EEXIST) + return (0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit((unsigned char)*trv)) + *trv = 'a'; + else + ++*trv; + break; + } + } + } +#endif + + /*NOTREACHED*/ +} +#endif + diff --git a/ext/native/ext/libzip/zip.h b/ext/native/ext/libzip/zip.h new file mode 100644 index 0000000000..78b8519918 --- /dev/null +++ b/ext/native/ext/libzip/zip.h @@ -0,0 +1,250 @@ +#ifndef _HAD_ZIP_H +#define _HAD_ZIP_H + +/* + zip.h -- exported declarations. + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#ifdef _MSC_VER +#ifndef ZIP_EXTERN +#define ZIP_EXTERN +// __declspec(dllexport) +#endif +#ifdef _M_X64 +typedef __int64 ssize_t; +#else +typedef __int32 ssize_t; +#endif +#else +#define ZIP_EXTERN +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#ifdef __SYMBIAN32__ +#define _stat stat +#define _wcsdup wcsdup +#define _wfopen wfopen +#define _wremove wremove +#define _wstat wstat +#endif + + +/* flags for zip_open */ + +#define ZIP_CREATE 1 +#define ZIP_EXCL 2 +#define ZIP_CHECKCONS 4 + + +/* flags for zip_name_locate, zip_fopen, zip_stat, ... */ + +#define ZIP_FL_NOCASE 1 /* ignore case on name lookup */ +#define ZIP_FL_NODIR 2 /* ignore directory component */ +#define ZIP_FL_COMPRESSED 4 /* read compressed data */ +#define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */ +#define ZIP_FL_RECOMPRESS 16 /* force recompression of data */ + +/* archive global flags flags */ + +#define ZIP_AFL_TORRENT 1 /* torrent zipped */ + +/* libzip error codes */ + +#define ZIP_ER_OK 0 /* N No error */ +#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */ +#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */ +#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */ +#define ZIP_ER_SEEK 4 /* S Seek error */ +#define ZIP_ER_READ 5 /* S Read error */ +#define ZIP_ER_WRITE 6 /* S Write error */ +#define ZIP_ER_CRC 7 /* N CRC error */ +#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */ +#define ZIP_ER_NOENT 9 /* N No such file */ +#define ZIP_ER_EXISTS 10 /* N File already exists */ +#define ZIP_ER_OPEN 11 /* S Can't open file */ +#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */ +#define ZIP_ER_ZLIB 13 /* Z Zlib error */ +#define ZIP_ER_MEMORY 14 /* N Malloc failure */ +#define ZIP_ER_CHANGED 15 /* N Entry has been changed */ +#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */ +#define ZIP_ER_EOF 17 /* N Premature EOF */ +#define ZIP_ER_INVAL 18 /* N Invalid argument */ +#define ZIP_ER_NOZIP 19 /* N Not a zip archive */ +#define ZIP_ER_INTERNAL 20 /* N Internal error */ +#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ +#define ZIP_ER_REMOVE 22 /* S Can't remove file */ +#define ZIP_ER_DELETED 23 /* N Entry has been deleted */ + + +/* type of system error value */ + +#define ZIP_ET_NONE 0 /* sys_err unused */ +#define ZIP_ET_SYS 1 /* sys_err is errno */ +#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */ + +/* compression methods */ + +#define ZIP_CM_DEFAULT -1 /* better of deflate or store */ +#define ZIP_CM_STORE 0 /* stored (uncompressed) */ +#define ZIP_CM_SHRINK 1 /* shrunk */ +#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */ +#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */ +#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */ +#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */ +#define ZIP_CM_IMPLODE 6 /* imploded */ +/* 7 - Reserved for Tokenizing compression algorithm */ +#define ZIP_CM_DEFLATE 8 /* deflated */ +#define ZIP_CM_DEFLATE64 9 /* deflate64 */ +#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */ +/* 11 - Reserved by PKWARE */ +#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */ +/* 13 - Reserved by PKWARE */ +#define ZIP_CM_LZMA 14 /* LZMA (EFS) */ +/* 15-17 - Reserved by PKWARE */ +#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ +#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ +#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ +#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */ + +/* encryption methods */ + +#define ZIP_EM_NONE 0 /* not encrypted */ +#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */ +#if 0 /* Strong Encryption Header not parsed yet */ +#define ZIP_EM_DES 0x6601 /* strong encryption: DES */ +#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */ +#define ZIP_EM_3DES_168 0x6603 +#define ZIP_EM_3DES_112 0x6609 +#define ZIP_EM_AES_128 0x660e +#define ZIP_EM_AES_192 0x660f +#define ZIP_EM_AES_256 0x6610 +#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */ +#define ZIP_EM_RC4 0x6801 +#endif +#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */ + + + +enum zip_source_cmd { + ZIP_SOURCE_OPEN, /* prepare for reading */ + ZIP_SOURCE_READ, /* read data */ + ZIP_SOURCE_CLOSE, /* reading is done */ + ZIP_SOURCE_STAT, /* get meta information */ + ZIP_SOURCE_ERROR, /* get error information */ + ZIP_SOURCE_FREE /* cleanup and free resources */ +}; + +typedef ssize_t (*zip_source_callback)(void *state, void *data, + size_t len, enum zip_source_cmd cmd); + +struct zip_stat { + const char *name; /* name of the file */ + int index; /* index within archive */ + unsigned int crc; /* crc of file data */ + time_t mtime; /* modification time */ + off_t size; /* size of file (uncompressed) */ + off_t comp_size; /* size of file (compressed) */ + unsigned short comp_method; /* compression method used */ + unsigned short encryption_method; /* encryption method used */ +}; + +struct zip; +struct zip_file; +struct zip_source; + + + +ZIP_EXTERN int zip_add(struct zip *, const char *, struct zip_source *); +ZIP_EXTERN int zip_add_dir(struct zip *, const char *); +ZIP_EXTERN int zip_close(struct zip *); +ZIP_EXTERN int zip_delete(struct zip *, int); +ZIP_EXTERN void zip_error_clear(struct zip *); +ZIP_EXTERN void zip_error_get(struct zip *, int *, int *); +ZIP_EXTERN int zip_error_get_sys_type(int); +ZIP_EXTERN int zip_error_to_str(char *, size_t, int, int); +ZIP_EXTERN int zip_fclose(struct zip_file *); +ZIP_EXTERN void zip_file_error_clear(struct zip_file *); +ZIP_EXTERN void zip_file_error_get(struct zip_file *, int *, int *); +ZIP_EXTERN const char *zip_file_strerror(struct zip_file *); +ZIP_EXTERN struct zip_file *zip_fopen(struct zip *, const char *, int); +ZIP_EXTERN struct zip_file *zip_fopen_index(struct zip *, int, int); +ZIP_EXTERN ssize_t zip_fread(struct zip_file *, void *, size_t); +ZIP_EXTERN const char *zip_get_archive_comment(struct zip *, int *, int); +ZIP_EXTERN int zip_get_archive_flag(struct zip *, int, int); +ZIP_EXTERN const char *zip_get_file_comment(struct zip *, int, int *, int); +ZIP_EXTERN const char *zip_get_name(struct zip *, int, int); +ZIP_EXTERN int zip_get_num_files(struct zip *); +ZIP_EXTERN int zip_name_locate(struct zip *, const char *, int); +#ifdef UNICODE +ZIP_EXTERN struct zip *zip_open(const wchar_t *, int, int *); +#else +ZIP_EXTERN struct zip *zip_open(const char *, int, int *); +#endif +ZIP_EXTERN int zip_rename(struct zip *, int, const char *); +ZIP_EXTERN int zip_replace(struct zip *, int, struct zip_source *); +ZIP_EXTERN int zip_set_archive_comment(struct zip *, const char *, int); +ZIP_EXTERN int zip_set_archive_flag(struct zip *, int, int); +ZIP_EXTERN int zip_set_file_comment(struct zip *, int, const char *, int); +ZIP_EXTERN struct zip_source *zip_source_buffer(struct zip *, const void *, + off_t, int); +ZIP_EXTERN struct zip_source *zip_source_file(struct zip *, const char *, + off_t, off_t); +ZIP_EXTERN struct zip_source *zip_source_filep(struct zip *, FILE *, + off_t, off_t); +ZIP_EXTERN void zip_source_free(struct zip_source *); +ZIP_EXTERN struct zip_source *zip_source_function(struct zip *, + zip_source_callback, void *); +ZIP_EXTERN struct zip_source *zip_source_zip(struct zip *, struct zip *, + int, int, off_t, off_t); +ZIP_EXTERN int zip_stat(struct zip *, const char *, int, struct zip_stat *); +ZIP_EXTERN int zip_stat_index(struct zip *, int, int, struct zip_stat *); +ZIP_EXTERN void zip_stat_init(struct zip_stat *); +ZIP_EXTERN const char *zip_strerror(struct zip *); +ZIP_EXTERN int zip_unchange(struct zip *, int); +ZIP_EXTERN int zip_unchange_all(struct zip *); +ZIP_EXTERN int zip_unchange_archive(struct zip *); + +#ifdef __cplusplus +} +#endif + +#endif /* _HAD_ZIP_H */ diff --git a/ext/native/ext/libzip/zip_add.c b/ext/native/ext/libzip/zip_add.c new file mode 100644 index 0000000000..f6bdb2ab92 --- /dev/null +++ b/ext/native/ext/libzip/zip_add.c @@ -0,0 +1,49 @@ +/* + zip_add.c -- add file via callback function + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_add(struct zip *za, const char *name, struct zip_source *source) +{ + if (name == NULL || source == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + return _zip_replace(za, -1, name, source); +} diff --git a/ext/native/ext/libzip/zip_add_dir.c b/ext/native/ext/libzip/zip_add_dir.c new file mode 100644 index 0000000000..a058640c1e --- /dev/null +++ b/ext/native/ext/libzip/zip_add_dir.c @@ -0,0 +1,83 @@ +/* + zip_add_dir.c -- add directory + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_add_dir(struct zip *za, const char *name) +{ + int len, ret; + char *s; + struct zip_source *source; + + if (name == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + s = NULL; + len = (int)strlen(name); + + if (name[len-1] != '/') { + if ((s=(char *)malloc(len+2)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + strcpy(s, name); + s[len] = '/'; + s[len+1] = '\0'; + } + + if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { + free(s); + return -1; + } + + ret = _zip_replace(za, -1, s ? s : name, source); + + free(s); + if (ret < 0) + zip_source_free(source); + + return ret; +} diff --git a/ext/native/ext/libzip/zip_close.c b/ext/native/ext/libzip/zip_close.c new file mode 100644 index 0000000000..902303a3f9 --- /dev/null +++ b/ext/native/ext/libzip/zip_close.c @@ -0,0 +1,736 @@ +/* + zip_close.c -- close zip archive and update changes + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include +#include +#include +#include +#include + +#include "zipint.h" + +#ifdef HAVE_STRINGS_H +#include +#endif + +static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, + FILE *); +static int add_data_comp(zip_source_callback, void *, struct zip_stat *, + FILE *, struct zip_error *); +static int add_data_uncomp(struct zip *, zip_source_callback, void *, + struct zip_stat *, FILE *); +static void ch_set_error(struct zip_error *, zip_source_callback, void *); +static int copy_data(FILE *, off_t, FILE *, struct zip_error *); +static int write_cdir(struct zip *, struct zip_cdir *, FILE *); +static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *); +static int _zip_changed(struct zip *, int *); +#ifdef UNICODE +static wchar_t * +#else +static char * +#endif + _zip_create_temp_output(struct zip *, FILE **); +static int _zip_torrentzip_cmp(const void *, const void *); + + + +struct filelist { + int idx; + const char *name; +}; + + + +ZIP_EXTERN int +zip_close(struct zip *za) +{ + int survivors; + int i, j, error; +#ifdef UNICODE + wchar_t *temp; +#else + char *temp; +#endif + FILE *out; + mode_t mask; + struct zip_cdir *cd; + struct zip_dirent de; + struct filelist *filelist; + int reopen_on_error; + int new_torrentzip; + + reopen_on_error = 0; + + if (za == NULL) + return -1; + + if (!_zip_changed(za, &survivors)) { + _zip_free(za); + return 0; + } + + /* don't create zip files with no entries */ + if (survivors == 0) { + if (za->zn && za->zp) { +#ifdef UNICODE + if (_wremove(za->zn) != 0) { +#else + if (remove(za->zn) != 0) { +#endif + _zip_error_set(&za->error, ZIP_ER_REMOVE, errno); + return -1; + } + } + _zip_free(za); + return 0; + } + + if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors)) + == NULL) + return -1; + + if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) { + free(filelist); + return -1; + } + + for (i=0; ientry[i]); + + /* archive comment is special for torrentzip */ + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) { + cd->comment = (char *)_zip_memdup(TORRENT_SIG "XXXXXXXX", + TORRENT_SIG_LEN + TORRENT_CRC_LEN, + &za->error); + if (cd->comment == NULL) { + _zip_cdir_free(cd); + free(filelist); + return -1; + } + cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN; + } + else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) { + if (_zip_cdir_set_comment(cd, za) == -1) { + _zip_cdir_free(cd); + free(filelist); + return -1; + } + } + + if ((temp = _zip_create_temp_output(za, &out)) == NULL) { + _zip_cdir_free(cd); + free(filelist); + return -1; + } + + + /* create list of files with index into original archive */ + for (i=j=0; inentry; i++) { + if (za->entry[i].state == ZIP_ST_DELETED) + continue; + + filelist[j].idx = i; + filelist[j].name = zip_get_name(za, i, 0); + j++; + } + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) + qsort(filelist, survivors, sizeof(filelist[0]), + _zip_torrentzip_cmp); + + new_torrentzip = (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 1 + && zip_get_archive_flag(za, ZIP_AFL_TORRENT, + ZIP_FL_UNCHANGED) == 0); + error = 0; + for (j=0; jentry+i) || new_torrentzip) { + _zip_dirent_init(&de); + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) + _zip_dirent_torrent_normalize(&de); + + /* use it as central directory entry */ + memcpy(cd->entry+j, &de, sizeof(cd->entry[j])); + + /* set/update file name */ + if (za->entry[i].ch_filename == NULL) { + if (za->entry[i].state == ZIP_ST_ADDED) { + de.filename = strdup("-"); + de.filename_len = 1; + cd->entry[j].filename = "-"; + cd->entry[j].filename_len = 1; + } + else { + de.filename = strdup(za->cdir->entry[i].filename); + de.filename_len = (unsigned short)strlen(de.filename); + cd->entry[j].filename = za->cdir->entry[i].filename; + cd->entry[j].filename_len = de.filename_len; + } + } + } + else { + /* copy existing directory entries */ + if (fseeko(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + error = 1; + break; + } + if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, + &za->error) != 0) { + error = 1; + break; + } + memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j])); + if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { + de.crc = za->cdir->entry[i].crc; + de.comp_size = za->cdir->entry[i].comp_size; + de.uncomp_size = za->cdir->entry[i].uncomp_size; + de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; + cd->entry[j].bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; + } + } + + if (za->entry[i].ch_filename) { + free(de.filename); + if ((de.filename=strdup(za->entry[i].ch_filename)) == NULL) { + error = 1; + break; + } + de.filename_len = (unsigned short)strlen(de.filename); + cd->entry[j].filename = za->entry[i].ch_filename; + cd->entry[j].filename_len = de.filename_len; + } + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0 + && za->entry[i].ch_comment_len != -1) { + /* as the rest of cd entries, its malloc/free is done by za */ + cd->entry[j].comment = za->entry[i].ch_comment; + cd->entry[j].comment_len = za->entry[i].ch_comment_len; + } + + cd->entry[j].offset = ftello(out); + + if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { + struct zip_source *zs; + + zs = NULL; + if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { + if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) + == NULL) { + error = 1; + break; + } + } + + if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) { + error = 1; + break; + } + cd->entry[j].last_mod = de.last_mod; + cd->entry[j].comp_method = de.comp_method; + cd->entry[j].comp_size = de.comp_size; + cd->entry[j].uncomp_size = de.uncomp_size; + cd->entry[j].crc = de.crc; + } + else { + if (_zip_dirent_write(&de, out, 1, &za->error) < 0) { + error = 1; + break; + } + /* we just read the local dirent, file is at correct position */ + if (copy_data(za->zp, cd->entry[j].comp_size, out, + &za->error) < 0) { + error = 1; + break; + } + } + + _zip_dirent_finalize(&de); + } + + free(filelist); + + if (!error) { + if (write_cdir(za, cd, out) < 0) + error = 1; + } + + /* pointers in cd entries are owned by za */ + cd->nentry = 0; + _zip_cdir_free(cd); + + if (error) { + _zip_dirent_finalize(&de); + fclose(out); +#ifdef UNICODE + _wremove(temp); +#else + remove(temp); +#endif + free(temp); + return -1; + } + + if (fclose(out) != 0) { + _zip_error_set(&za->error, ZIP_ER_CLOSE, errno); +#ifdef UNICODE + _wremove(temp); +#else + remove(temp); +#endif + free(temp); + return -1; + } + + if (za->zp) { + fclose(za->zp); + za->zp = NULL; + reopen_on_error = 1; + } + if (_zip_rename(temp, za->zn) != 0) { + _zip_error_set(&za->error, ZIP_ER_RENAME, errno); +#ifdef UNICODE + _wremove(temp); +#else + remove(temp); +#endif + free(temp); + if (reopen_on_error) { + /* ignore errors, since we're already in an error case */ +#ifdef UNICODE + za->zp = _wfopen(za->zn, L"rb"); +#else + za->zp = fopen(za->zn, "rb"); +#endif + } + return -1; + } + mask = umask(0); + umask(mask); + chmod(za->zn, 0666&~mask); + + _zip_free(za); + free(temp); + + return 0; +} + + + +static int +add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft) +{ + off_t offstart, offend; + zip_source_callback cb; + void *ud; + struct zip_stat st; + + cb = zs->f; + ud = zs->ud; + + if (cb(ud, &st, sizeof(st), ZIP_SOURCE_STAT) < (ssize_t)sizeof(st)) { + ch_set_error(&za->error, cb, ud); + return -1; + } + + if (cb(ud, NULL, 0, ZIP_SOURCE_OPEN) < 0) { + ch_set_error(&za->error, cb, ud); + return -1; + } + + offstart = ftello(ft); + + if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + return -1; + + if (st.comp_method != ZIP_CM_STORE) { + if (add_data_comp(cb, ud, &st, ft, &za->error) < 0) + return -1; + } + else { + if (add_data_uncomp(za, cb, ud, &st, ft) < 0) + return -1; + } + + if (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) { + ch_set_error(&za->error, cb, ud); + return -1; + } + + offend = ftello(ft); + + if (fseeko(ft, offstart, SEEK_SET) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + + de->last_mod = st.mtime; + de->comp_method = st.comp_method; + de->crc = st.crc; + de->uncomp_size = st.size; + de->comp_size = st.comp_size; + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) + _zip_dirent_torrent_normalize(de); + + if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + return -1; + + if (fseeko(ft, offend, SEEK_SET) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + return 0; +} + + + +static int +add_data_comp(zip_source_callback cb, void *ud, struct zip_stat *st,FILE *ft, + struct zip_error *error) +{ + char buf[BUFSIZE]; + ssize_t n; + + st->comp_size = 0; + while ((n=cb(ud, buf, sizeof(buf), ZIP_SOURCE_READ)) > 0) { + if (fwrite(buf, 1, n, ft) != (size_t)n) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + st->comp_size += n; + } + if (n < 0) { + ch_set_error(error, cb, ud); + return -1; + } + + return 0; +} + + + +static int +add_data_uncomp(struct zip *za, zip_source_callback cb, void *ud, + struct zip_stat *st, FILE *ft) +{ + char b1[BUFSIZE], b2[BUFSIZE]; + int end, flush, ret; + ssize_t n; + size_t n2; + z_stream zstr; + int mem_level; + + st->comp_method = ZIP_CM_DEFLATE; + st->comp_size = st->size = 0; + st->crc = crc32(0, NULL, 0); + + zstr.zalloc = Z_NULL; + zstr.zfree = Z_NULL; + zstr.opaque = NULL; + zstr.avail_in = 0; + zstr.avail_out = 0; + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) + mem_level = TORRENT_MEM_LEVEL; + else + mem_level = MAX_MEM_LEVEL; + + /* -MAX_WBITS: undocumented feature of zlib to _not_ write a zlib header */ + deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, mem_level, + Z_DEFAULT_STRATEGY); + + zstr.next_out = (Bytef *)b2; + zstr.avail_out = sizeof(b2); + zstr.next_in = NULL; + zstr.avail_in = 0; + + flush = 0; + end = 0; + while (!end) { + if (zstr.avail_in == 0 && !flush) { + if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) { + ch_set_error(&za->error, cb, ud); + deflateEnd(&zstr); + return -1; + } + if (n > 0) { + zstr.avail_in = n; + zstr.next_in = (Bytef *)b1; + st->size += n; + st->crc = crc32(st->crc, (Bytef *)b1, n); + } + else + flush = Z_FINISH; + } + + ret = deflate(&zstr, flush); + if (ret != Z_OK && ret != Z_STREAM_END) { + _zip_error_set(&za->error, ZIP_ER_ZLIB, ret); + return -1; + } + + if (zstr.avail_out != sizeof(b2)) { + n2 = sizeof(b2) - zstr.avail_out; + + if (fwrite(b2, 1, n2, ft) != n2) { + _zip_error_set(&za->error, ZIP_ER_WRITE, errno); + return -1; + } + + zstr.next_out = (Bytef *)b2; + zstr.avail_out = sizeof(b2); + st->comp_size += (off_t)n2; + } + + if (ret == Z_STREAM_END) { + deflateEnd(&zstr); + end = 1; + } + } + + return 0; +} + + + +static void +ch_set_error(struct zip_error *error, zip_source_callback cb, void *ud) +{ + int e[2]; + + if ((cb(ud, e, sizeof(e), ZIP_SOURCE_ERROR)) < (ssize_t)sizeof(e)) { + error->zip_err = ZIP_ER_INTERNAL; + error->sys_err = 0; + } + else { + error->zip_err = e[0]; + error->sys_err = e[1]; + } +} + + + +static int +copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error) +{ + char buf[BUFSIZE]; + ssize_t n, nn; + + if (len == 0) + return 0; + + while (len > 0) { + nn = len > sizeof(buf) ? sizeof(buf) : len; + if ((n=fread(buf, 1, nn, fs)) < 0) { + _zip_error_set(error, ZIP_ER_READ, errno); + return -1; + } + else if (n == 0) { + _zip_error_set(error, ZIP_ER_EOF, 0); + return -1; + } + + if (fwrite(buf, 1, n, ft) != n) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + len -= (off_t)n; + } + + return 0; +} + + + +static int +write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out) +{ + off_t offset; + uLong crc; + char buf[TORRENT_CRC_LEN+1]; + + if (_zip_cdir_write(cd, out, &za->error) < 0) + return -1; + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0) + return 0; + + + /* fix up torrentzip comment */ + + offset = ftello(out); + + if (_zip_filerange_crc(out, cd->offset, cd->size, &crc, &za->error) < 0) + return -1; + + snprintf(buf, sizeof(buf), "%08lX", (long)crc); + + if (fseeko(out, offset-TORRENT_CRC_LEN, SEEK_SET) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + if (fwrite(buf, TORRENT_CRC_LEN, 1, out) != 1) { + _zip_error_set(&za->error, ZIP_ER_WRITE, errno); + return -1; + } + + return 0; +} + + + +static int +_zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src) +{ + if (src->ch_comment_len != -1) { + dest->comment = (char *)_zip_memdup(src->ch_comment, + src->ch_comment_len, &src->error); + if (dest->comment == NULL) + return -1; + dest->comment_len = src->ch_comment_len; + } else { + if (src->cdir && src->cdir->comment) { + dest->comment = (char *)_zip_memdup(src->cdir->comment, + src->cdir->comment_len, &src->error); + if (dest->comment == NULL) + return -1; + dest->comment_len = src->cdir->comment_len; + } + } + + return 0; +} + + + +static int +_zip_changed(struct zip *za, int *survivorsp) +{ + int changed, i, survivors; + + changed = survivors = 0; + + if (za->ch_comment_len != -1 + || za->ch_flags != za->flags) + changed = 1; + + for (i=0; inentry; i++) { + if ((za->entry[i].state != ZIP_ST_UNCHANGED) + || (za->entry[i].ch_comment_len != -1)) + changed = 1; + if (za->entry[i].state != ZIP_ST_DELETED) + survivors++; + } + + *survivorsp = survivors; + + return changed; +} + + +#ifdef UNICODE +static wchar_t * +#else +static char * +#endif +_zip_create_temp_output(struct zip *za, FILE **outp) +{ +#ifdef UNICODE + wchar_t *temp; +#else + char *temp; +#endif + int tfd; + FILE *tfp; + +#ifdef UNICODE + if ((temp=(wchar_t *)malloc((wcslen(za->zn)+8)*2)) == NULL) { +#else + if ((temp=(char *)malloc(strlen(za->zn)+8)) == NULL) { +#endif + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + +#ifdef UNICODE + swprintf(temp, L"%s.XXXXXX", za->zn); +#else + sprintf(temp, "%s.XXXXXX", za->zn); +#endif + + if ((tfd=mkstemp(temp)) == -1) { + _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); + free(temp); + return NULL; + } + + if ((tfp=fdopen(tfd, "r+b")) == NULL) { + _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); +#ifndef _WIN32 + close(tfd); +#endif +#ifdef UNICODE + _wremove(temp); +#else + remove(temp); +#endif + free(temp); + return NULL; + } + + *outp = tfp; + return temp; +} + + + +static int +_zip_torrentzip_cmp(const void *a, const void *b) +{ + return strcasecmp(((const struct filelist *)a)->name, + ((const struct filelist *)b)->name); +} diff --git a/ext/native/ext/libzip/zip_delete.c b/ext/native/ext/libzip/zip_delete.c new file mode 100644 index 0000000000..a0545e4b9e --- /dev/null +++ b/ext/native/ext/libzip/zip_delete.c @@ -0,0 +1,58 @@ +/* + zip_delete.c -- delete file from zip archive + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_delete(struct zip *za, int idx) +{ + if (idx < 0 || idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + /* allow duplicate file names, because the file will + * be removed directly afterwards */ + if (_zip_unchange(za, idx, 1) != 0) + return -1; + + za->entry[idx].state = ZIP_ST_DELETED; + + return 0; +} + + diff --git a/ext/native/ext/libzip/zip_dirent.c b/ext/native/ext/libzip/zip_dirent.c new file mode 100644 index 0000000000..d0ae6ad1cb --- /dev/null +++ b/ext/native/ext/libzip/zip_dirent.c @@ -0,0 +1,618 @@ +/* + zip_dirent.c -- read directory entry (local or central), clean dirent + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include +#include +#include +#include +#include + +#include "zipint.h" + +static time_t _zip_d2u_time(int, int); +static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *); +static char *_zip_readstr(unsigned char **, int, int, struct zip_error *); +static void _zip_u2d_time(time_t, unsigned short *, unsigned short *); +static void _zip_write2(unsigned short, FILE *); +static void _zip_write4(unsigned int, FILE *); + + + +void +_zip_cdir_free(struct zip_cdir *cd) +{ + int i; + + if (!cd) + return; + + for (i=0; inentry; i++) + _zip_dirent_finalize(cd->entry+i); + free(cd->comment); + free(cd->entry); + free(cd); +} + + + +int +_zip_cdir_grow(struct zip_cdir *cd, int nentry, struct zip_error *error) +{ + struct zip_dirent *entry; + + if (nentry < cd->nentry) { + _zip_error_set(error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if ((entry=((struct zip_dirent *) + realloc(cd->entry, sizeof(*(cd->entry))*nentry))) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return -1; + } + + cd->nentry = nentry; + cd->entry = entry; + + return 0; +} + + + +struct zip_cdir * +_zip_cdir_new(int nentry, struct zip_error *error) +{ + struct zip_cdir *cd; + + if ((cd=(struct zip_cdir *)malloc(sizeof(*cd))) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if ((cd->entry=(struct zip_dirent *)malloc(sizeof(*(cd->entry))*nentry)) + == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + free(cd); + return NULL; + } + + /* entries must be initialized by caller */ + + cd->nentry = nentry; + cd->size = cd->offset = 0; + cd->comment = NULL; + cd->comment_len = 0; + + return cd; +} + + + +int +_zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error) +{ + int i; + + cd->offset = ftello(fp); + + for (i=0; inentry; i++) { + if (_zip_dirent_write(cd->entry+i, fp, 0, error) != 0) + return -1; + } + + cd->size = ftello(fp) - cd->offset; + + /* clearerr(fp); */ + fwrite(EOCD_MAGIC, 1, 4, fp); + _zip_write4(0, fp); + _zip_write2((unsigned short)cd->nentry, fp); + _zip_write2((unsigned short)cd->nentry, fp); + _zip_write4(cd->size, fp); + _zip_write4(cd->offset, fp); + _zip_write2(cd->comment_len, fp); + fwrite(cd->comment, 1, cd->comment_len, fp); + + if (ferror(fp)) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + return 0; +} + + + +void +_zip_dirent_finalize(struct zip_dirent *zde) +{ + free(zde->filename); + zde->filename = NULL; + free(zde->extrafield); + zde->extrafield = NULL; + free(zde->comment); + zde->comment = NULL; +} + + + +void +_zip_dirent_init(struct zip_dirent *de) +{ + de->version_madeby = 0; + de->version_needed = 20; /* 2.0 */ + de->bitflags = 0; + de->comp_method = 0; + de->last_mod = 0; + de->crc = 0; + de->comp_size = 0; + de->uncomp_size = 0; + de->filename = NULL; + de->filename_len = 0; + de->extrafield = NULL; + de->extrafield_len = 0; + de->comment = NULL; + de->comment_len = 0; + de->disk_number = 0; + de->int_attrib = 0; + de->ext_attrib = 0; + de->offset = 0; +} + + + +/* _zip_dirent_read(zde, fp, bufp, left, localp, error): + Fills the zip directory entry zde. + + If bufp is non-NULL, data is taken from there and bufp is advanced + by the amount of data used; otherwise data is read from fp as needed. + + if leftp is non-NULL, no more bytes than specified by it are used, + and *leftp is reduced by the number of bytes used. + + If local != 0, it reads a local header instead of a central + directory entry. + + Returns 0 if successful. On error, error is filled in and -1 is + returned. + + XXX: leftp and file position undefined on error. +*/ + +int +_zip_dirent_read(struct zip_dirent *zde, FILE *fp, + unsigned char **bufp, unsigned int *leftp, int local, + struct zip_error *error) +{ + unsigned char buf[CDENTRYSIZE]; + unsigned char *cur; + unsigned short dostime, dosdate; + unsigned int size; + + if (local) + size = LENTRYSIZE; + else + size = CDENTRYSIZE; + + if (leftp && (*leftp < size)) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + + if (bufp) { + /* use data from buffer */ + cur = *bufp; + } + else { + /* read entry from disk */ + if ((fread(buf, 1, size, fp)version_madeby = _zip_read2(&cur); + else + zde->version_madeby = 0; + zde->version_needed = _zip_read2(&cur); + zde->bitflags = _zip_read2(&cur); + zde->comp_method = _zip_read2(&cur); + + /* convert to time_t */ + dostime = _zip_read2(&cur); + dosdate = _zip_read2(&cur); + zde->last_mod = _zip_d2u_time(dostime, dosdate); + + zde->crc = _zip_read4(&cur); + zde->comp_size = _zip_read4(&cur); + zde->uncomp_size = _zip_read4(&cur); + + zde->filename_len = _zip_read2(&cur); + zde->extrafield_len = _zip_read2(&cur); + + if (local) { + zde->comment_len = 0; + zde->disk_number = 0; + zde->int_attrib = 0; + zde->ext_attrib = 0; + zde->offset = 0; + } else { + zde->comment_len = _zip_read2(&cur); + zde->disk_number = _zip_read2(&cur); + zde->int_attrib = _zip_read2(&cur); + zde->ext_attrib = _zip_read4(&cur); + zde->offset = _zip_read4(&cur); + } + + zde->filename = NULL; + zde->extrafield = NULL; + zde->comment = NULL; + + size += zde->filename_len+zde->extrafield_len+zde->comment_len; + + if (leftp && (*leftp < size)) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + + if (bufp) { + if (zde->filename_len) { + zde->filename = _zip_readstr(&cur, zde->filename_len, 1, error); + if (!zde->filename) + return -1; + } + + if (zde->extrafield_len) { + zde->extrafield = _zip_readstr(&cur, zde->extrafield_len, 0, + error); + if (!zde->extrafield) + return -1; + } + + if (zde->comment_len) { + zde->comment = _zip_readstr(&cur, zde->comment_len, 0, error); + if (!zde->comment) + return -1; + } + } + else { + if (zde->filename_len) { + zde->filename = _zip_readfpstr(fp, zde->filename_len, 1, error); + if (!zde->filename) + return -1; + } + + if (zde->extrafield_len) { + zde->extrafield = _zip_readfpstr(fp, zde->extrafield_len, 0, + error); + if (!zde->extrafield) + return -1; + } + + if (zde->comment_len) { + zde->comment = _zip_readfpstr(fp, zde->comment_len, 0, error); + if (!zde->comment) + return -1; + } + } + + if (bufp) + *bufp = cur; + if (leftp) + *leftp -= size; + + return 0; +} + + + +/* _zip_dirent_torrent_normalize(de); + Set values suitable for torrentzip. +*/ + +void +_zip_dirent_torrent_normalize(struct zip_dirent *de) +{ + static struct tm torrenttime; + static time_t last_mod = 0; + + if (last_mod == 0) { +#ifdef HAVE_STRUCT_TM_TM_ZONE + time_t now; + struct tm *l; +#endif + + torrenttime.tm_sec = 0; + torrenttime.tm_min = 32; + torrenttime.tm_hour = 23; + torrenttime.tm_mday = 24; + torrenttime.tm_mon = 11; + torrenttime.tm_year = 96; + torrenttime.tm_wday = 0; + torrenttime.tm_yday = 0; + torrenttime.tm_isdst = 0; + +#ifdef HAVE_STRUCT_TM_TM_ZONE + time(&now); + l = localtime(&now); + torrenttime.tm_gmtoff = l->tm_gmtoff; + torrenttime.tm_zone = l->tm_zone; +#endif + + last_mod = mktime(&torrenttime); + } + + de->version_madeby = 0; + de->version_needed = 20; /* 2.0 */ + de->bitflags = 2; /* maximum compression */ + de->comp_method = ZIP_CM_DEFLATE; + de->last_mod = last_mod; + + de->disk_number = 0; + de->int_attrib = 0; + de->ext_attrib = 0; + de->offset = 0; + + free(de->extrafield); + de->extrafield = NULL; + de->extrafield_len = 0; + free(de->comment); + de->comment = NULL; + de->comment_len = 0; +} + + + +/* _zip_dirent_write(zde, fp, localp, error): + Writes zip directory entry zde to file fp. + + If localp != 0, it writes a local header instead of a central + directory entry. + + Returns 0 if successful. On error, error is filled in and -1 is + returned. +*/ + +int +_zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp, + struct zip_error *error) +{ + unsigned short dostime, dosdate; + + fwrite(localp ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); + + if (!localp) + _zip_write2(zde->version_madeby, fp); + _zip_write2(zde->version_needed, fp); + _zip_write2(zde->bitflags, fp); + _zip_write2(zde->comp_method, fp); + + _zip_u2d_time(zde->last_mod, &dostime, &dosdate); + _zip_write2(dostime, fp); + _zip_write2(dosdate, fp); + + _zip_write4(zde->crc, fp); + _zip_write4(zde->comp_size, fp); + _zip_write4(zde->uncomp_size, fp); + + _zip_write2(zde->filename_len, fp); + _zip_write2(zde->extrafield_len, fp); + + if (!localp) { + _zip_write2(zde->comment_len, fp); + _zip_write2(zde->disk_number, fp); + _zip_write2(zde->int_attrib, fp); + _zip_write4(zde->ext_attrib, fp); + _zip_write4(zde->offset, fp); + } + + if (zde->filename_len) + fwrite(zde->filename, 1, zde->filename_len, fp); + + if (zde->extrafield_len) + fwrite(zde->extrafield, 1, zde->extrafield_len, fp); + + if (!localp) { + if (zde->comment_len) + fwrite(zde->comment, 1, zde->comment_len, fp); + } + + if (ferror(fp)) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + return 0; +} + + + +static time_t +_zip_d2u_time(int dtime, int ddate) +{ + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + /* let mktime decide if DST is in effect */ + tm.tm_isdst = -1; + + tm.tm_year = ((ddate>>9)&127) + 1980 - 1900; + tm.tm_mon = ((ddate>>5)&15) - 1; + tm.tm_mday = ddate&31; + + tm.tm_hour = (dtime>>11)&31; + tm.tm_min = (dtime>>5)&63; + tm.tm_sec = (dtime<<1)&62; + + return mktime(&tm); +} + + + +unsigned short +_zip_read2(unsigned char **a) +{ + unsigned short ret; + + ret = (*a)[0]+((*a)[1]<<8); + *a += 2; + + return ret; +} + + + +unsigned int +_zip_read4(unsigned char **a) +{ + unsigned int ret; + + ret = ((((((*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; + *a += 4; + + return ret; +} + + + +static char * +_zip_readfpstr(FILE *fp, unsigned int len, int nulp, struct zip_error *error) +{ + char *r, *o; + + r = (char *)malloc(nulp ? len+1 : len); + if (!r) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if (fread(r, 1, len, fp)>8)&0xff, fp); + + return; +} + + + +static void +_zip_write4(unsigned int i, FILE *fp) +{ + putc(i&0xff, fp); + putc((i>>8)&0xff, fp); + putc((i>>16)&0xff, fp); + putc((i>>24)&0xff, fp); + + return; +} + + + +static void +_zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate) +{ + struct tm *tm; + + tm = localtime(&time); + *ddate = ((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + + tm->tm_mday; + *dtime = ((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + + ((tm->tm_sec)>>1); + + return; +} diff --git a/ext/native/ext/libzip/zip_entry_free.c b/ext/native/ext/libzip/zip_entry_free.c new file mode 100644 index 0000000000..c50c9434bd --- /dev/null +++ b/ext/native/ext/libzip/zip_entry_free.c @@ -0,0 +1,52 @@ +/* + zip_entry_free.c -- free struct zip_entry + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +void +_zip_entry_free(struct zip_entry *ze) +{ + free(ze->ch_filename); + ze->ch_filename = NULL; + free(ze->ch_comment); + ze->ch_comment = NULL; + ze->ch_comment_len = -1; + + _zip_unchange_data(ze); +} diff --git a/ext/native/ext/libzip/zip_entry_new.c b/ext/native/ext/libzip/zip_entry_new.c new file mode 100644 index 0000000000..7059b1b060 --- /dev/null +++ b/ext/native/ext/libzip/zip_entry_new.c @@ -0,0 +1,78 @@ +/* + zip_entry_new.c -- create and init struct zip_entry + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +struct zip_entry * +_zip_entry_new(struct zip *za) +{ + struct zip_entry *ze; + if (!za) { + ze = (struct zip_entry *)malloc(sizeof(struct zip_entry)); + if (!ze) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + } + else { + if (za->nentry >= za->nentry_alloc-1) { + za->nentry_alloc += 16; + za->entry = (struct zip_entry *)realloc(za->entry, + sizeof(struct zip_entry) + * za->nentry_alloc); + if (!za->entry) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + } + ze = za->entry+za->nentry; + } + + ze->state = ZIP_ST_UNCHANGED; + + ze->ch_filename = NULL; + ze->ch_comment = NULL; + ze->ch_comment_len = -1; + ze->source = NULL; + + if (za) + za->nentry++; + + return ze; +} diff --git a/ext/native/ext/libzip/zip_err_str.c b/ext/native/ext/libzip/zip_err_str.c new file mode 100644 index 0000000000..3fcdf1738a --- /dev/null +++ b/ext/native/ext/libzip/zip_err_str.c @@ -0,0 +1,68 @@ +/* + This file was generated automatically by ./make_zip_err_str.sh + from ./zip.h; make changes there. + */ + +#include "zipint.h" + + + +const char * const _zip_err_str[] = { + "No error", + "Multi-disk zip archives not supported", + "Renaming temporary file failed", + "Closing zip archive failed", + "Seek error", + "Read error", + "Write error", + "CRC error", + "Containing zip archive was closed", + "No such file", + "File already exists", + "Can't open file", + "Failure to create temporary file", + "Zlib error", + "Malloc failure", + "Entry has been changed", + "Compression method not supported", + "Premature EOF", + "Invalid argument", + "Not a zip archive", + "Internal error", + "Zip archive inconsistent", + "Can't remove file", + "Entry has been deleted", +}; + +const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); + +#define N ZIP_ET_NONE +#define S ZIP_ET_SYS +#define Z ZIP_ET_ZLIB + +const int _zip_err_type[] = { + N, + N, + S, + S, + S, + S, + S, + N, + N, + N, + N, + S, + S, + Z, + N, + N, + N, + N, + N, + N, + N, + N, + S, + N, +}; diff --git a/ext/native/ext/libzip/zip_error.c b/ext/native/ext/libzip/zip_error.c new file mode 100644 index 0000000000..aab7079456 --- /dev/null +++ b/ext/native/ext/libzip/zip_error.c @@ -0,0 +1,101 @@ +/* + zip_error.c -- struct zip_error helper functions + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +void +_zip_error_clear(struct zip_error *err) +{ + err->zip_err = ZIP_ER_OK; + err->sys_err = 0; +} + + + +void +_zip_error_copy(struct zip_error *dst, struct zip_error *src) +{ + dst->zip_err = src->zip_err; + dst->sys_err = src->sys_err; +} + + + +void +_zip_error_fini(struct zip_error *err) +{ + free(err->str); + err->str = NULL; +} + + + +void +_zip_error_get(struct zip_error *err, int *zep, int *sep) +{ + if (zep) + *zep = err->zip_err; + if (sep) { + if (zip_error_get_sys_type(err->zip_err) != ZIP_ET_NONE) + *sep = err->sys_err; + else + *sep = 0; + } +} + + + +void +_zip_error_init(struct zip_error *err) +{ + err->zip_err = ZIP_ER_OK; + err->sys_err = 0; + err->str = NULL; +} + + + +void +_zip_error_set(struct zip_error *err, int ze, int se) +{ + if (err) { + err->zip_err = ze; + err->sys_err = se; + } +} diff --git a/ext/native/ext/libzip/zip_error_clear.c b/ext/native/ext/libzip/zip_error_clear.c new file mode 100644 index 0000000000..364383ebe9 --- /dev/null +++ b/ext/native/ext/libzip/zip_error_clear.c @@ -0,0 +1,44 @@ +/* + zip_error_clear.c -- clear zip error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN void +zip_error_clear(struct zip *za) +{ + _zip_error_clear(&za->error); +} diff --git a/ext/native/ext/libzip/zip_error_get.c b/ext/native/ext/libzip/zip_error_get.c new file mode 100644 index 0000000000..6d1c958c17 --- /dev/null +++ b/ext/native/ext/libzip/zip_error_get.c @@ -0,0 +1,44 @@ +/* + zip_error_get.c -- get zip error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN void +zip_error_get(struct zip *za, int *zep, int *sep) +{ + _zip_error_get(&za->error, zep, sep); +} diff --git a/ext/native/ext/libzip/zip_error_get_sys_type.c b/ext/native/ext/libzip/zip_error_get_sys_type.c new file mode 100644 index 0000000000..6c6f380740 --- /dev/null +++ b/ext/native/ext/libzip/zip_error_get_sys_type.c @@ -0,0 +1,47 @@ +/* + zip_error_get_sys_type.c -- return type of system error code + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_error_get_sys_type(int ze) +{ + if (ze < 0 || ze >= _zip_nerr_str) + return 0; + + return _zip_err_type[ze]; +} diff --git a/ext/native/ext/libzip/zip_error_strerror.c b/ext/native/ext/libzip/zip_error_strerror.c new file mode 100644 index 0000000000..d7f7d0ea9a --- /dev/null +++ b/ext/native/ext/libzip/zip_error_strerror.c @@ -0,0 +1,93 @@ +/* + zip_error_sterror.c -- get string representation of struct zip_error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include +#include +#include + +#include "zipint.h" + + + +const char * +_zip_error_strerror(struct zip_error *err) +{ + const char *zs, *ss; + char buf[128], *s; + + _zip_error_fini(err); + + if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) { + sprintf(buf, "Unknown error %d", err->zip_err); + zs = NULL; + ss = buf; + } + else { + zs = _zip_err_str[err->zip_err]; + + switch (_zip_err_type[err->zip_err]) { + case ZIP_ET_SYS: + ss = strerror(err->sys_err); + break; + + case ZIP_ET_ZLIB: + ss = zError(err->sys_err); + break; + + default: + ss = NULL; + } + } + + if (ss == NULL) + return zs; + else { + if ((s=(char *)malloc(strlen(ss) + + (zs ? strlen(zs)+2 : 0) + 1)) == NULL) + return _zip_err_str[ZIP_ER_MEMORY]; + + sprintf(s, "%s%s%s", + (zs ? zs : ""), + (zs ? ": " : ""), + ss); + err->str = s; + + return s; + } +} diff --git a/ext/native/ext/libzip/zip_error_to_str.c b/ext/native/ext/libzip/zip_error_to_str.c new file mode 100644 index 0000000000..4eea045662 --- /dev/null +++ b/ext/native/ext/libzip/zip_error_to_str.c @@ -0,0 +1,73 @@ +/* + zip_error_to_str.c -- get string representation of zip error code + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include +#include +#include + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_error_to_str(char *buf, size_t len, int ze, int se) +{ + const char *zs, *ss; + + if (ze < 0 || ze >= _zip_nerr_str) + return snprintf(buf, len, "Unknown error %d", ze); + + zs = _zip_err_str[ze]; + + switch (_zip_err_type[ze]) { + case ZIP_ET_SYS: + ss = strerror(se); + break; + + case ZIP_ET_ZLIB: + ss = zError(se); + break; + + default: + ss = NULL; + } + + return snprintf(buf, len, "%s%s%s", + zs, (ss ? ": " : ""), (ss ? ss : "")); +} diff --git a/ext/native/ext/libzip/zip_fclose.c b/ext/native/ext/libzip/zip_fclose.c new file mode 100644 index 0000000000..8709362d6c --- /dev/null +++ b/ext/native/ext/libzip/zip_fclose.c @@ -0,0 +1,71 @@ +/* + zip_fclose.c -- close file in zip archive + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_fclose(struct zip_file *zf) +{ + int i, ret; + + if (zf->zstr) + inflateEnd(zf->zstr); + free(zf->buffer); + free(zf->zstr); + + for (i=0; iza->nfile; i++) { + if (zf->za->file[i] == zf) { + zf->za->file[i] = zf->za->file[zf->za->nfile-1]; + zf->za->nfile--; + break; + } + } + + ret = 0; + if (zf->error.zip_err) + ret = zf->error.zip_err; + else if ((zf->flags & ZIP_ZF_CRC) && (zf->flags & ZIP_ZF_EOF)) { + /* if EOF, compare CRC */ + if (zf->crc_orig != zf->crc) + ret = ZIP_ER_CRC; + } + + free(zf); + return ret; +} diff --git a/ext/native/ext/libzip/zip_file_error_clear.c b/ext/native/ext/libzip/zip_file_error_clear.c new file mode 100644 index 0000000000..ef6fa10e4d --- /dev/null +++ b/ext/native/ext/libzip/zip_file_error_clear.c @@ -0,0 +1,44 @@ +/* + zip_file_error_clear.c -- clear zip file error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN void +zip_file_error_clear(struct zip_file *zf) +{ + _zip_error_clear(&zf->error); +} diff --git a/ext/native/ext/libzip/zip_file_error_get.c b/ext/native/ext/libzip/zip_file_error_get.c new file mode 100644 index 0000000000..f20e011fc7 --- /dev/null +++ b/ext/native/ext/libzip/zip_file_error_get.c @@ -0,0 +1,44 @@ +/* + zip_file_error_get.c -- get zip file error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN void +zip_file_error_get(struct zip_file *zf, int *zep, int *sep) +{ + _zip_error_get(&zf->error, zep, sep); +} diff --git a/ext/native/ext/libzip/zip_file_get_offset.c b/ext/native/ext/libzip/zip_file_get_offset.c new file mode 100644 index 0000000000..b96fd5e480 --- /dev/null +++ b/ext/native/ext/libzip/zip_file_get_offset.c @@ -0,0 +1,74 @@ +/* + zip_file_get_offset.c -- get offset of file data in archive. + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 +#include +#include + +#include "zipint.h" + + + +/* _zip_file_get_offset(za, ze): + Returns the offset of the file data for entry ze. + + On error, fills in za->error and returns 0. +*/ + +unsigned int +_zip_file_get_offset(struct zip *za, int idx) +{ + struct zip_dirent de; + unsigned int offset; + + offset = za->cdir->entry[idx].offset; + + if (fseeko(za->zp, offset, SEEK_SET) != 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return 0; + } + + if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, &za->error) != 0) + return 0; + + offset += LENTRYSIZE + de.filename_len + de.extrafield_len; + + _zip_dirent_finalize(&de); + + return offset; +} diff --git a/ext/native/ext/libzip/zip_file_strerror.c b/ext/native/ext/libzip/zip_file_strerror.c new file mode 100644 index 0000000000..9ba70f14ff --- /dev/null +++ b/ext/native/ext/libzip/zip_file_strerror.c @@ -0,0 +1,44 @@ +/* + zip_file_sterror.c -- get string representation of zip file error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN const char * +zip_file_strerror(struct zip_file *zf) +{ + return _zip_error_strerror(&zf->error); +} diff --git a/ext/native/ext/libzip/zip_filerange_crc.c b/ext/native/ext/libzip/zip_filerange_crc.c new file mode 100644 index 0000000000..4da727b337 --- /dev/null +++ b/ext/native/ext/libzip/zip_filerange_crc.c @@ -0,0 +1,75 @@ +/* + zip_filerange_crc.c -- compute CRC32 for a range of a file + Copyright (C) 2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include + +#include "zipint.h" + + + + +int +_zip_filerange_crc(FILE *fp, off_t start, off_t len, uLong *crcp, + struct zip_error *errp) +{ + Bytef buf[BUFSIZE]; + size_t n; + + *crcp = crc32(0L, Z_NULL, 0); + + if (fseeko(fp, start, SEEK_SET) != 0) { + _zip_error_set(errp, ZIP_ER_SEEK, errno); + return -1; + } + + while (len > 0) { + n = len > BUFSIZE ? BUFSIZE : len; + if ((n=fread(buf, 1, n, fp)) <= 0) { + _zip_error_set(errp, ZIP_ER_READ, errno); + return -1; + } + + *crcp = crc32(*crcp, buf, (uInt)n); + + len-= (off_t)n; + } + + return 0; +} diff --git a/ext/native/ext/libzip/zip_fopen.c b/ext/native/ext/libzip/zip_fopen.c new file mode 100644 index 0000000000..6e2f724127 --- /dev/null +++ b/ext/native/ext/libzip/zip_fopen.c @@ -0,0 +1,49 @@ +/* + zip_fopen.c -- open file in zip archive for reading + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN struct zip_file * +zip_fopen(struct zip *za, const char *fname, int flags) +{ + int idx; + + if ((idx=zip_name_locate(za, fname, flags)) < 0) + return NULL; + + return zip_fopen_index(za, idx, flags); +} diff --git a/ext/native/ext/libzip/zip_fopen_index.c b/ext/native/ext/libzip/zip_fopen_index.c new file mode 100644 index 0000000000..ea4a68acf7 --- /dev/null +++ b/ext/native/ext/libzip/zip_fopen_index.c @@ -0,0 +1,221 @@ +/* + zip_fopen_index.c -- open file in zip archive for reading by index + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + + +#include +#include +#include + +#include "zipint.h" + +static struct zip_file *_zip_file_new(struct zip *za); + + + +ZIP_EXTERN struct zip_file * +zip_fopen_index(struct zip *za, int fileno, int flags) +{ + int len, ret; + int zfflags; + struct zip_file *zf; + + if ((fileno < 0) || (fileno >= za->nentry)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return NULL; + } + + if (fileno >= za->cdir->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + zfflags = 0; + switch (za->cdir->entry[fileno].comp_method) { + case ZIP_CM_STORE: + zfflags |= ZIP_ZF_CRC; + break; + + case ZIP_CM_DEFLATE: + if ((flags & ZIP_FL_COMPRESSED) == 0) + zfflags |= ZIP_ZF_CRC | ZIP_ZF_DECOMP; + break; + default: + if ((flags & ZIP_FL_COMPRESSED) == 0) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return NULL; + } + break; + } + + zf = _zip_file_new(za); + + zf->flags = zfflags; + /* zf->name = za->cdir->entry[fileno].filename; */ + zf->method = za->cdir->entry[fileno].comp_method; + zf->bytes_left = za->cdir->entry[fileno].uncomp_size; + zf->cbytes_left = za->cdir->entry[fileno].comp_size; + zf->crc_orig = za->cdir->entry[fileno].crc; + + if ((zf->fpos=_zip_file_get_offset(za, fileno)) == 0) { + zip_fclose(zf); + return NULL; + } + + if ((zf->flags & ZIP_ZF_DECOMP) == 0) + zf->bytes_left = zf->cbytes_left; + else { + if ((zf->buffer=(char *)malloc(BUFSIZE)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + zip_fclose(zf); + return NULL; + } + + len = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf); + if (len <= 0) { + _zip_error_copy(&za->error, &zf->error); + zip_fclose(zf); + return NULL; + } + + if ((zf->zstr = (z_stream *)malloc(sizeof(z_stream))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + zip_fclose(zf); + return NULL; + } + zf->zstr->zalloc = Z_NULL; + zf->zstr->zfree = Z_NULL; + zf->zstr->opaque = NULL; + zf->zstr->next_in = (Bytef *)zf->buffer; + zf->zstr->avail_in = len; + + /* negative value to tell zlib that there is no header */ + if ((ret=inflateInit2(zf->zstr, -MAX_WBITS)) != Z_OK) { + _zip_error_set(&za->error, ZIP_ER_ZLIB, ret); + zip_fclose(zf); + return NULL; + } + } + + return zf; +} + + + +int +_zip_file_fillbuf(void *buf, size_t buflen, struct zip_file *zf) +{ + ssize_t i; + int j; + + if (zf->error.zip_err != ZIP_ER_OK) + return -1; + + if ((zf->flags & ZIP_ZF_EOF) || zf->cbytes_left <= 0 || buflen <= 0) + return 0; + + if (fseeko(zf->za->zp, zf->fpos, SEEK_SET) < 0) { + _zip_error_set(&zf->error, ZIP_ER_SEEK, errno); + return -1; + } + if (buflen < zf->cbytes_left) + i = buflen; + else + i = zf->cbytes_left; + + j = (int)fread(buf, 1, i, zf->za->zp); + if (j == 0) { + _zip_error_set(&zf->error, ZIP_ER_EOF, 0); + j = -1; + } + else if (j < 0) + _zip_error_set(&zf->error, ZIP_ER_READ, errno); + else { + zf->fpos += j; + zf->cbytes_left -= j; + } + + return j; +} + + + +static struct zip_file * +_zip_file_new(struct zip *za) +{ + struct zip_file *zf, **file; + int n; + + if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if (za->nfile >= za->nfile_alloc-1) { + n = za->nfile_alloc + 10; + file = (struct zip_file **)realloc(za->file, + n*sizeof(struct zip_file *)); + if (file == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + free(zf); + return NULL; + } + za->nfile_alloc = n; + za->file = file; + } + + za->file[za->nfile++] = zf; + + zf->za = za; + _zip_error_init(&zf->error); + zf->flags = 0; + zf->crc = crc32(0L, Z_NULL, 0); + zf->crc_orig = 0; + zf->method = -1; + zf->bytes_left = zf->cbytes_left = 0; + zf->fpos = 0; + zf->buffer = NULL; + zf->zstr = NULL; + + return zf; +} diff --git a/ext/native/ext/libzip/zip_fread.c b/ext/native/ext/libzip/zip_fread.c new file mode 100644 index 0000000000..036e87c547 --- /dev/null +++ b/ext/native/ext/libzip/zip_fread.c @@ -0,0 +1,134 @@ +/* + zip_fread.c -- read from file + Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include "zipint.h" + + + +ZIP_EXTERN ssize_t +zip_fread(struct zip_file *zf, void *outbuf, size_t toread) +{ + int ret; + size_t out_before, len; + int i; + + if (!zf) + return -1; + + if (zf->error.zip_err != 0) + return -1; + + if ((zf->flags & ZIP_ZF_EOF) || (toread == 0)) + return 0; + + if (zf->bytes_left == 0) { + zf->flags |= ZIP_ZF_EOF; + if (zf->flags & ZIP_ZF_CRC) { + if (zf->crc != zf->crc_orig) { + _zip_error_set(&zf->error, ZIP_ER_CRC, 0); + return -1; + } + } + return 0; + } + + if ((zf->flags & ZIP_ZF_DECOMP) == 0) { + ret = _zip_file_fillbuf(outbuf, toread, zf); + if (ret > 0) { + if (zf->flags & ZIP_ZF_CRC) + zf->crc = crc32(zf->crc, (Bytef *)outbuf, ret); + zf->bytes_left -= ret; + } + return ret; + } + + zf->zstr->next_out = (Bytef *)outbuf; + zf->zstr->avail_out = (uInt)toread; + out_before = zf->zstr->total_out; + + /* endless loop until something has been accomplished */ + for (;;) { + ret = inflate(zf->zstr, Z_SYNC_FLUSH); + + switch (ret) { + case Z_STREAM_END: + if (zf->zstr->total_out == out_before) { + if (zf->crc != zf->crc_orig) { + _zip_error_set(&zf->error, ZIP_ER_CRC, 0); + return -1; + } + else + return 0; + } + + /* fallthrough */ + + case Z_OK: + len = zf->zstr->total_out - out_before; + if (len >= zf->bytes_left || len >= toread) { + if (zf->flags & ZIP_ZF_CRC) + zf->crc = crc32(zf->crc, (Bytef *)outbuf, (uInt)len); + zf->bytes_left -= (unsigned long)len; + return len; + } + break; + + case Z_BUF_ERROR: + if (zf->zstr->avail_in == 0) { + i = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf); + if (i == 0) { + _zip_error_set(&zf->error, ZIP_ER_INCONS, 0); + return -1; + } + else if (i < 0) + return -1; + zf->zstr->next_in = (Bytef *)zf->buffer; + zf->zstr->avail_in = i; + continue; + } + /* fallthrough */ + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_STREAM_ERROR: + case Z_MEM_ERROR: + _zip_error_set(&zf->error, ZIP_ER_ZLIB, ret); + return -1; + } + } +} diff --git a/ext/native/ext/libzip/zip_free.c b/ext/native/ext/libzip/zip_free.c new file mode 100644 index 0000000000..76c3a9673f --- /dev/null +++ b/ext/native/ext/libzip/zip_free.c @@ -0,0 +1,81 @@ +/* + zip_free.c -- free struct zip + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +/* _zip_free: + frees the space allocated to a zipfile struct, and closes the + corresponding file. */ + +void +_zip_free(struct zip *za) +{ + int i; + + if (za == NULL) + return; + + if (za->zn) + free(za->zn); + + if (za->zp) + fclose(za->zp); + + _zip_cdir_free(za->cdir); + + if (za->entry) { + for (i=0; inentry; i++) { + _zip_entry_free(za->entry+i); + } + free(za->entry); + } + + for (i=0; infile; i++) { + if (za->file[i]->error.zip_err == ZIP_ER_OK) { + _zip_error_set(&za->file[i]->error, ZIP_ER_ZIPCLOSED, 0); + za->file[i]->za = NULL; + } + } + + free(za->file); + + free(za); + + return; +} diff --git a/ext/native/ext/libzip/zip_get_archive_comment.c b/ext/native/ext/libzip/zip_get_archive_comment.c new file mode 100644 index 0000000000..669eb70216 --- /dev/null +++ b/ext/native/ext/libzip/zip_get_archive_comment.c @@ -0,0 +1,60 @@ +/* + zip_get_archive_comment.c -- get archive comment + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN const char * +zip_get_archive_comment(struct zip *za, int *lenp, int flags) +{ + if ((flags & ZIP_FL_UNCHANGED) + || (za->ch_comment_len == -1)) { + if (za->cdir) { + if (lenp != NULL) + *lenp = za->cdir->comment_len; + return za->cdir->comment; + } + else { + if (lenp != NULL) + *lenp = -1; + return NULL; + } + } + + if (lenp != NULL) + *lenp = za->ch_comment_len; + return za->ch_comment; +} diff --git a/ext/native/ext/libzip/zip_get_archive_flag.c b/ext/native/ext/libzip/zip_get_archive_flag.c new file mode 100644 index 0000000000..4733d92b58 --- /dev/null +++ b/ext/native/ext/libzip/zip_get_archive_flag.c @@ -0,0 +1,48 @@ +/* + zip_get_archive_flag.c -- get archive global flag + Copyright (C) 2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_get_archive_flag(struct zip *za, int flag, int flags) +{ + int fl; + + fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags; + + return (fl & flag) ? 1 : 0; +} diff --git a/ext/native/ext/libzip/zip_get_file_comment.c b/ext/native/ext/libzip/zip_get_file_comment.c new file mode 100644 index 0000000000..adace72474 --- /dev/null +++ b/ext/native/ext/libzip/zip_get_file_comment.c @@ -0,0 +1,58 @@ +/* + zip_get_file_comment.c -- get file comment + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN const char * +zip_get_file_comment(struct zip *za, int idx, int *lenp, int flags) +{ + if (idx < 0 || idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) + || (za->entry[idx].ch_comment_len == -1)) { + if (lenp != NULL) + *lenp = za->cdir->entry[idx].comment_len; + return za->cdir->entry[idx].comment; + } + + if (lenp != NULL) + *lenp = za->entry[idx].ch_comment_len; + return za->entry[idx].ch_comment; +} diff --git a/ext/native/ext/libzip/zip_get_name.c b/ext/native/ext/libzip/zip_get_name.c new file mode 100644 index 0000000000..8f5050bd2e --- /dev/null +++ b/ext/native/ext/libzip/zip_get_name.c @@ -0,0 +1,71 @@ +/* + zip_get_name.c -- get filename for a file in zip file + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN const char * +zip_get_name(struct zip *za, int idx, int flags) +{ + return _zip_get_name(za, idx, flags, &za->error); +} + + + +const char * +_zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error) +{ + if (idx < 0 || idx >= za->nentry) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0) { + if (za->entry[idx].state == ZIP_ST_DELETED) { + _zip_error_set(error, ZIP_ER_DELETED, 0); + return NULL; + } + if (za->entry[idx].ch_filename) + return za->entry[idx].ch_filename; + } + + if (za->cdir == NULL || idx >= za->cdir->nentry) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + return za->cdir->entry[idx].filename; +} diff --git a/ext/native/ext/libzip/zip_get_num_files.c b/ext/native/ext/libzip/zip_get_num_files.c new file mode 100644 index 0000000000..1d9baa3d65 --- /dev/null +++ b/ext/native/ext/libzip/zip_get_num_files.c @@ -0,0 +1,47 @@ +/* + zip_get_num_files.c -- get number of files in archive + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_get_num_files(struct zip *za) +{ + if (za == NULL) + return -1; + + return za->nentry; +} diff --git a/ext/native/ext/libzip/zip_memdup.c b/ext/native/ext/libzip/zip_memdup.c new file mode 100644 index 0000000000..641125ed2d --- /dev/null +++ b/ext/native/ext/libzip/zip_memdup.c @@ -0,0 +1,55 @@ +/* + zip_memdup.c -- internal zip function, "strdup" with len + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +void * +_zip_memdup(const void *mem, size_t len, struct zip_error *error) +{ + void *ret; + + ret = malloc(len); + if (!ret) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + memcpy(ret, mem, len); + + return ret; +} diff --git a/ext/native/ext/libzip/zip_name_locate.c b/ext/native/ext/libzip/zip_name_locate.c new file mode 100644 index 0000000000..926abc1b90 --- /dev/null +++ b/ext/native/ext/libzip/zip_name_locate.c @@ -0,0 +1,90 @@ +/* + zip_name_locate.c -- get index by name + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + +#include +#ifdef HAVE_STRINGS_H +#include +#endif + + +ZIP_EXTERN int +zip_name_locate(struct zip *za, const char *fname, int flags) +{ + return _zip_name_locate(za, fname, flags, &za->error); +} + + + +int +_zip_name_locate(struct zip *za, const char *fname, int flags, + struct zip_error *error) +{ + int (*cmp)(const char *, const char *); + const char *fn, *p; + int i, n; + + if (fname == NULL) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return -1; + } + + cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp; + + n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry; + for (i=0; icdir->entry[i].filename; + else + fn = _zip_get_name(za, i, flags, error); + + /* newly added (partially filled) entry */ + if (fn == NULL) + continue; + + if (flags & ZIP_FL_NODIR) { + p = strrchr(fn, '/'); + if (p) + fn = p+1; + } + + if (cmp(fname, fn) == 0) + return i; + } + + _zip_error_set(error, ZIP_ER_NOENT, 0); + return -1; +} diff --git a/ext/native/ext/libzip/zip_new.c b/ext/native/ext/libzip/zip_new.c new file mode 100644 index 0000000000..3e8ccee644 --- /dev/null +++ b/ext/native/ext/libzip/zip_new.c @@ -0,0 +1,70 @@ +/* + zip_new.c -- create and init struct zip + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +/* _zip_new: + creates a new zipfile struct, and sets the contents to zero; returns + the new struct. */ + +struct zip * +_zip_new(struct zip_error *error) +{ + struct zip *za; + + za = (struct zip *)malloc(sizeof(struct zip)); + if (!za) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + za->zn = NULL; + za->zp = NULL; + _zip_error_init(&za->error); + za->cdir = NULL; + za->ch_comment = NULL; + za->ch_comment_len = -1; + za->nentry = za->nentry_alloc = 0; + za->entry = NULL; + za->nfile = za->nfile_alloc = 0; + za->file = NULL; + za->flags = za->ch_flags = 0; + + return za; +} diff --git a/ext/native/ext/libzip/zip_open.c b/ext/native/ext/libzip/zip_open.c new file mode 100644 index 0000000000..fee8a9c61c --- /dev/null +++ b/ext/native/ext/libzip/zip_open.c @@ -0,0 +1,601 @@ +/* + zip_open.c -- open zip archive + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include +#include +#include +#include +#include + +#include "zipint.h" + +static void set_error(int *, struct zip_error *, int); +static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); +static void _zip_check_torrentzip(struct zip *); +static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t); +#ifdef UNICODE +static struct zip *_zip_allocate_new(const wchar_t *, int *); +static int _zip_file_exists(const wchar_t *, int, int *); +#else +static struct zip *_zip_allocate_new(const char *, int *); +static int _zip_file_exists(const char *, int, int *); +#endif +static int _zip_headercomp(struct zip_dirent *, int, + struct zip_dirent *, int); +static unsigned char *_zip_memmem(const unsigned char *, int, + const unsigned char *, int); +static struct zip_cdir *_zip_readcdir(FILE *, unsigned char *, unsigned char *, + int, int, struct zip_error *); + + +ZIP_EXTERN struct zip * +#ifdef UNICODE +zip_open(const wchar_t *fn, int flags, int *zep) +#else +zip_open(const char *fn, int flags, int *zep) +#endif +{ + FILE *fp; + struct zip *za; + struct zip_cdir *cdir; + int i; + off_t len; + + switch (_zip_file_exists(fn, flags, zep)) { + case -1: + return NULL; + case 0: + return _zip_allocate_new(fn, zep); + default: + break; + } + +#ifdef UNICODE + if ((fp=_wfopen(fn, L"rb")) == NULL) { +#else + if ((fp=fopen(fn, "rb")) == NULL) { +#endif + set_error(zep, NULL, ZIP_ER_OPEN); + return NULL; + } + + fseeko(fp, 0, SEEK_END); + len = ftello(fp); + + /* treat empty files as empty archives */ + if (len == 0) { + if ((za=_zip_allocate_new(fn, zep)) == NULL) + fclose(fp); + else + za->zp = fp; + return za; + } + + cdir = _zip_find_central_dir(fp, flags, zep, len); + if (cdir == NULL) { + fclose(fp); + return NULL; + } + + if ((za=_zip_allocate_new(fn, zep)) == NULL) { + _zip_cdir_free(cdir); + fclose(fp); + return NULL; + } + + za->cdir = cdir; + za->zp = fp; + + if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry)) + * cdir->nentry)) == NULL) { + set_error(zep, NULL, ZIP_ER_MEMORY); + _zip_free(za); + return NULL; + } + for (i=0; inentry; i++) + _zip_entry_new(za); + + _zip_check_torrentzip(za); + za->ch_flags = za->flags; + + return za; +} + + + +static void +set_error(int *zep, struct zip_error *err, int ze) +{ + int se; + + if (err) { + _zip_error_get(err, &ze, &se); + if (zip_error_get_sys_type(ze) == ZIP_ET_SYS) + errno = se; + } + + if (zep) + *zep = ze; +} + + + +/* _zip_readcdir: + tries to find a valid end-of-central-directory at the beginning of + buf, and then the corresponding central directory entries. + Returns a struct zip_cdir which contains the central directory + entries, or NULL if unsuccessful. */ + +static struct zip_cdir * +_zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, + int flags, struct zip_error *error) +{ + struct zip_cdir *cd; + unsigned char *cdp, **bufp; + int i, comlen, nentry; + unsigned int left; + + comlen = buf + buflen - eocd - EOCDLEN; + if (comlen < 0) { + /* not enough bytes left for comment */ + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return NULL; + } + + /* check for end-of-central-dir magic */ + if (memcmp(eocd, EOCD_MAGIC, 4) != 0) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return NULL; + } + + if (memcmp(eocd+4, "\0\0\0\0", 4) != 0) { + _zip_error_set(error, ZIP_ER_MULTIDISK, 0); + return NULL; + } + + cdp = eocd + 8; + /* number of cdir-entries on this disk */ + i = _zip_read2(&cdp); + /* number of cdir-entries */ + nentry = _zip_read2(&cdp); + + if ((cd=_zip_cdir_new(nentry, error)) == NULL) + return NULL; + + cd->size = _zip_read4(&cdp); + cd->offset = _zip_read4(&cdp); + cd->comment = NULL; + cd->comment_len = _zip_read2(&cdp); + + if ((comlen < cd->comment_len) || (cd->nentry != i)) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + free(cd); + return NULL; + } + if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + free(cd); + return NULL; + } + + if (cd->comment_len) { + if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN, + cd->comment_len, error)) + == NULL) { + free(cd); + return NULL; + } + } + + if (cd->size < (unsigned int)(eocd-buf)) { + /* if buffer already read in, use it */ + cdp = eocd - cd->size; + bufp = &cdp; + } + else { + /* go to start of cdir and read it entry by entry */ + bufp = NULL; + clearerr(fp); + fseeko(fp, cd->offset, SEEK_SET); + /* possible consistency check: cd->offset = + len-(cd->size+cd->comment_len+EOCDLEN) ? */ + if (ferror(fp) || ((unsigned long)ftello(fp) != cd->offset)) { + /* seek error or offset of cdir wrong */ + if (ferror(fp)) + _zip_error_set(error, ZIP_ER_SEEK, errno); + else + _zip_error_set(error, ZIP_ER_NOZIP, 0); + free(cd); + return NULL; + } + } + + left = cd->size; + i=0; + do { + if (i == cd->nentry && left > 0) { + /* Infozip extension for more than 64k entries: + nentries wraps around, size indicates correct EOCD */ + _zip_cdir_grow(cd, cd->nentry+0x10000, error); + } + + if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) { + cd->nentry = i; + _zip_cdir_free(cd); + return NULL; + } + i++; + + } while (inentry); + + return cd; +} + + + +/* _zip_checkcons: + Checks the consistency of the central directory by comparing central + directory entries with local headers and checking for plausible + file and header offsets. Returns -1 if not plausible, else the + difference between the lowest and the highest fileposition reached */ + +static int +_zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error) +{ + int i; + unsigned int min, max, j; + struct zip_dirent temp; + + if (cd->nentry) { + max = cd->entry[0].offset; + min = cd->entry[0].offset; + } + else + min = max = 0; + + for (i=0; inentry; i++) { + if (cd->entry[i].offset < min) + min = cd->entry[i].offset; + if (min > cd->offset) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + + j = cd->entry[i].offset + cd->entry[i].comp_size + + cd->entry[i].filename_len + LENTRYSIZE; + if (j > max) + max = j; + if (max > cd->offset) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + + if (fseeko(fp, cd->entry[i].offset, SEEK_SET) != 0) { + _zip_error_set(error, ZIP_ER_SEEK, 0); + return -1; + } + + if (_zip_dirent_read(&temp, fp, NULL, NULL, 1, error) == -1) + return -1; + + if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_dirent_finalize(&temp); + return -1; + } + _zip_dirent_finalize(&temp); + } + + return max - min; +} + + + +/* _zip_check_torrentzip: + check wether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ + +static void +_zip_check_torrentzip(struct zip *za) +{ + uLong crc_got, crc_should; + char buf[8+1]; + char *end; + + if (za->zp == NULL || za->cdir == NULL) + return; + + if (za->cdir->comment_len != TORRENT_SIG_LEN+8 + || strncmp(za->cdir->comment, TORRENT_SIG, TORRENT_SIG_LEN) != 0) + return; + + memcpy(buf, za->cdir->comment+TORRENT_SIG_LEN, 8); + buf[8] = '\0'; + errno = 0; + crc_should = strtoul(buf, &end, 16); + if ((crc_should == UINT_MAX && errno != 0) || (end && *end)) + return; + + if (_zip_filerange_crc(za->zp, za->cdir->offset, za->cdir->size, + &crc_got, NULL) < 0) + return; + + if (crc_got == crc_should) + za->flags |= ZIP_AFL_TORRENT; +} + + + + +/* _zip_headercomp: + compares two headers h1 and h2; if they are local headers, set + local1p or local2p respectively to 1, else 0. Return 0 if they + are identical, -1 if not. */ + +static int +_zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2, + int local2p) +{ + if ((h1->version_needed != h2->version_needed) +#if 0 + /* some zip-files have different values in local + and global headers for the bitflags */ + || (h1->bitflags != h2->bitflags) +#endif + || (h1->comp_method != h2->comp_method) + || (h1->last_mod != h2->last_mod) + || (h1->filename_len != h2->filename_len) + || !h1->filename || !h2->filename + || strcmp(h1->filename, h2->filename)) + return -1; + + /* check that CRC and sizes are zero if data descriptor is used */ + if ((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local1p + && (h1->crc != 0 + || h1->comp_size != 0 + || h1->uncomp_size != 0)) + return -1; + if ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local2p + && (h2->crc != 0 + || h2->comp_size != 0 + || h2->uncomp_size != 0)) + return -1; + + /* check that CRC and sizes are equal if no data descriptor is used */ + if (((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local1p == 0) + && ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local2p == 0)) { + if ((h1->crc != h2->crc) + || (h1->comp_size != h2->comp_size) + || (h1->uncomp_size != h2->uncomp_size)) + return -1; + } + + if ((local1p == local2p) + && ((h1->extrafield_len != h2->extrafield_len) + || (h1->extrafield_len && h2->extrafield + && memcmp(h1->extrafield, h2->extrafield, + h1->extrafield_len)))) + return -1; + + /* if either is local, nothing more to check */ + if (local1p || local2p) + return 0; + + if ((h1->version_madeby != h2->version_madeby) + || (h1->disk_number != h2->disk_number) + || (h1->int_attrib != h2->int_attrib) + || (h1->ext_attrib != h2->ext_attrib) + || (h1->offset != h2->offset) + || (h1->comment_len != h2->comment_len) + || (h1->comment_len && h2->comment + && memcmp(h1->comment, h2->comment, h1->comment_len))) + return -1; + + return 0; +} + + + +static struct zip * +#ifdef _UNICODE +_zip_allocate_new(const wchar_t *fn, int *zep) +#else +_zip_allocate_new(const char *fn, int *zep) +#endif +{ + struct zip *za; + struct zip_error error; + + if ((za=_zip_new(&error)) == NULL) { + set_error(zep, &error, 0); + return NULL; + } + +#ifdef UNICODE + za->zn = _wcsdup(fn); +#else + za->zn = strdup(fn); +#endif + if (!za->zn) { + _zip_free(za); + set_error(zep, NULL, ZIP_ER_MEMORY); + return NULL; + } + return za; +} + + + +static int +#ifdef UNICODE +_zip_file_exists(const wchar_t *fn, int flags, int *zep) +#else +_zip_file_exists(const char *fn, int flags, int *zep) +#endif +{ +#ifdef UNICODE + struct _stat st; +#else + struct stat st; +#endif + if (fn == NULL) { + set_error(zep, NULL, ZIP_ER_INVAL); + return -1; + } + +#ifdef UNICODE + if (_wstat(fn, &st) != 0) { +#else + if (stat(fn, &st) != 0) { +#endif + if (flags & ZIP_CREATE) + return 0; + else { + set_error(zep, NULL, ZIP_ER_OPEN); + return -1; + } + } + else if ((flags & ZIP_EXCL)) { + set_error(zep, NULL, ZIP_ER_EXISTS); + return -1; + } + /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, + just like open() */ + + return 1; +} + + + +static struct zip_cdir * +_zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) +{ + struct zip_cdir *cdir, *cdirnew; + unsigned char *buf, *match; + int a, best, buflen, i; + struct zip_error zerr; + + i = fseeko(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END); + if (i == -1 && errno != EFBIG) { + /* seek before start of file on my machine */ + set_error(zep, NULL, ZIP_ER_SEEK); + return NULL; + } + + /* 64k is too much for stack */ + if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) { + set_error(zep, NULL, ZIP_ER_MEMORY); + return NULL; + } + + clearerr(fp); + buflen = (int)fread(buf, 1, CDBUFSIZE, fp); + + if (ferror(fp)) { + set_error(zep, NULL, ZIP_ER_READ); + free(buf); + return NULL; + } + + best = -1; + cdir = NULL; + match = buf; + _zip_error_set(&zerr, ZIP_ER_NOZIP, 0); + + while ((match=_zip_memmem(match, buflen-(match-buf)-18, + (const unsigned char *)EOCD_MAGIC, 4))!=NULL) { + /* found match -- check, if good */ + /* to avoid finding the same match all over again */ + match++; + if ((cdirnew=_zip_readcdir(fp, buf, match-1, buflen, flags, + &zerr)) == NULL) + continue; + + if (cdir) { + if (best <= 0) + best = _zip_checkcons(fp, cdir, &zerr); + a = _zip_checkcons(fp, cdirnew, &zerr); + if (best < a) { + _zip_cdir_free(cdir); + cdir = cdirnew; + best = a; + } + else + _zip_cdir_free(cdirnew); + } + else { + cdir = cdirnew; + if (flags & ZIP_CHECKCONS) + best = _zip_checkcons(fp, cdir, &zerr); + else + best = 0; + } + cdirnew = NULL; + } + + free(buf); + + if (best < 0) { + set_error(zep, &zerr, 0); + _zip_cdir_free(cdir); + return NULL; + } + + return cdir; +} + + + +static unsigned char * +_zip_memmem(const unsigned char *big, int biglen, const unsigned char *little, + int littlelen) +{ + const unsigned char *p; + + if ((biglen < littlelen) || (littlelen == 0)) + return NULL; + p = big-1; + while ((p=(const unsigned char *) + memchr(p+1, little[0], (size_t)(big-(p+1)+biglen-littlelen+1))) + != NULL) { + if (memcmp(p+1, little+1, littlelen-1)==0) + return (unsigned char *)p; + } + + return NULL; +} diff --git a/ext/native/ext/libzip/zip_rename.c b/ext/native/ext/libzip/zip_rename.c new file mode 100644 index 0000000000..1d056bbe37 --- /dev/null +++ b/ext/native/ext/libzip/zip_rename.c @@ -0,0 +1,65 @@ +/* + zip_rename.c -- rename file in zip archive + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_rename(struct zip *za, int idx, const char *name) +{ + const char *old_name; + int old_is_dir, new_is_dir; + + if (idx >= za->nentry || idx < 0 || name[0] == '\0') { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((old_name=zip_get_name(za, idx, 0)) == NULL) + return -1; + + new_is_dir = (name[strlen(name)-1] == '/'); + old_is_dir = (old_name[strlen(old_name)-1] == '/'); + + if (new_is_dir != old_is_dir) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + return _zip_set_name(za, idx, name); +} diff --git a/ext/native/ext/libzip/zip_replace.c b/ext/native/ext/libzip/zip_replace.c new file mode 100644 index 0000000000..6cdb80c503 --- /dev/null +++ b/ext/native/ext/libzip/zip_replace.c @@ -0,0 +1,78 @@ +/* + zip_replace.c -- replace file via callback function + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_replace(struct zip *za, int idx, struct zip_source *source) +{ + if (idx < 0 || idx >= za->nentry || source == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_replace(za, idx, NULL, source) == -1) + return -1; + + return 0; +} + + + + +int +_zip_replace(struct zip *za, int idx, const char *name, + struct zip_source *source) +{ + if (idx == -1) { + if (_zip_entry_new(za) == NULL) + return -1; + + idx = za->nentry - 1; + } + + _zip_unchange_data(za->entry+idx); + + if (name && _zip_set_name(za, idx, name) != 0) + return -1; + + za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry) + ? ZIP_ST_ADDED : ZIP_ST_REPLACED); + za->entry[idx].source = source; + + return idx; +} diff --git a/ext/native/ext/libzip/zip_set_archive_comment.c b/ext/native/ext/libzip/zip_set_archive_comment.c new file mode 100644 index 0000000000..343fa5491c --- /dev/null +++ b/ext/native/ext/libzip/zip_set_archive_comment.c @@ -0,0 +1,65 @@ +/* + zip_set_archive_comment.c -- set archive comment + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_set_archive_comment(struct zip *za, const char *comment, int len) +{ + char *tmpcom; + + if (len < 0 || len > MAXCOMLEN + || (len > 0 && comment == NULL)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (len > 0) { + if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) + return -1; + } + else + tmpcom = NULL; + + free(za->ch_comment); + za->ch_comment = tmpcom; + za->ch_comment_len = len; + + return 0; +} diff --git a/ext/native/ext/libzip/zip_set_archive_flag.c b/ext/native/ext/libzip/zip_set_archive_flag.c new file mode 100644 index 0000000000..720e1f3508 --- /dev/null +++ b/ext/native/ext/libzip/zip_set_archive_flag.c @@ -0,0 +1,49 @@ +/* + zip_get_archive_flag.c -- set archive global flag + Copyright (C) 2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_set_archive_flag(struct zip *za, int flag, int value) +{ + if (value) + za->ch_flags |= flag; + else + za->ch_flags &= ~flag; + + return 0; +} diff --git a/ext/native/ext/libzip/zip_set_file_comment.c b/ext/native/ext/libzip/zip_set_file_comment.c new file mode 100644 index 0000000000..bc1938e1df --- /dev/null +++ b/ext/native/ext/libzip/zip_set_file_comment.c @@ -0,0 +1,66 @@ +/* + zip_set_file_comment.c -- set comment for file in archive + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_set_file_comment(struct zip *za, int idx, const char *comment, int len) +{ + char *tmpcom; + + if (idx < 0 || idx >= za->nentry + || len < 0 || len > MAXCOMLEN + || (len > 0 && comment == NULL)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (len > 0) { + if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) + return -1; + } + else + tmpcom = NULL; + + free(za->entry[idx].ch_comment); + za->entry[idx].ch_comment = tmpcom; + za->entry[idx].ch_comment_len = len; + + return 0; +} diff --git a/ext/native/ext/libzip/zip_set_name.c b/ext/native/ext/libzip/zip_set_name.c new file mode 100644 index 0000000000..65b60a65cb --- /dev/null +++ b/ext/native/ext/libzip/zip_set_name.c @@ -0,0 +1,78 @@ +/* + zip_set_name.c -- rename helper function + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include + +#include "zipint.h" + + + +int +_zip_set_name(struct zip *za, int idx, const char *name) +{ + char *s; + int i; + + if (idx < 0 || idx >= za->nentry || name == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) { + _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); + return -1; + } + + /* no effective name change */ + if (i == idx) + return 0; + + if ((s=strdup(name)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + + if (za->entry[idx].state == ZIP_ST_UNCHANGED) + za->entry[idx].state = ZIP_ST_RENAMED; + + free(za->entry[idx].ch_filename); + za->entry[idx].ch_filename = s; + + return 0; +} diff --git a/ext/native/ext/libzip/zip_source_buffer.c b/ext/native/ext/libzip/zip_source_buffer.c new file mode 100644 index 0000000000..1f24a1642e --- /dev/null +++ b/ext/native/ext/libzip/zip_source_buffer.c @@ -0,0 +1,157 @@ +/* + zip_source_buffer.c -- create zip data source from buffer + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + +struct read_data { + const char *buf, *data, *end; + time_t mtime; + int freep; +}; + +static ssize_t read_data(void *state, void *data, size_t len, + enum zip_source_cmd cmd); + + + +ZIP_EXTERN struct zip_source * +zip_source_buffer(struct zip *za, const void *data, off_t len, int freep) +{ + struct read_data *f; + struct zip_source *zs; + + if (za == NULL) + return NULL; + + if (len < 0 || (data == NULL && len > 0)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((f=(struct read_data *)malloc(sizeof(*f))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + f->data = (const char *)data; + f->end = ((const char *)data)+len; + f->freep = freep; + f->mtime = time(NULL); + + if ((zs=zip_source_function(za, read_data, f)) == NULL) { + free(f); + return NULL; + } + + return zs; +} + + + +static ssize_t +read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) +{ + struct read_data *z; + char *buf; + size_t n; + + z = (struct read_data *)state; + buf = (char *)data; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + z->buf = z->data; + return 0; + + case ZIP_SOURCE_READ: + n = z->end - z->buf; + if (n > len) + n = len; + + if (n) { + memcpy(buf, z->buf, n); + z->buf += n; + } + + return n; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: + { + struct zip_stat *st; + + if (len < sizeof(*st)) + return -1; + + st = (struct zip_stat *)data; + + zip_stat_init(st); + st->mtime = z->mtime; + st->size = (off_t)(z->end - z->data); + + return sizeof(*st); + } + + case ZIP_SOURCE_ERROR: + { + int *e; + + if (len < sizeof(int)*2) + return -1; + + e = (int *)data; + e[0] = e[1] = 0; + } + return sizeof(int)*2; + + case ZIP_SOURCE_FREE: + if (z->freep) { + free((void *)z->data); + z->data = NULL; + } + free(z); + return 0; + + default: + ; + } + + return -1; +} diff --git a/ext/native/ext/libzip/zip_source_file.c b/ext/native/ext/libzip/zip_source_file.c new file mode 100644 index 0000000000..eb1129a275 --- /dev/null +++ b/ext/native/ext/libzip/zip_source_file.c @@ -0,0 +1,55 @@ +/* + zip_source_file.c -- create data source from file + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN struct zip_source * +zip_source_file(struct zip *za, const char *fname, off_t start, off_t len) +{ + if (za == NULL) + return NULL; + + if (fname == NULL || start < 0 || len < -1) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + return _zip_source_file_or_p(za, fname, NULL, start, len); +} diff --git a/ext/native/ext/libzip/zip_source_filep.c b/ext/native/ext/libzip/zip_source_filep.c new file mode 100644 index 0000000000..e81a9df193 --- /dev/null +++ b/ext/native/ext/libzip/zip_source_filep.c @@ -0,0 +1,220 @@ +/* + zip_source_filep.c -- create data source from FILE * + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include +#include +#include +#include + +#include "zipint.h" + +struct read_file { + char *fname; /* name of file to copy from */ + FILE *f; /* file to copy from */ + off_t off; /* start offset of */ + off_t len; /* lengt of data to copy */ + off_t remain; /* bytes remaining to be copied */ + int e[2]; /* error codes */ +}; + +static ssize_t read_file(void *state, void *data, size_t len, + enum zip_source_cmd cmd); + + + +ZIP_EXTERN struct zip_source * +zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len) +{ + if (za == NULL) + return NULL; + + if (file == NULL || start < 0 || len < -1) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + return _zip_source_file_or_p(za, NULL, file, start, len); +} + + + +struct zip_source * +_zip_source_file_or_p(struct zip *za, const char *fname, FILE *file, + off_t start, off_t len) +{ + struct read_file *f; + struct zip_source *zs; + + if (file == NULL && fname == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((f=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + f->fname = NULL; + if (fname) { + if ((f->fname=strdup(fname)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + free(f); + return NULL; + } + } + f->f = file; + f->off = start; + f->len = (len ? len : -1); + + if ((zs=zip_source_function(za, read_file, f)) == NULL) { + free(f); + return NULL; + } + + return zs; +} + + + +static ssize_t +read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd) +{ + struct read_file *z; + char *buf; + ssize_t i; + size_t n; + + z = (struct read_file *)state; + buf = (char *)data; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + if (z->fname) { + if ((z->f=fopen(z->fname, "rb")) == NULL) { + z->e[0] = ZIP_ER_OPEN; + z->e[1] = errno; + return -1; + } + } + + if (fseeko(z->f, z->off, SEEK_SET) < 0) { + z->e[0] = ZIP_ER_SEEK; + z->e[1] = errno; + return -1; + } + z->remain = z->len; + return 0; + + case ZIP_SOURCE_READ: + if (z->remain != -1) + n = len > z->remain ? z->remain : len; + else + n = len; + + if ((i=fread(buf, 1, n, z->f)) < 0) { + z->e[0] = ZIP_ER_READ; + z->e[1] = errno; + return -1; + } + + if (z->remain != -1) + z->remain -= (off_t)i; + + return i; + + case ZIP_SOURCE_CLOSE: + if (z->fname) { + fclose(z->f); + z->f = NULL; + } + return 0; + + case ZIP_SOURCE_STAT: + { + struct zip_stat *st; + struct stat fst; + int err; + + if (len < sizeof(*st)) + return -1; + + if (z->f) + err = fstat(fileno(z->f), &fst); + else + err = stat(z->fname, &fst); + + if (err != 0) { + z->e[0] = ZIP_ER_READ; /* best match */ + z->e[1] = errno; + return -1; + } + + st = (struct zip_stat *)data; + + zip_stat_init(st); + st->mtime = fst.st_mtime; + if (z->len != -1) + st->size = z->len; + else if ((fst.st_mode&S_IFMT) == S_IFREG) + st->size = fst.st_size; + + return sizeof(*st); + } + + case ZIP_SOURCE_ERROR: + if (len < sizeof(int)*2) + return -1; + + memcpy(data, z->e, sizeof(int)*2); + return sizeof(int)*2; + + case ZIP_SOURCE_FREE: + free(z->fname); + if (z->f) + fclose(z->f); + free(z); + return 0; + + default: + ; + } + + return -1; +} diff --git a/ext/native/ext/libzip/zip_source_free.c b/ext/native/ext/libzip/zip_source_free.c new file mode 100644 index 0000000000..7a1632fbf9 --- /dev/null +++ b/ext/native/ext/libzip/zip_source_free.c @@ -0,0 +1,51 @@ +/* + zip_source_free.c -- free zip data source + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN void +zip_source_free(struct zip_source *source) +{ + if (source == NULL) + return; + + (void)source->f(source->ud, NULL, 0, ZIP_SOURCE_FREE); + + free(source); +} diff --git a/ext/native/ext/libzip/zip_source_function.c b/ext/native/ext/libzip/zip_source_function.c new file mode 100644 index 0000000000..91b183cb6f --- /dev/null +++ b/ext/native/ext/libzip/zip_source_function.c @@ -0,0 +1,59 @@ +/* + zip_source_function.c -- create zip data source from callback function + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN struct zip_source * +zip_source_function(struct zip *za, zip_source_callback zcb, void *ud) +{ + struct zip_source *zs; + + if (za == NULL) + return NULL; + + if ((zs=(struct zip_source *)malloc(sizeof(*zs))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + zs->f = zcb; + zs->ud = ud; + + return zs; +} diff --git a/ext/native/ext/libzip/zip_source_zip.c b/ext/native/ext/libzip/zip_source_zip.c new file mode 100644 index 0000000000..e2e128e0f6 --- /dev/null +++ b/ext/native/ext/libzip/zip_source_zip.c @@ -0,0 +1,191 @@ +/* + zip_source_zip.c -- create data source from zip file + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#endif + +#include +#include + +#include "zipint.h" + +struct read_zip { + struct zip_file *zf; + struct zip_stat st; + off_t off, len; +}; + +static ssize_t read_zip(void *st, void *data, size_t len, + enum zip_source_cmd cmd); + + + +ZIP_EXTERN struct zip_source * +zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, + off_t start, off_t len) +{ + struct zip_error error; + struct zip_source *zs; + struct read_zip *p; + + /* XXX: ZIP_FL_RECOMPRESS */ + + if (za == NULL) + return NULL; + + if (srcza == NULL || start < 0 || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx)) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return NULL; + } + + if (len == 0) + len = -1; + + if (start == 0 && len == -1 && (flags & ZIP_FL_RECOMPRESS) == 0) + flags |= ZIP_FL_COMPRESSED; + else + flags &= ~ZIP_FL_COMPRESSED; + + if ((p=(struct read_zip *)malloc(sizeof(*p))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + _zip_error_copy(&error, &srcza->error); + + if (zip_stat_index(srcza, srcidx, flags, &p->st) < 0 + || (p->zf=zip_fopen_index(srcza, srcidx, flags)) == NULL) { + free(p); + _zip_error_copy(&za->error, &srcza->error); + _zip_error_copy(&srcza->error, &error); + + return NULL; + } + p->off = start; + p->len = len; + + if ((flags & ZIP_FL_COMPRESSED) == 0) { + p->st.size = p->st.comp_size = len; + p->st.comp_method = ZIP_CM_STORE; + p->st.crc = 0; + } + + if ((zs=zip_source_function(za, read_zip, p)) == NULL) { + free(p); + return NULL; + } + + return zs; +} + + + +static ssize_t +read_zip(void *state, void *data, size_t len, enum zip_source_cmd cmd) +{ + struct read_zip *z; + char b[8192], *buf; + ssize_t i, n; + + z = (struct read_zip *)state; + buf = (char *)data; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + for (n=0; noff; n+= i) { + i = (z->off-n > sizeof(b) ? sizeof(b) : z->off-n); + if ((i=zip_fread(z->zf, b, i)) < 0) { + zip_fclose(z->zf); + z->zf = NULL; + return -1; + } + } + return 0; + + case ZIP_SOURCE_READ: + if (z->len != -1) + n = len > z->len ? z->len : len; + else + n = len; + + + if ((i=zip_fread(z->zf, buf, n)) < 0) + return -1; + + if (z->len != -1) + z->len -= i; + + return i; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: + if (len < sizeof(z->st)) + return -1; + len = sizeof(z->st); + + memcpy(data, &z->st, len); + return len; + + case ZIP_SOURCE_ERROR: + { + int *e; + + if (len < sizeof(int)*2) + return -1; + + e = (int *)data; + zip_file_error_get(z->zf, e, e+1); + } + return sizeof(int)*2; + + case ZIP_SOURCE_FREE: + zip_fclose(z->zf); + free(z); + return 0; + + default: + ; + } + + return -1; +} diff --git a/ext/native/ext/libzip/zip_stat.c b/ext/native/ext/libzip/zip_stat.c new file mode 100644 index 0000000000..df1c0b50b9 --- /dev/null +++ b/ext/native/ext/libzip/zip_stat.c @@ -0,0 +1,49 @@ +/* + zip_stat.c -- get information about file by name + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_stat(struct zip *za, const char *fname, int flags, struct zip_stat *st) +{ + int idx; + + if ((idx=zip_name_locate(za, fname, flags)) < 0) + return -1; + + return zip_stat_index(za, idx, flags, st); +} diff --git a/ext/native/ext/libzip/zip_stat_index.c b/ext/native/ext/libzip/zip_stat_index.c new file mode 100644 index 0000000000..60558e432b --- /dev/null +++ b/ext/native/ext/libzip/zip_stat_index.c @@ -0,0 +1,90 @@ +/* + zip_stat_index.c -- get information about file by index + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st) +{ + const char *name; + + if (index < 0 || index >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((name=zip_get_name(za, index, flags)) == NULL) + return -1; + + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && ZIP_ENTRY_DATA_CHANGED(za->entry+index)) { + if (za->entry[index].source->f(za->entry[index].source->ud, + st, sizeof(*st), ZIP_SOURCE_STAT) < 0) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return -1; + } + } + else { + if (za->cdir == NULL || index >= za->cdir->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + st->crc = za->cdir->entry[index].crc; + st->size = za->cdir->entry[index].uncomp_size; + st->mtime = za->cdir->entry[index].last_mod; + st->comp_size = za->cdir->entry[index].comp_size; + st->comp_method = za->cdir->entry[index].comp_method; + if (za->cdir->entry[index].bitflags & ZIP_GPBF_ENCRYPTED) { + if (za->cdir->entry[index].bitflags & ZIP_GPBF_STRONG_ENCRYPTION) { + /* XXX */ + st->encryption_method = ZIP_EM_UNKNOWN; + } + else + st->encryption_method = ZIP_EM_TRAD_PKWARE; + } + else + st->encryption_method = ZIP_EM_NONE; + /* st->bitflags = za->cdir->entry[index].bitflags; */ + } + + st->index = index; + st->name = name; + + return 0; +} diff --git a/ext/native/ext/libzip/zip_stat_init.c b/ext/native/ext/libzip/zip_stat_init.c new file mode 100644 index 0000000000..133ad304aa --- /dev/null +++ b/ext/native/ext/libzip/zip_stat_init.c @@ -0,0 +1,51 @@ +/* + zip_stat_init.c -- initialize struct zip_stat. + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN void +zip_stat_init(struct zip_stat *st) +{ + st->name = NULL; + st->index = -1; + st->crc = 0; + st->mtime = (time_t)-1; + st->size = -1; + st->comp_size = -1; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; +} diff --git a/ext/native/ext/libzip/zip_strerror.c b/ext/native/ext/libzip/zip_strerror.c new file mode 100644 index 0000000000..9ebee144f9 --- /dev/null +++ b/ext/native/ext/libzip/zip_strerror.c @@ -0,0 +1,44 @@ +/* + zip_sterror.c -- get string representation of zip error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN const char * +zip_strerror(struct zip *za) +{ + return _zip_error_strerror(&za->error); +} diff --git a/ext/native/ext/libzip/zip_unchange.c b/ext/native/ext/libzip/zip_unchange.c new file mode 100644 index 0000000000..ed0d4de65b --- /dev/null +++ b/ext/native/ext/libzip/zip_unchange.c @@ -0,0 +1,82 @@ +/* + zip_unchange.c -- undo changes to file in zip archive + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_unchange(struct zip *za, int idx) +{ + return _zip_unchange(za, idx, 0); +} + + + +int +_zip_unchange(struct zip *za, int idx, int allow_duplicates) +{ + int i; + + if (idx < 0 || idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (za->entry[idx].ch_filename) { + if (!allow_duplicates) { + i = _zip_name_locate(za, + _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), + 0, NULL); + if (i != -1 && i != idx) { + _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); + return -1; + } + } + + free(za->entry[idx].ch_filename); + za->entry[idx].ch_filename = NULL; + } + + free(za->entry[idx].ch_comment); + za->entry[idx].ch_comment = NULL; + za->entry[idx].ch_comment_len = -1; + + _zip_unchange_data(za->entry+idx); + + return 0; +} diff --git a/ext/native/ext/libzip/zip_unchange_all.c b/ext/native/ext/libzip/zip_unchange_all.c new file mode 100644 index 0000000000..54a7a0d2e1 --- /dev/null +++ b/ext/native/ext/libzip/zip_unchange_all.c @@ -0,0 +1,54 @@ +/* + zip_unchange.c -- undo changes to all files in zip archive + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_unchange_all(struct zip *za) +{ + int ret, i; + + ret = 0; + for (i=0; inentry; i++) + ret |= _zip_unchange(za, i, 1); + + ret |= zip_unchange_archive(za); + + return ret; +} diff --git a/ext/native/ext/libzip/zip_unchange_archive.c b/ext/native/ext/libzip/zip_unchange_archive.c new file mode 100644 index 0000000000..8f9c024c36 --- /dev/null +++ b/ext/native/ext/libzip/zip_unchange_archive.c @@ -0,0 +1,52 @@ +/* + zip_unchange_archive.c -- undo global changes to ZIP archive + Copyright (C) 2006-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + + + +ZIP_EXTERN int +zip_unchange_archive(struct zip *za) +{ + free(za->ch_comment); + za->ch_comment = NULL; + za->ch_comment_len = -1; + + za->ch_flags = za->flags; + + return 0; +} diff --git a/ext/native/ext/libzip/zip_unchange_data.c b/ext/native/ext/libzip/zip_unchange_data.c new file mode 100644 index 0000000000..6fe89f4fb2 --- /dev/null +++ b/ext/native/ext/libzip/zip_unchange_data.c @@ -0,0 +1,53 @@ +/* + $NiH: zip_unchange_data.c,v 1.14 2004/11/30 23:02:47 wiz Exp $ + + zip_unchange_data.c -- undo helper function + Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "zipint.h" + +void +_zip_unchange_data(struct zip_entry *ze) +{ + if (ze->source) { + (void)ze->source->f(ze->source->ud, NULL, 0, ZIP_SOURCE_FREE); + free(ze->source); + ze->source = NULL; + } + + ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED; +} + diff --git a/ext/native/ext/libzip/zipint.h b/ext/native/ext/libzip/zipint.h new file mode 100644 index 0000000000..26e9b73280 --- /dev/null +++ b/ext/native/ext/libzip/zipint.h @@ -0,0 +1,284 @@ +#ifndef _HAD_ZIPINT_H +#define _HAD_ZIPINT_H + +/* + zipint.h -- internal declarations. + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + 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 the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 + +#ifdef _MSC_VER +#define ZIP_EXTERN +#define fseeko fseek +#define ftello ftell +#if _MSC_VER < 1900 +#define snprintf _snprintf +#endif +#ifndef strcasecmp +#define strcasecmp _stricmp +#endif +#define umask(x) 0; +#define chmod(...) ; +typedef int mode_t; +// __declspec(dllimport) +#endif + +#include "zip.h" +#include "config.h" + +#ifndef HAVE_MKSTEMP +#ifdef UNICODE +int _zip_mkstemp(wchar_t *); +#else +int _zip_mkstemp(char *); +#endif +#define mkstemp _zip_mkstemp +#endif + +#ifdef HAVE_MOVEFILEEXA +#include +#define _zip_rename(s, t) \ + (!MoveFileEx((s), (t), \ + MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING)) +#else +#define _zip_rename rename +#endif + +#ifndef HAVE_FSEEKO +#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) +#endif +#ifndef HAVE_FTELLO +#define ftello(s) ((long)ftell((s))) +#endif + + + +#define CENTRAL_MAGIC "PK\1\2" +#define LOCAL_MAGIC "PK\3\4" +#define EOCD_MAGIC "PK\5\6" +#define DATADES_MAGIC "PK\7\8" +#define TORRENT_SIG "TORRENTZIPPED-" +#define TORRENT_SIG_LEN 14 +#define TORRENT_CRC_LEN 8 +#define TORRENT_MEM_LEVEL 8 +#define CDENTRYSIZE 46u +#define LENTRYSIZE 30 +#define MAXCOMLEN 65536 +#define EOCDLEN 22 +#define CDBUFSIZE (MAXCOMLEN+EOCDLEN) +#define BUFSIZE 8192 + + + +/* state of change of a file in zip archive */ + +enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED, + ZIP_ST_ADDED, ZIP_ST_RENAMED }; + +/* constants for struct zip_file's member flags */ + +#define ZIP_ZF_EOF 1 /* EOF reached */ +#define ZIP_ZF_DECOMP 2 /* decompress data */ +#define ZIP_ZF_CRC 4 /* compute and compare CRC */ + +/* directory entry: general purpose bit flags */ + +#define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */ +#define ZIP_GPBF_DATA_DESCRIPTOR 0x0008 /* crc/size after file data */ +#define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */ + +/* error information */ + +struct zip_error { + int zip_err; /* libzip error code (ZIP_ER_*) */ + int sys_err; /* copy of errno (E*) or zlib error code */ + char *str; /* string representation or NULL */ +}; + +/* zip archive, part of API */ + +struct zip { +#ifdef UNICODE + wchar_t *zn; /* file name */ +#else + char *zn; /* file name */ +#endif + FILE *zp; /* file */ + struct zip_error error; /* error information */ + + unsigned int flags; /* archive global flags */ + unsigned int ch_flags; /* changed archive global flags */ + + struct zip_cdir *cdir; /* central directory */ + char *ch_comment; /* changed archive comment */ + int ch_comment_len; /* length of changed zip archive + * comment, -1 if unchanged */ + int nentry; /* number of entries */ + int nentry_alloc; /* number of entries allocated */ + struct zip_entry *entry; /* entries */ + int nfile; /* number of opened files within archive */ + int nfile_alloc; /* number of files allocated */ + struct zip_file **file; /* opened files within archive */ +}; + +/* file in zip archive, part of API */ + +struct zip_file { + struct zip *za; /* zip archive containing this file */ + struct zip_error error; /* error information */ + int flags; /* -1: eof, >0: error */ + + int method; /* compression method */ + off_t fpos; /* position within zip file (fread/fwrite) */ + unsigned long bytes_left; /* number of bytes left to read */ + unsigned long cbytes_left; /* number of bytes of compressed data left */ + + unsigned long crc; /* CRC so far */ + unsigned long crc_orig; /* CRC recorded in archive */ + + char *buffer; + z_stream *zstr; +}; + +/* zip archive directory entry (central or local) */ + +struct zip_dirent { + unsigned short version_madeby; /* (c) version of creator */ + unsigned short version_needed; /* (cl) version needed to extract */ + unsigned short bitflags; /* (cl) general purpose bit flag */ + unsigned short comp_method; /* (cl) compression method used */ + time_t last_mod; /* (cl) time of last modification */ + unsigned int crc; /* (cl) CRC-32 of uncompressed data */ + unsigned int comp_size; /* (cl) size of commpressed data */ + unsigned int uncomp_size; /* (cl) size of uncommpressed data */ + char *filename; /* (cl) file name (NUL-terminated) */ + unsigned short filename_len; /* (cl) length of filename (w/o NUL) */ + char *extrafield; /* (cl) extra field */ + unsigned short extrafield_len; /* (cl) length of extra field */ + char *comment; /* (c) file comment */ + unsigned short comment_len; /* (c) length of file comment */ + unsigned short disk_number; /* (c) disk number start */ + unsigned short int_attrib; /* (c) internal file attributes */ + unsigned int ext_attrib; /* (c) external file attributes */ + unsigned int offset; /* (c) offset of local header */ +}; + +/* zip archive central directory */ + +struct zip_cdir { + struct zip_dirent *entry; /* directory entries */ + int nentry; /* number of entries */ + + unsigned int size; /* size of central direcotry */ + unsigned int offset; /* offset of central directory in file */ + char *comment; /* zip archive comment */ + unsigned short comment_len; /* length of zip archive comment */ +}; + + + +struct zip_source { + zip_source_callback f; + void *ud; +}; + +/* entry in zip archive directory */ + +struct zip_entry { + enum zip_state state; + struct zip_source *source; + char *ch_filename; + char *ch_comment; + int ch_comment_len; +}; + + + +extern const char * const _zip_err_str[]; +extern const int _zip_nerr_str; +extern const int _zip_err_type[]; + + + +#define ZIP_ENTRY_DATA_CHANGED(x) \ + ((x)->state == ZIP_ST_REPLACED \ + || (x)->state == ZIP_ST_ADDED) + + + +int _zip_cdir_compute_crc(struct zip *, uLong *); +void _zip_cdir_free(struct zip_cdir *); +int _zip_cdir_grow(struct zip_cdir *, int, struct zip_error *); +struct zip_cdir *_zip_cdir_new(int, struct zip_error *); +int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *); + +void _zip_dirent_finalize(struct zip_dirent *); +void _zip_dirent_init(struct zip_dirent *); +int _zip_dirent_read(struct zip_dirent *, FILE *, unsigned char **, + unsigned int *, int, struct zip_error *); +void _zip_dirent_torrent_normalize(struct zip_dirent *); +int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); + +void _zip_entry_free(struct zip_entry *); +void _zip_entry_init(struct zip *, int); +struct zip_entry *_zip_entry_new(struct zip *); + +void _zip_error_clear(struct zip_error *); +void _zip_error_copy(struct zip_error *, struct zip_error *); +void _zip_error_fini(struct zip_error *); +void _zip_error_get(struct zip_error *, int *, int *); +void _zip_error_init(struct zip_error *); +void _zip_error_set(struct zip_error *, int, int); +const char *_zip_error_strerror(struct zip_error *); + +int _zip_file_fillbuf(void *, size_t, struct zip_file *); +unsigned int _zip_file_get_offset(struct zip *, int); + +int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *); + +struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *, + off_t, off_t); + +void _zip_free(struct zip *); +const char *_zip_get_name(struct zip *, int, int, struct zip_error *); +int _zip_local_header_read(struct zip *, int); +void *_zip_memdup(const void *, size_t, struct zip_error *); +int _zip_name_locate(struct zip *, const char *, int, struct zip_error *); +struct zip *_zip_new(struct zip_error *); +unsigned short _zip_read2(unsigned char **); +unsigned int _zip_read4(unsigned char **); +int _zip_replace(struct zip *, int, const char *, struct zip_source *); +int _zip_set_name(struct zip *, int, const char *); +int _zip_unchange(struct zip *, int, int); +void _zip_unchange_data(struct zip_entry *); + +#endif /* zipint.h */ diff --git a/ext/native/ext/rapidxml/license.txt b/ext/native/ext/rapidxml/license.txt new file mode 100644 index 0000000000..140983180b --- /dev/null +++ b/ext/native/ext/rapidxml/license.txt @@ -0,0 +1,52 @@ +Use of this software is granted under one of the following two licenses, +to be chosen freely by the user. + +1. Boost Software License - Version 1.0 - August 17th, 2003 +=============================================================================== + +Copyright (c) 2006, 2007 Marcin Kalicinski + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +2. The MIT License +=============================================================================== + +Copyright (c) 2006, 2007 Marcin Kalicinski + +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/ext/native/ext/rapidxml/manual.html b/ext/native/ext/rapidxml/manual.html new file mode 100644 index 0000000000..2c422703f4 --- /dev/null +++ b/ext/native/ext/rapidxml/manual.html @@ -0,0 +1,406 @@ +

RAPIDXML Manual

Version 1.13

Copyright (C) 2006, 2009 Marcin Kalicinski
See accompanying file license.txt for license information.

Table of Contents

1. What is RapidXml?
1.1 Dependencies And Compatibility
1.2 Character Types And Encodings
1.3 Error Handling
1.4 Memory Allocation
1.5 W3C Compliance
1.6 API Design
1.7 Reliability
1.8 Acknowledgements
2. Two Minute Tutorial
2.1 Parsing
2.2 Accessing The DOM Tree
2.3 Modifying The DOM Tree
2.4 Printing XML
3. Differences From Regular XML Parsers
3.1 Lifetime Of Source Text
3.2 Ownership Of Strings
3.3 Destructive Vs Non-Destructive Mode
4. Performance
4.1 Comparison With Other Parsers
5. Reference

1. What is RapidXml?

RapidXml is an attempt to create the fastest XML DOM parser possible, while retaining useability, portability and reasonable W3C compatibility. It is an in-situ parser written in C++, with parsing speed approaching that of strlen() function executed on the same data.

+ Entire parser is contained in a single header file, so no building or linking is neccesary. To use it you just need to copy rapidxml.hpp file to a convenient place (such as your project directory), and include it where needed. You may also want to use printing functions contained in header rapidxml_print.hpp.

1.1 Dependencies And Compatibility

RapidXml has no dependencies other than a very small subset of standard C++ library (<cassert>, <cstdlib>, <new> and <exception>, unless exceptions are disabled). It should compile on any reasonably conformant compiler, and was tested on Visual C++ 2003, Visual C++ 2005, Visual C++ 2008, gcc 3, gcc 4, and Comeau 4.3.3. Care was taken that no warnings are produced on these compilers, even with highest warning levels enabled.

1.2 Character Types And Encodings

RapidXml is character type agnostic, and can work both with narrow and wide characters. Current version does not fully support UTF-16 or UTF-32, so use of wide characters is somewhat incapacitated. However, it should succesfully parse wchar_t strings containing UTF-16 or UTF-32 if endianness of the data matches that of the machine. UTF-8 is fully supported, including all numeric character references, which are expanded into appropriate UTF-8 byte sequences (unless you enable parse_no_utf8 flag).

+ Note that RapidXml performs no decoding - strings returned by name() and value() functions will contain text encoded using the same encoding as source file. Rapidxml understands and expands the following character references: &apos; &amp; &quot; &lt; &gt; &#...; Other character references are not expanded.

1.3 Error Handling

By default, RapidXml uses C++ exceptions to report errors. If this behaviour is undesirable, RAPIDXML_NO_EXCEPTIONS can be defined to suppress exception code. See parse_error class and parse_error_handler() function for more information.

1.4 Memory Allocation

RapidXml uses a special memory pool object to allocate nodes and attributes, because direct allocation using new operator would be far too slow. Underlying memory allocations performed by the pool can be customized by use of memory_pool::set_allocator() function. See class memory_pool for more information.

1.5 W3C Compliance

RapidXml is not a W3C compliant parser, primarily because it ignores DOCTYPE declarations. There is a number of other, minor incompatibilities as well. Still, it can successfully parse and produce complete trees of all valid XML files in W3C conformance suite (over 1000 files specially designed to find flaws in XML processors). In destructive mode it performs whitespace normalization and character entity substitution for a small set of built-in entities.

1.6 API Design

RapidXml API is minimalistic, to reduce code size as much as possible, and facilitate use in embedded environments. Additional convenience functions are provided in separate headers: rapidxml_utils.hpp and rapidxml_print.hpp. Contents of these headers is not an essential part of the library, and is currently not documented (otherwise than with comments in code).

1.7 Reliability

RapidXml is very robust and comes with a large harness of unit tests. Special care has been taken to ensure stability of the parser no matter what source text is thrown at it. One of the unit tests produces 100,000 randomly corrupted variants of XML document, which (when uncorrupted) contains all constructs recognized by RapidXml. RapidXml passes this test when it correctly recognizes that errors have been introduced, and does not crash or loop indefinitely.

+ Another unit test puts RapidXml head-to-head with another, well estabilished XML parser, and verifies that their outputs match across a wide variety of small and large documents.

+ Yet another test feeds RapidXml with over 1000 test files from W3C compliance suite, and verifies that correct results are obtained. There are also additional tests that verify each API function separately, and test that various parsing modes work as expected.

1.8 Acknowledgements

I would like to thank Arseny Kapoulkine for his work on pugixml, which was an inspiration for this project. Additional thanks go to Kristen Wegner for creating pugxml, from which pugixml was derived. Janusz Wohlfeil kindly ran RapidXml speed tests on hardware that I did not have access to, allowing me to expand performance comparison table.

2. Two Minute Tutorial

2.1 Parsing

The following code causes RapidXml to parse a zero-terminated string named text:
using namespace rapidxml;
+xml_document<> doc;    // character type defaults to char
+doc.parse<0>(text);    // 0 means default parse flags
+
doc object is now a root of DOM tree containing representation of the parsed XML. Because all RapidXml interface is contained inside namespace rapidxml, users must either bring contents of this namespace into scope, or fully qualify all the names. Class xml_document represents a root of the DOM hierarchy. By means of public inheritance, it is also an xml_node and a memory_pool. Template parameter of xml_document::parse() function is used to specify parsing flags, with which you can fine-tune behaviour of the parser. Note that flags must be a compile-time constant.

2.2 Accessing The DOM Tree

To access the DOM tree, use methods of xml_node and xml_attribute classes:
cout << "Name of my first node is: " << doc.first_node()->name() << "\n";
+xml_node<> *node = doc.first_node("foobar");
+cout << "Node foobar has value " << node->value() << "\n";
+for (xml_attribute<> *attr = node->first_attribute();
+     attr; attr = attr->next_attribute())
+{
+    cout << "Node foobar has attribute " << attr->name() << " ";
+    cout << "with value " << attr->value() << "\n";
+}
+

2.3 Modifying The DOM Tree

DOM tree produced by the parser is fully modifiable. Nodes and attributes can be added/removed, and their contents changed. The below example creates a HTML document, whose sole contents is a link to google.com website:
xml_document<> doc;
+xml_node<> *node = doc.allocate_node(node_element, "a", "Google");
+doc.append_node(node);
+xml_attribute<> *attr = doc.allocate_attribute("href", "google.com");
+node->append_attribute(attr);
+
One quirk is that nodes and attributes do not own the text of their names and values. This is because normally they only store pointers to the source text. So, when assigning a new name or value to the node, care must be taken to ensure proper lifetime of the string. The easiest way to achieve it is to allocate the string from the xml_document memory pool. In the above example this is not necessary, because we are only assigning character constants. But the code below uses memory_pool::allocate_string() function to allocate node name (which will have the same lifetime as the document), and assigns it to a new node:
xml_document<> doc;
+char *node_name = doc.allocate_string(name);        // Allocate string and copy name into it
+xml_node<> *node = doc.allocate_node(node_element, node_name);  // Set node name to node_name
+
Check Reference section for description of the entire interface.

2.4 Printing XML

You can print xml_document and xml_node objects into an XML string. Use print() function or operator <<, which are defined in rapidxml_print.hpp header.
using namespace rapidxml;
+xml_document<> doc;    // character type defaults to char
+// ... some code to fill the document
+
+// Print to stream using operator <<
+std::cout << doc;   
+
+// Print to stream using print function, specifying printing flags
+print(std::cout, doc, 0);   // 0 means default printing flags
+
+// Print to string using output iterator
+std::string s;
+print(std::back_inserter(s), doc, 0);
+
+// Print to memory buffer using output iterator
+char buffer[4096];                      // You are responsible for making the buffer large enough!
+char *end = print(buffer, doc, 0);      // end contains pointer to character after last printed character
+*end = 0;                               // Add string terminator after XML
+

3. Differences From Regular XML Parsers

RapidXml is an in-situ parser, which allows it to achieve very high parsing speed. In-situ means that parser does not make copies of strings. Instead, it places pointers to the source text in the DOM hierarchy.

3.1 Lifetime Of Source Text

In-situ parsing requires that source text lives at least as long as the document object. If source text is destroyed, names and values of nodes in DOM tree will become destroyed as well. Additionally, whitespace processing, character entity translation, and zero-termination of strings require that source text be modified during parsing (but see non-destructive mode). This makes the text useless for further processing once it was parsed by RapidXml.

+ In many cases however, these are not serious issues.

3.2 Ownership Of Strings

Nodes and attributes produced by RapidXml do not own their name and value strings. They merely hold the pointers to them. This means you have to be careful when setting these values manually, by using xml_base::name(const Ch *) or xml_base::value(const Ch *) functions. Care must be taken to ensure that lifetime of the string passed is at least as long as lifetime of the node/attribute. The easiest way to achieve it is to allocate the string from memory_pool owned by the document. Use memory_pool::allocate_string() function for this purpose.

3.3 Destructive Vs Non-Destructive Mode

By default, the parser modifies source text during the parsing process. This is required to achieve character entity translation, whitespace normalization, and zero-termination of strings.

+ In some cases this behaviour may be undesirable, for example if source text resides in read only memory, or is mapped to memory directly from file. By using appropriate parser flags (parse_non_destructive), source text modifications can be disabled. However, because RapidXml does in-situ parsing, it obviously has the following side-effects:

4. Performance

RapidXml achieves its speed through use of several techniques:
  • In-situ parsing. When building DOM tree, RapidXml does not make copies of string data, such as node names and values. Instead, it stores pointers to interior of the source text.
  • Use of template metaprogramming techniques. This allows it to move much of the work to compile time. Through magic of the templates, C++ compiler generates a separate copy of parsing code for any combination of parser flags you use. In each copy, all possible decisions are made at compile time and all unused code is omitted.
  • Extensive use of lookup tables for parsing.
  • Hand-tuned C++ with profiling done on several most popular CPUs.
This results in a very small and fast code: a parser which is custom tailored to exact needs with each invocation.

4.1 Comparison With Other Parsers

The table below compares speed of RapidXml to some other parsers, and to strlen() function executed on the same data. On a modern CPU (as of 2007), you can expect parsing throughput to be close to 1 GB/s. As a rule of thumb, parsing speed is about 50-100x faster than Xerces DOM, 30-60x faster than TinyXml, 3-12x faster than pugxml, and about 5% - 30% faster than pugixml, the fastest XML parser I know of.
  • The test file is a real-world, 50kB large, moderately dense XML file.
  • All timing is done by using RDTSC instruction present in Pentium-compatible CPUs.
  • No profile-guided optimizations are used.
  • All parsers are running in their fastest modes.
  • The results are given in CPU cycles per character, so frequency of CPUs is irrelevant.
  • The results are minimum values from a large number of runs, to minimize effects of operating system activity, task switching, interrupt handling etc.
  • A single parse of the test file takes about 1/10th of a millisecond, so with large number of runs there is a good chance of hitting at least one no-interrupt streak, and obtaining undisturbed results.
Platform
Compiler
strlen() RapidXml pugixml 0.3 pugxml TinyXml
Pentium 4
MSVC 8.0
2.5
5.4
7.0
61.7
298.8
Pentium 4
gcc 4.1.1
0.8
6.1
9.5
67.0
413.2
Core 2
MSVC 8.0
1.0
4.5
5.0
24.6
154.8
Core 2
gcc 4.1.1
0.6
4.6
5.4
28.3
229.3
Athlon XP
MSVC 8.0
3.1
7.7
8.0
25.5
182.6
Athlon XP
gcc 4.1.1
0.9
8.2
9.2
33.7
265.2
Pentium 3
MSVC 8.0
2.0
6.3
7.0
30.9
211.9
Pentium 3
gcc 4.1.1
1.0
6.7
8.9
35.3
316.0
(*) All results are in CPU cycles per character of source text

5. Reference

This section lists all classes, functions, constants etc. and describes them in detail.
class + template + rapidxml::memory_pool
+ constructor + memory_pool()
+ destructor + ~memory_pool()
function allocate_node(node_type type, const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
function allocate_attribute(const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
function allocate_string(const Ch *source=0, std::size_t size=0)
function clone_node(const xml_node< Ch > *source, xml_node< Ch > *result=0)
function clear()
function set_allocator(alloc_func *af, free_func *ff)

class rapidxml::parse_error
+ constructor + parse_error(const char *what, void *where)
function what() const
function where() const

class + template + rapidxml::xml_attribute
+ constructor + xml_attribute()
function document() const
function previous_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
function next_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const

class + template + rapidxml::xml_base
+ constructor + xml_base()
function name() const
function name_size() const
function value() const
function value_size() const
function name(const Ch *name, std::size_t size)
function name(const Ch *name)
function value(const Ch *value, std::size_t size)
function value(const Ch *value)
function parent() const

class + template + rapidxml::xml_document
+ constructor + xml_document()
function parse(Ch *text)
function clear()

class + template + rapidxml::xml_node
+ constructor + xml_node(node_type type)
function type() const
function document() const
function first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
function last_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
function previous_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
function next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
function first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
function last_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
function type(node_type type)
function prepend_node(xml_node< Ch > *child)
function append_node(xml_node< Ch > *child)
function insert_node(xml_node< Ch > *where, xml_node< Ch > *child)
function remove_first_node()
function remove_last_node()
function remove_node(xml_node< Ch > *where)
function remove_all_nodes()
function prepend_attribute(xml_attribute< Ch > *attribute)
function append_attribute(xml_attribute< Ch > *attribute)
function insert_attribute(xml_attribute< Ch > *where, xml_attribute< Ch > *attribute)
function remove_first_attribute()
function remove_last_attribute()
function remove_attribute(xml_attribute< Ch > *where)
function remove_all_attributes()

namespace rapidxml
enum node_type
function parse_error_handler(const char *what, void *where)
function print(OutIt out, const xml_node< Ch > &node, int flags=0)
function print(std::basic_ostream< Ch > &out, const xml_node< Ch > &node, int flags=0)
function operator<<(std::basic_ostream< Ch > &out, const xml_node< Ch > &node)
+ constant + parse_no_data_nodes
+ constant + parse_no_element_values
+ constant + parse_no_string_terminators
+ constant + parse_no_entity_translation
+ constant + parse_no_utf8
+ constant + parse_declaration_node
+ constant + parse_comment_nodes
+ constant + parse_doctype_node
+ constant + parse_pi_nodes
+ constant + parse_validate_closing_tags
+ constant + parse_trim_whitespace
+ constant + parse_normalize_whitespace
+ constant + parse_default
+ constant + parse_non_destructive
+ constant + parse_fastest
+ constant + parse_full
+ constant + print_no_indenting


class + template + rapidxml::memory_pool

+ + Defined in rapidxml.hpp
+ Base class for + xml_document

Description

This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation. In most cases, you will not need to use this class directly. However, if you need to create nodes manually or modify names/values of nodes, you are encouraged to use memory_pool of relevant xml_document to allocate the memory. Not only is this faster than allocating them by using new operator, but also their lifetime will be tied to the lifetime of document, possibly simplyfing memory management.

+ Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. You can also call allocate_string() function to allocate strings. Such strings can then be used as names or values of nodes without worrying about their lifetime. Note that there is no free() function -- all allocations are freed at once when clear() function is called, or when the pool is destroyed.

+ It is also possible to create a standalone memory_pool, and use it to allocate nodes, whose lifetime will not be tied to any document.

+ Pool maintains RAPIDXML_STATIC_POOL_SIZE bytes of statically allocated memory. Until static memory is exhausted, no dynamic memory allocations are done. When static memory is exhausted, pool allocates additional blocks of memory of size RAPIDXML_DYNAMIC_POOL_SIZE each, by using global new[] and delete[] operators. This behaviour can be changed by setting custom allocation routines. Use set_allocator() function to set them.

+ Allocations for nodes, attributes and strings are aligned at RAPIDXML_ALIGNMENT bytes. This value defaults to the size of pointer on target architecture.

+ To obtain absolutely top performance from the parser, it is important that all nodes are allocated from a single, contiguous block of memory. Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably. If required, you can tweak RAPIDXML_STATIC_POOL_SIZE, RAPIDXML_DYNAMIC_POOL_SIZE and RAPIDXML_ALIGNMENT to obtain best wasted memory to performance compromise. To do it, define their values before rapidxml.hpp file is included.

Parameters

Ch
Character type of created nodes.

+ constructor + memory_pool::memory_pool

Synopsis

memory_pool(); +

Description

Constructs empty pool with default allocator functions.

+ destructor + memory_pool::~memory_pool

Synopsis

~memory_pool(); +

Description

Destroys pool and frees all the memory. This causes memory occupied by nodes allocated by the pool to be freed. Nodes allocated from the pool are no longer valid.

function memory_pool::allocate_node

Synopsis

xml_node<Ch>* allocate_node(node_type type, const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0); +

Description

Allocates a new node from the pool, and optionally assigns name and value to it. If the allocation request cannot be accomodated, this function will throw std::bad_alloc. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function.

Parameters

type
Type of node to create.
name
Name to assign to the node, or 0 to assign no name.
value
Value to assign to the node, or 0 to assign no value.
name_size
Size of name to assign, or 0 to automatically calculate size from name string.
value_size
Size of value to assign, or 0 to automatically calculate size from value string.

Returns

Pointer to allocated node. This pointer will never be NULL.

function memory_pool::allocate_attribute

Synopsis

xml_attribute<Ch>* allocate_attribute(const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0); +

Description

Allocates a new attribute from the pool, and optionally assigns name and value to it. If the allocation request cannot be accomodated, this function will throw std::bad_alloc. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function.

Parameters

name
Name to assign to the attribute, or 0 to assign no name.
value
Value to assign to the attribute, or 0 to assign no value.
name_size
Size of name to assign, or 0 to automatically calculate size from name string.
value_size
Size of value to assign, or 0 to automatically calculate size from value string.

Returns

Pointer to allocated attribute. This pointer will never be NULL.

function memory_pool::allocate_string

Synopsis

Ch* allocate_string(const Ch *source=0, std::size_t size=0); +

Description

Allocates a char array of given size from the pool, and optionally copies a given string to it. If the allocation request cannot be accomodated, this function will throw std::bad_alloc. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function.

Parameters

source
String to initialize the allocated memory with, or 0 to not initialize it.
size
Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated.

Returns

Pointer to allocated char array. This pointer will never be NULL.

function memory_pool::clone_node

Synopsis

xml_node<Ch>* clone_node(const xml_node< Ch > *source, xml_node< Ch > *result=0); +

Description

Clones an xml_node and its hierarchy of child nodes and attributes. Nodes and attributes are allocated from this memory pool. Names and values are not cloned, they are shared between the clone and the source. Result node can be optionally specified as a second parameter, in which case its contents will be replaced with cloned source node. This is useful when you want to clone entire document.

Parameters

source
Node to clone.
result
Node to put results in, or 0 to automatically allocate result node

Returns

Pointer to cloned node. This pointer will never be NULL.

function memory_pool::clear

Synopsis

void clear(); +

Description

Clears the pool. This causes memory occupied by nodes allocated by the pool to be freed. Any nodes or strings allocated from the pool will no longer be valid.

function memory_pool::set_allocator

Synopsis

void set_allocator(alloc_func *af, free_func *ff); +

Description

Sets or resets the user-defined memory allocation functions for the pool. This can only be called when no memory is allocated from the pool yet, otherwise results are undefined. Allocation function must not return invalid pointer on failure. It should either throw, stop the program, or use longjmp() function to pass control to other place of program. If it returns invalid pointer, results are undefined.

+ User defined allocation functions must have the following forms:

+void *allocate(std::size_t size);
+void free(void *pointer);

Parameters

af
Allocation function, or 0 to restore default function
ff
Free function, or 0 to restore default function

class rapidxml::parse_error

+ + Defined in rapidxml.hpp

Description

Parse error exception. This exception is thrown by the parser when an error occurs. Use what() function to get human-readable error message. Use where() function to get a pointer to position within source text where error was detected.

+ If throwing exceptions by the parser is undesirable, it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included. This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception. This function must be defined by the user.

+ This class derives from std::exception class.

+ constructor + parse_error::parse_error

Synopsis

parse_error(const char *what, void *where); +

Description

Constructs parse error.

function parse_error::what

Synopsis

virtual const char* what() const; +

Description

Gets human readable description of error.

Returns

Pointer to null terminated description of the error.

function parse_error::where

Synopsis

Ch* where() const; +

Description

Gets pointer to character data where error happened. Ch should be the same as char type of xml_document that produced the error.

Returns

Pointer to location within the parsed string where error occured.

class + template + rapidxml::xml_attribute

+ + Defined in rapidxml.hpp
+ Inherits from + xml_base

Description

Class representing attribute node of XML document. Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base). Note that after parse, both name and value of attribute will point to interior of source text used for parsing. Thus, this text must persist in memory for the lifetime of attribute.

Parameters

Ch
Character type to use.

+ constructor + xml_attribute::xml_attribute

Synopsis

xml_attribute(); +

Description

Constructs an empty attribute with the specified type. Consider using memory_pool of appropriate xml_document if allocating attributes manually.

function xml_attribute::document

Synopsis

xml_document<Ch>* document() const; +

Description

Gets document of which attribute is a child.

Returns

Pointer to document that contains this attribute, or 0 if there is no parent document.

function xml_attribute::previous_attribute

Synopsis

xml_attribute<Ch>* previous_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; +

Description

Gets previous attribute, optionally matching attribute name.

Parameters

name
Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
name_size
Size of name, in characters, or 0 to have size calculated automatically from string
case_sensitive
Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters

Returns

Pointer to found attribute, or 0 if not found.

function xml_attribute::next_attribute

Synopsis

xml_attribute<Ch>* next_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; +

Description

Gets next attribute, optionally matching attribute name.

Parameters

name
Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
name_size
Size of name, in characters, or 0 to have size calculated automatically from string
case_sensitive
Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters

Returns

Pointer to found attribute, or 0 if not found.

class + template + rapidxml::xml_base

+ + Defined in rapidxml.hpp
+ Base class for + xml_attribute xml_node

Description

Base class for xml_node and xml_attribute implementing common functions: name(), name_size(), value(), value_size() and parent().

Parameters

Ch
Character type to use

+ constructor + xml_base::xml_base

Synopsis

xml_base(); +

function xml_base::name

Synopsis

Ch* name() const; +

Description

Gets name of the node. Interpretation of name depends on type of node. Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.

+ Use name_size() function to determine length of the name.

Returns

Name of node, or empty string if node has no name.

function xml_base::name_size

Synopsis

std::size_t name_size() const; +

Description

Gets size of node name, not including terminator character. This function works correctly irrespective of whether name is or is not zero terminated.

Returns

Size of node name, in characters.

function xml_base::value

Synopsis

Ch* value() const; +

Description

Gets value of node. Interpretation of value depends on type of node. Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.

+ Use value_size() function to determine length of the value.

Returns

Value of node, or empty string if node has no value.

function xml_base::value_size

Synopsis

std::size_t value_size() const; +

Description

Gets size of node value, not including terminator character. This function works correctly irrespective of whether value is or is not zero terminated.

Returns

Size of node value, in characters.

function xml_base::name

Synopsis

void name(const Ch *name, std::size_t size); +

Description

Sets name of node to a non zero-terminated string. See Ownership Of Strings .

+ Note that node does not own its name or value, it only stores a pointer to it. It will not delete or otherwise free the pointer on destruction. It is reponsibility of the user to properly manage lifetime of the string. The easiest way to achieve it is to use memory_pool of the document to allocate the string - on destruction of the document the string will be automatically freed.

+ Size of name must be specified separately, because name does not have to be zero terminated. Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated).

Parameters

name
Name of node to set. Does not have to be zero terminated.
size
Size of name, in characters. This does not include zero terminator, if one is present.

function xml_base::name

Synopsis

void name(const Ch *name); +

Description

Sets name of node to a zero-terminated string. See also Ownership Of Strings and xml_node::name(const Ch *, std::size_t).

Parameters

name
Name of node to set. Must be zero terminated.

function xml_base::value

Synopsis

void value(const Ch *value, std::size_t size); +

Description

Sets value of node to a non zero-terminated string. See Ownership Of Strings .

+ Note that node does not own its name or value, it only stores a pointer to it. It will not delete or otherwise free the pointer on destruction. It is reponsibility of the user to properly manage lifetime of the string. The easiest way to achieve it is to use memory_pool of the document to allocate the string - on destruction of the document the string will be automatically freed.

+ Size of value must be specified separately, because it does not have to be zero terminated. Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated).

+ If an element has a child node of type node_data, it will take precedence over element value when printing. If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser.

Parameters

value
value of node to set. Does not have to be zero terminated.
size
Size of value, in characters. This does not include zero terminator, if one is present.

function xml_base::value

Synopsis

void value(const Ch *value); +

Description

Sets value of node to a zero-terminated string. See also Ownership Of Strings and xml_node::value(const Ch *, std::size_t).

Parameters

value
Vame of node to set. Must be zero terminated.

function xml_base::parent

Synopsis

xml_node<Ch>* parent() const; +

Description

Gets node parent.

Returns

Pointer to parent node, or 0 if there is no parent.

class + template + rapidxml::xml_document

+ + Defined in rapidxml.hpp
+ Inherits from + xml_node memory_pool

Description

This class represents root of the DOM hierarchy. It is also an xml_node and a memory_pool through public inheritance. Use parse() function to build a DOM tree from a zero-terminated XML text string. parse() function allocates memory for nodes and attributes by using functions of xml_document, which are inherited from memory_pool. To access root node of the document, use the document itself, as if it was an xml_node.

Parameters

Ch
Character type to use.

+ constructor + xml_document::xml_document

Synopsis

xml_document(); +

Description

Constructs empty XML document.

function xml_document::parse

Synopsis

void parse(Ch *text); +

Description

Parses zero-terminated XML string according to given flags. Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used. The string must persist for the lifetime of the document. In case of error, rapidxml::parse_error exception will be thrown.

+ If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning. Make sure that data is zero-terminated.

+ Document can be parsed into multiple times. Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool.

Parameters

text
XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser.

function xml_document::clear

Synopsis

void clear(); +

Description

Clears the document by deleting all nodes and clearing the memory pool. All nodes owned by document pool are destroyed.

class + template + rapidxml::xml_node

+ + Defined in rapidxml.hpp
+ Inherits from + xml_base
+ Base class for + xml_document

Description

Class representing a node of XML document. Each node may have associated name and value strings, which are available through name() and value() functions. Interpretation of name and value depends on type of the node. Type of node can be determined by using type() function.

+ Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. Thus, this text must persist in the memory for the lifetime of node.

Parameters

Ch
Character type to use.

+ constructor + xml_node::xml_node

Synopsis

xml_node(node_type type); +

Description

Constructs an empty node with the specified type. Consider using memory_pool of appropriate document to allocate nodes manually.

Parameters

type
Type of node to construct.

function xml_node::type

Synopsis

node_type type() const; +

Description

Gets type of node.

Returns

Type of node.

function xml_node::document

Synopsis

xml_document<Ch>* document() const; +

Description

Gets document of which node is a child.

Returns

Pointer to document that contains this node, or 0 if there is no parent document.

function xml_node::first_node

Synopsis

xml_node<Ch>* first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; +

Description

Gets first child node, optionally matching node name.

Parameters

name
Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
name_size
Size of name, in characters, or 0 to have size calculated automatically from string
case_sensitive
Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters

Returns

Pointer to found child, or 0 if not found.

function xml_node::last_node

Synopsis

xml_node<Ch>* last_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; +

Description

Gets last child node, optionally matching node name. Behaviour is undefined if node has no children. Use first_node() to test if node has children.

Parameters

name
Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
name_size
Size of name, in characters, or 0 to have size calculated automatically from string
case_sensitive
Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters

Returns

Pointer to found child, or 0 if not found.

function xml_node::previous_sibling

Synopsis

xml_node<Ch>* previous_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; +

Description

Gets previous sibling node, optionally matching node name. Behaviour is undefined if node has no parent. Use parent() to test if node has a parent.

Parameters

name
Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
name_size
Size of name, in characters, or 0 to have size calculated automatically from string
case_sensitive
Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters

Returns

Pointer to found sibling, or 0 if not found.

function xml_node::next_sibling

Synopsis

xml_node<Ch>* next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; +

Description

Gets next sibling node, optionally matching node name. Behaviour is undefined if node has no parent. Use parent() to test if node has a parent.

Parameters

name
Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
name_size
Size of name, in characters, or 0 to have size calculated automatically from string
case_sensitive
Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters

Returns

Pointer to found sibling, or 0 if not found.

function xml_node::first_attribute

Synopsis

xml_attribute<Ch>* first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; +

Description

Gets first attribute of node, optionally matching attribute name.

Parameters

name
Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
name_size
Size of name, in characters, or 0 to have size calculated automatically from string
case_sensitive
Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters

Returns

Pointer to found attribute, or 0 if not found.

function xml_node::last_attribute

Synopsis

xml_attribute<Ch>* last_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; +

Description

Gets last attribute of node, optionally matching attribute name.

Parameters

name
Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
name_size
Size of name, in characters, or 0 to have size calculated automatically from string
case_sensitive
Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters

Returns

Pointer to found attribute, or 0 if not found.

function xml_node::type

Synopsis

void type(node_type type); +

Description

Sets type of node.

Parameters

type
Type of node to set.

function xml_node::prepend_node

Synopsis

void prepend_node(xml_node< Ch > *child); +

Description

Prepends a new child node. The prepended child becomes the first child, and all existing children are moved one position back.

Parameters

child
Node to prepend.

function xml_node::append_node

Synopsis

void append_node(xml_node< Ch > *child); +

Description

Appends a new child node. The appended child becomes the last child.

Parameters

child
Node to append.

function xml_node::insert_node

Synopsis

void insert_node(xml_node< Ch > *where, xml_node< Ch > *child); +

Description

Inserts a new child node at specified place inside the node. All children after and including the specified node are moved one position back.

Parameters

where
Place where to insert the child, or 0 to insert at the back.
child
Node to insert.

function xml_node::remove_first_node

Synopsis

void remove_first_node(); +

Description

Removes first child node. If node has no children, behaviour is undefined. Use first_node() to test if node has children.

function xml_node::remove_last_node

Synopsis

void remove_last_node(); +

Description

Removes last child of the node. If node has no children, behaviour is undefined. Use first_node() to test if node has children.

function xml_node::remove_node

Synopsis

void remove_node(xml_node< Ch > *where); +

Description

Removes specified child from the node.

function xml_node::remove_all_nodes

Synopsis

void remove_all_nodes(); +

Description

Removes all child nodes (but not attributes).

function xml_node::prepend_attribute

Synopsis

void prepend_attribute(xml_attribute< Ch > *attribute); +

Description

Prepends a new attribute to the node.

Parameters

attribute
Attribute to prepend.

function xml_node::append_attribute

Synopsis

void append_attribute(xml_attribute< Ch > *attribute); +

Description

Appends a new attribute to the node.

Parameters

attribute
Attribute to append.

function xml_node::insert_attribute

Synopsis

void insert_attribute(xml_attribute< Ch > *where, xml_attribute< Ch > *attribute); +

Description

Inserts a new attribute at specified place inside the node. All attributes after and including the specified attribute are moved one position back.

Parameters

where
Place where to insert the attribute, or 0 to insert at the back.
attribute
Attribute to insert.

function xml_node::remove_first_attribute

Synopsis

void remove_first_attribute(); +

Description

Removes first attribute of the node. If node has no attributes, behaviour is undefined. Use first_attribute() to test if node has attributes.

function xml_node::remove_last_attribute

Synopsis

void remove_last_attribute(); +

Description

Removes last attribute of the node. If node has no attributes, behaviour is undefined. Use first_attribute() to test if node has attributes.

function xml_node::remove_attribute

Synopsis

void remove_attribute(xml_attribute< Ch > *where); +

Description

Removes specified attribute from node.

Parameters

where
Pointer to attribute to be removed.

function xml_node::remove_all_attributes

Synopsis

void remove_all_attributes(); +

Description

Removes all attributes of node.

enum node_type

Description

Enumeration listing all node types produced by the parser. Use xml_node::type() function to query node type.

Values

node_document
A document node. Name and value are empty.
node_element
An element node. Name contains element name. Value contains text of first data node.
node_data
A data node. Name is empty. Value contains data text.
node_cdata
A CDATA node. Name is empty. Value contains data text.
node_comment
A comment node. Name is empty. Value contains comment text.
node_declaration
A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes.
node_doctype
A DOCTYPE node. Name is empty. Value contains DOCTYPE text.
node_pi
A PI node. Name contains target. Value contains instructions.

function parse_error_handler

Synopsis

void rapidxml::parse_error_handler(const char *what, void *where); +

Description

When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function is called to notify user about the error. It must be defined by the user.

+ This function cannot return. If it does, the results are undefined.

+ A very simple definition might look like that: + void rapidxml::parse_error_handler(const char *what, void *where) + { + std::cout << "Parse error: " << what << "\n"; + std::abort(); + } +

Parameters

what
Human readable description of the error.
where
Pointer to character data where error was detected.

function print

Synopsis

OutIt rapidxml::print(OutIt out, const xml_node< Ch > &node, int flags=0); +

Description

Prints XML to given output iterator.

Parameters

out
Output iterator to print to.
node
Node to be printed. Pass xml_document to print entire document.
flags
Flags controlling how XML is printed.

Returns

Output iterator pointing to position immediately after last character of printed text.

function print

Synopsis

std::basic_ostream<Ch>& rapidxml::print(std::basic_ostream< Ch > &out, const xml_node< Ch > &node, int flags=0); +

Description

Prints XML to given output stream.

Parameters

out
Output stream to print to.
node
Node to be printed. Pass xml_document to print entire document.
flags
Flags controlling how XML is printed.

Returns

Output stream.

function operator<<

Synopsis

std::basic_ostream<Ch>& rapidxml::operator<<(std::basic_ostream< Ch > &out, const xml_node< Ch > &node); +

Description

Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.

Parameters

out
Output stream to print to.
node
Node to be printed.

Returns

Output stream.

+ constant + parse_no_data_nodes

Synopsis

const int parse_no_data_nodes + = 0x1; +

Description

Parse flag instructing the parser to not create data nodes. Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_no_element_values

Synopsis

const int parse_no_element_values + = 0x2; +

Description

Parse flag instructing the parser to not use text of first data node as a value of parent element. Can be combined with other flags by use of | operator. Note that child data nodes of element node take precendence over its value when printing. That is, if element has one or more child data nodes and a value, the value will be ignored. Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements.

+ See xml_document::parse() function.

+ constant + parse_no_string_terminators

Synopsis

const int parse_no_string_terminators + = 0x4; +

Description

Parse flag instructing the parser to not place zero terminators after strings in the source text. By default zero terminators are placed, modifying source text. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_no_entity_translation

Synopsis

const int parse_no_entity_translation + = 0x8; +

Description

Parse flag instructing the parser to not translate entities in the source text. By default entities are translated, modifying source text. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_no_utf8

Synopsis

const int parse_no_utf8 + = 0x10; +

Description

Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters. By default, UTF-8 handling is enabled. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_declaration_node

Synopsis

const int parse_declaration_node + = 0x20; +

Description

Parse flag instructing the parser to create XML declaration node. By default, declaration node is not created. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_comment_nodes

Synopsis

const int parse_comment_nodes + = 0x40; +

Description

Parse flag instructing the parser to create comments nodes. By default, comment nodes are not created. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_doctype_node

Synopsis

const int parse_doctype_node + = 0x80; +

Description

Parse flag instructing the parser to create DOCTYPE node. By default, doctype node is not created. Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_pi_nodes

Synopsis

const int parse_pi_nodes + = 0x100; +

Description

Parse flag instructing the parser to create PI nodes. By default, PI nodes are not created. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_validate_closing_tags

Synopsis

const int parse_validate_closing_tags + = 0x200; +

Description

Parse flag instructing the parser to validate closing tag names. If not set, name inside closing tag is irrelevant to the parser. By default, closing tags are not validated. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_trim_whitespace

Synopsis

const int parse_trim_whitespace + = 0x400; +

Description

Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes. By default, whitespace is not trimmed. This flag does not cause the parser to modify source text. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_normalize_whitespace

Synopsis

const int parse_normalize_whitespace + = 0x800; +

Description

Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character. Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag. By default, whitespace is not normalized. If this flag is specified, source text will be modified. Can be combined with other flags by use of | operator.

+ See xml_document::parse() function.

+ constant + parse_default

Synopsis

const int parse_default + = 0; +

Description

Parse flags which represent default behaviour of the parser. This is always equal to 0, so that all other flags can be simply ored together. Normally there is no need to inconveniently disable flags by anding with their negated (~) values. This also means that meaning of each flag is a negation of the default setting. For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is enabled by default, and using the flag will disable it.

+ See xml_document::parse() function.

+ constant + parse_non_destructive

Synopsis

const int parse_non_destructive + = parse_no_string_terminators | parse_no_entity_translation; +

Description

A combination of parse flags that forbids any modifications of the source text. This also results in faster parsing. However, note that the following will occur:
  • names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends
  • entities will not be translated
  • whitespace will not be normalized
+See xml_document::parse() function.

+ constant + parse_fastest

Synopsis

const int parse_fastest + = parse_non_destructive | parse_no_data_nodes; +

Description

A combination of parse flags resulting in fastest possible parsing, without sacrificing important data.

+ See xml_document::parse() function.

+ constant + parse_full

Synopsis

const int parse_full + = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags; +

Description

A combination of parse flags resulting in largest amount of data being extracted. This usually results in slowest parsing.

+ See xml_document::parse() function.

+ constant + print_no_indenting

Synopsis

const int print_no_indenting + = 0x1; +

Description

Printer flag instructing the printer to suppress indenting of XML. See print() function.

\ No newline at end of file diff --git a/ext/native/ext/rapidxml/rapidxml.hpp b/ext/native/ext/rapidxml/rapidxml.hpp new file mode 100644 index 0000000000..ae91e081d0 --- /dev/null +++ b/ext/native/ext/rapidxml/rapidxml.hpp @@ -0,0 +1,2596 @@ +#ifndef RAPIDXML_HPP_INCLUDED +#define RAPIDXML_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation + +// If standard library is disabled, user must provide implementations of required functions and typedefs +#if !defined(RAPIDXML_NO_STDLIB) + #include // For std::size_t + #include // For assert + #include // For placement new +#endif + +// On MSVC, disable "conditional expression is constant" warning (level 4). +// This warning is almost impossible to avoid with certain types of templated code +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable:4127) // Conditional expression is constant +#endif + +/////////////////////////////////////////////////////////////////////////// +// RAPIDXML_PARSE_ERROR + +#if defined(RAPIDXML_NO_EXCEPTIONS) + +#define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); } + +namespace rapidxml +{ + //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, + //! this function is called to notify user about the error. + //! It must be defined by the user. + //!

+ //! This function cannot return. If it does, the results are undefined. + //!

+ //! A very simple definition might look like that: + //!

+    //! void %rapidxml::%parse_error_handler(const char *what, void *where)
+    //! {
+    //!     std::cout << "Parse error: " << what << "\n";
+    //!     std::abort();
+    //! }
+    //! 
+ //! \param what Human readable description of the error. + //! \param where Pointer to character data where error was detected. + void parse_error_handler(const char *what, void *where); +} + +#else + +#include // For std::exception + +#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where) + +namespace rapidxml +{ + + //! Parse error exception. + //! This exception is thrown by the parser when an error occurs. + //! Use what() function to get human-readable error message. + //! Use where() function to get a pointer to position within source text where error was detected. + //!

+ //! If throwing exceptions by the parser is undesirable, + //! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included. + //! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception. + //! This function must be defined by the user. + //!

+ //! This class derives from std::exception class. + class parse_error: public std::exception + { + + public: + + //! Constructs parse error + parse_error(const char *what, void *where) + : m_what(what) + , m_where(where) + { + } + + //! Gets human readable description of error. + //! \return Pointer to null terminated description of the error. + virtual const char *what() const throw() + { + return m_what; + } + + //! Gets pointer to character data where error happened. + //! Ch should be the same as char type of xml_document that produced the error. + //! \return Pointer to location within the parsed string where error occured. + template + Ch *where() const + { + return reinterpret_cast(m_where); + } + + private: + + const char *m_what; + void *m_where; + + }; +} + +#endif + +/////////////////////////////////////////////////////////////////////////// +// Pool sizes + +#ifndef RAPIDXML_STATIC_POOL_SIZE + // Size of static memory block of memory_pool. + // Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. + // No dynamic memory allocations are performed by memory_pool until static memory is exhausted. + #define RAPIDXML_STATIC_POOL_SIZE (64 * 1024) +#endif + +#ifndef RAPIDXML_DYNAMIC_POOL_SIZE + // Size of dynamic memory block of memory_pool. + // Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. + // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool. + #define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024) +#endif + +#ifndef RAPIDXML_ALIGNMENT + // Memory allocation alignment. + // Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer. + // All memory allocations for nodes, attributes and strings will be aligned to this value. + // This must be a power of 2 and at least 1, otherwise memory_pool will not work. + #define RAPIDXML_ALIGNMENT sizeof(void *) +#endif + +namespace rapidxml +{ + // Forward declarations + template class xml_node; + template class xml_attribute; + template class xml_document; + + //! Enumeration listing all node types produced by the parser. + //! Use xml_node::type() function to query node type. + enum node_type + { + node_document, //!< A document node. Name and value are empty. + node_element, //!< An element node. Name contains element name. Value contains text of first data node. + node_data, //!< A data node. Name is empty. Value contains data text. + node_cdata, //!< A CDATA node. Name is empty. Value contains data text. + node_comment, //!< A comment node. Name is empty. Value contains comment text. + node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes. + node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text. + node_pi //!< A PI node. Name contains target. Value contains instructions. + }; + + /////////////////////////////////////////////////////////////////////// + // Parsing flags + + //! Parse flag instructing the parser to not create data nodes. + //! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_data_nodes = 0x1; + + //! Parse flag instructing the parser to not use text of first data node as a value of parent element. + //! Can be combined with other flags by use of | operator. + //! Note that child data nodes of element node take precendence over its value when printing. + //! That is, if element has one or more child data nodes and a value, the value will be ignored. + //! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements. + //!

+ //! See xml_document::parse() function. + const int parse_no_element_values = 0x2; + + //! Parse flag instructing the parser to not place zero terminators after strings in the source text. + //! By default zero terminators are placed, modifying source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_string_terminators = 0x4; + + //! Parse flag instructing the parser to not translate entities in the source text. + //! By default entities are translated, modifying source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_entity_translation = 0x8; + + //! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters. + //! By default, UTF-8 handling is enabled. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_utf8 = 0x10; + + //! Parse flag instructing the parser to create XML declaration node. + //! By default, declaration node is not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_declaration_node = 0x20; + + //! Parse flag instructing the parser to create comments nodes. + //! By default, comment nodes are not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_comment_nodes = 0x40; + + //! Parse flag instructing the parser to create DOCTYPE node. + //! By default, doctype node is not created. + //! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_doctype_node = 0x80; + + //! Parse flag instructing the parser to create PI nodes. + //! By default, PI nodes are not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_pi_nodes = 0x100; + + //! Parse flag instructing the parser to validate closing tag names. + //! If not set, name inside closing tag is irrelevant to the parser. + //! By default, closing tags are not validated. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_validate_closing_tags = 0x200; + + //! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes. + //! By default, whitespace is not trimmed. + //! This flag does not cause the parser to modify source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_trim_whitespace = 0x400; + + //! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character. + //! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag. + //! By default, whitespace is not normalized. + //! If this flag is specified, source text will be modified. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_normalize_whitespace = 0x800; + + // Compound flags + + //! Parse flags which represent default behaviour of the parser. + //! This is always equal to 0, so that all other flags can be simply ored together. + //! Normally there is no need to inconveniently disable flags by anding with their negated (~) values. + //! This also means that meaning of each flag is a negation of the default setting. + //! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is enabled by default, + //! and using the flag will disable it. + //!

+ //! See xml_document::parse() function. + const int parse_default = 0; + + //! A combination of parse flags that forbids any modifications of the source text. + //! This also results in faster parsing. However, note that the following will occur: + //!
    + //!
  • names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends
  • + //!
  • entities will not be translated
  • + //!
  • whitespace will not be normalized
  • + //!
+ //! See xml_document::parse() function. + const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation; + + //! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data. + //!

+ //! See xml_document::parse() function. + const int parse_fastest = parse_non_destructive | parse_no_data_nodes; + + //! A combination of parse flags resulting in largest amount of data being extracted. + //! This usually results in slowest parsing. + //!

+ //! See xml_document::parse() function. + const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags; + + /////////////////////////////////////////////////////////////////////// + // Internals + + //! \cond internal + namespace internal + { + + // Struct that contains lookup tables for the parser + // It must be a template to allow correct linking (because it has static data members, which are defined in a header file). + template + struct lookup_tables + { + static const unsigned char lookup_whitespace[256]; // Whitespace table + static const unsigned char lookup_node_name[256]; // Node name table + static const unsigned char lookup_text[256]; // Text table + static const unsigned char lookup_text_pure_no_ws[256]; // Text table + static const unsigned char lookup_text_pure_with_ws[256]; // Text table + static const unsigned char lookup_attribute_name[256]; // Attribute name table + static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote + static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote + static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes + static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes + static const unsigned char lookup_digits[256]; // Digits + static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters + }; + + // Find length of the string + template + inline std::size_t measure(const Ch *p) + { + const Ch *tmp = p; + while (*tmp) + ++tmp; + return tmp - p; + } + + // Compare strings for equality + template + inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive) + { + if (size1 != size2) + return false; + if (case_sensitive) + { + for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) + if (*p1 != *p2) + return false; + } + else + { + for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) + if (lookup_tables<0>::lookup_upcase[static_cast(*p1)] != lookup_tables<0>::lookup_upcase[static_cast(*p2)]) + return false; + } + return true; + } + } + //! \endcond + + /////////////////////////////////////////////////////////////////////// + // Memory pool + + //! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation. + //! In most cases, you will not need to use this class directly. + //! However, if you need to create nodes manually or modify names/values of nodes, + //! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. + //! Not only is this faster than allocating them by using new operator, + //! but also their lifetime will be tied to the lifetime of document, + //! possibly simplyfing memory management. + //!

+ //! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. + //! You can also call allocate_string() function to allocate strings. + //! Such strings can then be used as names or values of nodes without worrying about their lifetime. + //! Note that there is no free() function -- all allocations are freed at once when clear() function is called, + //! or when the pool is destroyed. + //!

+ //! It is also possible to create a standalone memory_pool, and use it + //! to allocate nodes, whose lifetime will not be tied to any document. + //!

+ //! Pool maintains RAPIDXML_STATIC_POOL_SIZE bytes of statically allocated memory. + //! Until static memory is exhausted, no dynamic memory allocations are done. + //! When static memory is exhausted, pool allocates additional blocks of memory of size RAPIDXML_DYNAMIC_POOL_SIZE each, + //! by using global new[] and delete[] operators. + //! This behaviour can be changed by setting custom allocation routines. + //! Use set_allocator() function to set them. + //!

+ //! Allocations for nodes, attributes and strings are aligned at RAPIDXML_ALIGNMENT bytes. + //! This value defaults to the size of pointer on target architecture. + //!

+ //! To obtain absolutely top performance from the parser, + //! it is important that all nodes are allocated from a single, contiguous block of memory. + //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably. + //! If required, you can tweak RAPIDXML_STATIC_POOL_SIZE, RAPIDXML_DYNAMIC_POOL_SIZE and RAPIDXML_ALIGNMENT + //! to obtain best wasted memory to performance compromise. + //! To do it, define their values before rapidxml.hpp file is included. + //! \param Ch Character type of created nodes. + template + class memory_pool + { + + public: + + //! \cond internal + typedef void *(alloc_func)(std::size_t); // Type of user-defined function used to allocate memory + typedef void (free_func)(void *); // Type of user-defined function used to free memory + //! \endcond + + //! Constructs empty pool with default allocator functions. + memory_pool() + : m_alloc_func(0) + , m_free_func(0) + { + init(); + } + + //! Destroys pool and frees all the memory. + //! This causes memory occupied by nodes allocated by the pool to be freed. + //! Nodes allocated from the pool are no longer valid. + ~memory_pool() + { + clear(); + } + + //! Allocates a new node from the pool, and optionally assigns name and value to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param type Type of node to create. + //! \param name Name to assign to the node, or 0 to assign no name. + //! \param value Value to assign to the node, or 0 to assign no value. + //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. + //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. + //! \return Pointer to allocated node. This pointer will never be NULL. + xml_node *allocate_node(node_type type, + const Ch *name = 0, const Ch *value = 0, + std::size_t name_size = 0, std::size_t value_size = 0) + { + void *memory = allocate_aligned(sizeof(xml_node)); + xml_node *node = new(memory) xml_node(type); + if (name) + { + if (name_size > 0) + node->name(name, name_size); + else + node->name(name); + } + if (value) + { + if (value_size > 0) + node->value(value, value_size); + else + node->value(value); + } + return node; + } + + //! Allocates a new attribute from the pool, and optionally assigns name and value to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param name Name to assign to the attribute, or 0 to assign no name. + //! \param value Value to assign to the attribute, or 0 to assign no value. + //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. + //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. + //! \return Pointer to allocated attribute. This pointer will never be NULL. + xml_attribute *allocate_attribute(const Ch *name = 0, const Ch *value = 0, + std::size_t name_size = 0, std::size_t value_size = 0) + { + void *memory = allocate_aligned(sizeof(xml_attribute)); + xml_attribute *attribute = new(memory) xml_attribute; + if (name) + { + if (name_size > 0) + attribute->name(name, name_size); + else + attribute->name(name); + } + if (value) + { + if (value_size > 0) + attribute->value(value, value_size); + else + attribute->value(value); + } + return attribute; + } + + //! Allocates a char array of given size from the pool, and optionally copies a given string to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param source String to initialize the allocated memory with, or 0 to not initialize it. + //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated. + //! \return Pointer to allocated char array. This pointer will never be NULL. + Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) + { + assert(source || size); // Either source or size (or both) must be specified + if (size == 0) + size = internal::measure(source) + 1; + Ch *result = static_cast(allocate_aligned(size * sizeof(Ch))); + if (source) + for (std::size_t i = 0; i < size; ++i) + result[i] = source[i]; + return result; + } + + //! Clones an xml_node and its hierarchy of child nodes and attributes. + //! Nodes and attributes are allocated from this memory pool. + //! Names and values are not cloned, they are shared between the clone and the source. + //! Result node can be optionally specified as a second parameter, + //! in which case its contents will be replaced with cloned source node. + //! This is useful when you want to clone entire document. + //! \param source Node to clone. + //! \param result Node to put results in, or 0 to automatically allocate result node + //! \return Pointer to cloned node. This pointer will never be NULL. + xml_node *clone_node(const xml_node *source, xml_node *result = 0) + { + // Prepare result node + if (result) + { + result->remove_all_attributes(); + result->remove_all_nodes(); + result->type(source->type()); + } + else + result = allocate_node(source->type()); + + // Clone name and value + result->name(source->name(), source->name_size()); + result->value(source->value(), source->value_size()); + + // Clone child nodes and attributes + for (xml_node *child = source->first_node(); child; child = child->next_sibling()) + result->append_node(clone_node(child)); + for (xml_attribute *attr = source->first_attribute(); attr; attr = attr->next_attribute()) + result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size())); + + return result; + } + + //! Clears the pool. + //! This causes memory occupied by nodes allocated by the pool to be freed. + //! Any nodes or strings allocated from the pool will no longer be valid. + void clear() + { + while (m_begin != m_static_memory) + { + char *previous_begin = reinterpret_cast
(align(m_begin))->previous_begin; + if (m_free_func) + m_free_func(m_begin); + else + delete[] m_begin; + m_begin = previous_begin; + } + init(); + } + + //! Sets or resets the user-defined memory allocation functions for the pool. + //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined. + //! Allocation function must not return invalid pointer on failure. It should either throw, + //! stop the program, or use longjmp() function to pass control to other place of program. + //! If it returns invalid pointer, results are undefined. + //!

+ //! User defined allocation functions must have the following forms: + //!
+ //!
void *allocate(std::size_t size); + //!
void free(void *pointer); + //!

+ //! \param af Allocation function, or 0 to restore default function + //! \param ff Free function, or 0 to restore default function + void set_allocator(alloc_func *af, free_func *ff) + { + assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet + m_alloc_func = af; + m_free_func = ff; + } + + private: + + struct header + { + char *previous_begin; + }; + + void init() + { + m_begin = m_static_memory; + m_ptr = align(m_begin); + m_end = m_static_memory + sizeof(m_static_memory); + } + + char *align(char *ptr) + { + std::size_t alignment = ((RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1))) & (RAPIDXML_ALIGNMENT - 1)); + return ptr + alignment; + } + + char *allocate_raw(std::size_t size) + { + // Allocate + void *memory; + if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[] + { + memory = m_alloc_func(size); + assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp + } + else + { + memory = new char[size]; +#ifdef RAPIDXML_NO_EXCEPTIONS + if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc + RAPIDXML_PARSE_ERROR("out of memory", 0); +#endif + } + return static_cast(memory); + } + + void *allocate_aligned(std::size_t size) + { + // Calculate aligned pointer + char *result = align(m_ptr); + + // If not enough memory left in current pool, allocate a new pool + if (result + size > m_end) + { + // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE) + std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE; + if (pool_size < size) + pool_size = size; + + // Allocate + std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation + char *raw_memory = allocate_raw(alloc_size); + + // Setup new pool in allocated memory + char *pool = align(raw_memory); + header *new_header = reinterpret_cast
(pool); + new_header->previous_begin = m_begin; + m_begin = raw_memory; + m_ptr = pool + sizeof(header); + m_end = raw_memory + alloc_size; + + // Calculate aligned pointer again using new pool + result = align(m_ptr); + } + + // Update pool and return aligned pointer + m_ptr = result + size; + return result; + } + + char *m_begin; // Start of raw memory making up current pool + char *m_ptr; // First free byte in current pool + char *m_end; // One past last available byte in current pool + char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]; // Static raw memory + alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used + free_func *m_free_func; // Free function, or 0 if default is to be used + }; + + /////////////////////////////////////////////////////////////////////////// + // XML base + + //! Base class for xml_node and xml_attribute implementing common functions: + //! name(), name_size(), value(), value_size() and parent(). + //! \param Ch Character type to use + template + class xml_base + { + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + // Construct a base with empty name, value and parent + xml_base() + : m_name(0) + , m_value(0) + , m_parent(0) + { + } + + /////////////////////////////////////////////////////////////////////////// + // Node data access + + //! Gets name of the node. + //! Interpretation of name depends on type of node. + //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. + //!

+ //! Use name_size() function to determine length of the name. + //! \return Name of node, or empty string if node has no name. + Ch *name() const + { + return m_name ? m_name : nullstr(); + } + + //! Gets size of node name, not including terminator character. + //! This function works correctly irrespective of whether name is or is not zero terminated. + //! \return Size of node name, in characters. + std::size_t name_size() const + { + return m_name ? m_name_size : 0; + } + + //! Gets value of node. + //! Interpretation of value depends on type of node. + //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. + //!

+ //! Use value_size() function to determine length of the value. + //! \return Value of node, or empty string if node has no value. + Ch *value() const + { + return m_value ? m_value : nullstr(); + } + + //! Gets size of node value, not including terminator character. + //! This function works correctly irrespective of whether value is or is not zero terminated. + //! \return Size of node value, in characters. + std::size_t value_size() const + { + return m_value ? m_value_size : 0; + } + + /////////////////////////////////////////////////////////////////////////// + // Node modification + + //! Sets name of node to a non zero-terminated string. + //! See \ref ownership_of_strings. + //!

+ //! Note that node does not own its name or value, it only stores a pointer to it. + //! It will not delete or otherwise free the pointer on destruction. + //! It is reponsibility of the user to properly manage lifetime of the string. + //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - + //! on destruction of the document the string will be automatically freed. + //!

+ //! Size of name must be specified separately, because name does not have to be zero terminated. + //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated). + //! \param name Name of node to set. Does not have to be zero terminated. + //! \param size Size of name, in characters. This does not include zero terminator, if one is present. + void name(const Ch *name, std::size_t size) + { + m_name = const_cast(name); + m_name_size = size; + } + + //! Sets name of node to a zero-terminated string. + //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t). + //! \param name Name of node to set. Must be zero terminated. + void name(const Ch *name) + { + this->name(name, internal::measure(name)); + } + + //! Sets value of node to a non zero-terminated string. + //! See \ref ownership_of_strings. + //!

+ //! Note that node does not own its name or value, it only stores a pointer to it. + //! It will not delete or otherwise free the pointer on destruction. + //! It is reponsibility of the user to properly manage lifetime of the string. + //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - + //! on destruction of the document the string will be automatically freed. + //!

+ //! Size of value must be specified separately, because it does not have to be zero terminated. + //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated). + //!

+ //! If an element has a child node of type node_data, it will take precedence over element value when printing. + //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser. + //! \param value value of node to set. Does not have to be zero terminated. + //! \param size Size of value, in characters. This does not include zero terminator, if one is present. + void value(const Ch *value, std::size_t size) + { + m_value = const_cast(value); + m_value_size = size; + } + + //! Sets value of node to a zero-terminated string. + //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t). + //! \param value Vame of node to set. Must be zero terminated. + void value(const Ch *value) + { + this->value(value, internal::measure(value)); + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets node parent. + //! \return Pointer to parent node, or 0 if there is no parent. + xml_node *parent() const + { + return m_parent; + } + + protected: + + // Return empty string + static Ch *nullstr() + { + static Ch zero = Ch('\0'); + return &zero; + } + + Ch *m_name; // Name of node, or 0 if no name + Ch *m_value; // Value of node, or 0 if no value + std::size_t m_name_size; // Length of node name, or undefined of no name + std::size_t m_value_size; // Length of node value, or undefined if no value + xml_node *m_parent; // Pointer to parent node, or 0 if none + + }; + + //! Class representing attribute node of XML document. + //! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base). + //! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. + //! Thus, this text must persist in memory for the lifetime of attribute. + //! \param Ch Character type to use. + template + class xml_attribute: public xml_base + { + + friend class xml_node; + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + //! Constructs an empty attribute with the specified type. + //! Consider using memory_pool of appropriate xml_document if allocating attributes manually. + xml_attribute() + { + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets document of which attribute is a child. + //! \return Pointer to document that contains this attribute, or 0 if there is no parent document. + xml_document *document() const + { + if (xml_node *node = this->parent()) + { + while (node->parent()) + node = node->parent(); + return node->type() == node_document ? static_cast *>(node) : 0; + } + else + return 0; + } + + //! Gets previous attribute, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return this->m_parent ? m_prev_attribute : 0; + } + + //! Gets next attribute, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return this->m_parent ? m_next_attribute : 0; + } + + private: + + xml_attribute *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero + xml_attribute *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero + + }; + + /////////////////////////////////////////////////////////////////////////// + // XML node + + //! Class representing a node of XML document. + //! Each node may have associated name and value strings, which are available through name() and value() functions. + //! Interpretation of name and value depends on type of the node. + //! Type of node can be determined by using type() function. + //!

+ //! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. + //! Thus, this text must persist in the memory for the lifetime of node. + //! \param Ch Character type to use. + template + class xml_node: public xml_base + { + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + //! Constructs an empty node with the specified type. + //! Consider using memory_pool of appropriate document to allocate nodes manually. + //! \param type Type of node to construct. + xml_node(node_type type) + : m_type(type) + , m_first_node(0) + , m_first_attribute(0) + { + } + + /////////////////////////////////////////////////////////////////////////// + // Node data access + + //! Gets type of node. + //! \return Type of node. + node_type type() const + { + return m_type; + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets document of which node is a child. + //! \return Pointer to document that contains this node, or 0 if there is no parent document. + xml_document *document() const + { + xml_node *node = const_cast *>(this); + while (node->parent()) + node = node->parent(); + return node->type() == node_document ? static_cast *>(node) : 0; + } + + //! Gets first child node, optionally matching node name. + //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found child, or 0 if not found. + xml_node *first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *child = m_first_node; child; child = child->next_sibling()) + if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) + return child; + return 0; + } + else + return m_first_node; + } + + //! Gets last child node, optionally matching node name. + //! Behaviour is undefined if node has no children. + //! Use first_node() to test if node has children. + //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found child, or 0 if not found. + xml_node *last_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + { + assert(m_first_node); // Cannot query for last child if node has no children + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *child = m_last_node; child; child = child->previous_sibling()) + if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) + return child; + return 0; + } + else + return m_last_node; + } + + //! Gets previous sibling node, optionally matching node name. + //! Behaviour is undefined if node has no parent. + //! Use parent() to test if node has a parent. + //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found sibling, or 0 if not found. + xml_node *previous_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + { + assert(this->m_parent); // Cannot query for siblings if node has no parent + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling) + if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) + return sibling; + return 0; + } + else + return m_prev_sibling; + } + + //! Gets next sibling node, optionally matching node name. + //! Behaviour is undefined if node has no parent. + //! Use parent() to test if node has a parent. + //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found sibling, or 0 if not found. + xml_node *next_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + { + assert(this->m_parent); // Cannot query for siblings if node has no parent + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling) + if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) + return sibling; + return 0; + } + else + return m_next_sibling; + } + + //! Gets first attribute of node, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return m_first_attribute; + } + + //! Gets last attribute of node, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return m_first_attribute ? m_last_attribute : 0; + } + + /////////////////////////////////////////////////////////////////////////// + // Node modification + + //! Sets type of node. + //! \param type Type of node to set. + void type(node_type type) + { + m_type = type; + } + + /////////////////////////////////////////////////////////////////////////// + // Node manipulation + + //! Prepends a new child node. + //! The prepended child becomes the first child, and all existing children are moved one position back. + //! \param child Node to prepend. + void prepend_node(xml_node *child) + { + assert(child && !child->parent() && child->type() != node_document); + if (first_node()) + { + child->m_next_sibling = m_first_node; + m_first_node->m_prev_sibling = child; + } + else + { + child->m_next_sibling = 0; + m_last_node = child; + } + m_first_node = child; + child->m_parent = this; + child->m_prev_sibling = 0; + } + + //! Appends a new child node. + //! The appended child becomes the last child. + //! \param child Node to append. + void append_node(xml_node *child) + { + assert(child && !child->parent() && child->type() != node_document); + if (first_node()) + { + child->m_prev_sibling = m_last_node; + m_last_node->m_next_sibling = child; + } + else + { + child->m_prev_sibling = 0; + m_first_node = child; + } + m_last_node = child; + child->m_parent = this; + child->m_next_sibling = 0; + } + + //! Inserts a new child node at specified place inside the node. + //! All children after and including the specified node are moved one position back. + //! \param where Place where to insert the child, or 0 to insert at the back. + //! \param child Node to insert. + void insert_node(xml_node *where, xml_node *child) + { + assert(!where || where->parent() == this); + assert(child && !child->parent() && child->type() != node_document); + if (where == m_first_node) + prepend_node(child); + else if (where == 0) + append_node(child); + else + { + child->m_prev_sibling = where->m_prev_sibling; + child->m_next_sibling = where; + where->m_prev_sibling->m_next_sibling = child; + where->m_prev_sibling = child; + child->m_parent = this; + } + } + + //! Removes first child node. + //! If node has no children, behaviour is undefined. + //! Use first_node() to test if node has children. + void remove_first_node() + { + assert(first_node()); + xml_node *child = m_first_node; + m_first_node = child->m_next_sibling; + if (child->m_next_sibling) + child->m_next_sibling->m_prev_sibling = 0; + else + m_last_node = 0; + child->m_parent = 0; + } + + //! Removes last child of the node. + //! If node has no children, behaviour is undefined. + //! Use first_node() to test if node has children. + void remove_last_node() + { + assert(first_node()); + xml_node *child = m_last_node; + if (child->m_prev_sibling) + { + m_last_node = child->m_prev_sibling; + child->m_prev_sibling->m_next_sibling = 0; + } + else + m_first_node = 0; + child->m_parent = 0; + } + + //! Removes specified child from the node + // \param where Pointer to child to be removed. + void remove_node(xml_node *where) + { + assert(where && where->parent() == this); + assert(first_node()); + if (where == m_first_node) + remove_first_node(); + else if (where == m_last_node) + remove_last_node(); + else + { + where->m_prev_sibling->m_next_sibling = where->m_next_sibling; + where->m_next_sibling->m_prev_sibling = where->m_prev_sibling; + where->m_parent = 0; + } + } + + //! Removes all child nodes (but not attributes). + void remove_all_nodes() + { + for (xml_node *node = first_node(); node; node = node->m_next_sibling) + node->m_parent = 0; + m_first_node = 0; + } + + //! Prepends a new attribute to the node. + //! \param attribute Attribute to prepend. + void prepend_attribute(xml_attribute *attribute) + { + assert(attribute && !attribute->parent()); + if (first_attribute()) + { + attribute->m_next_attribute = m_first_attribute; + m_first_attribute->m_prev_attribute = attribute; + } + else + { + attribute->m_next_attribute = 0; + m_last_attribute = attribute; + } + m_first_attribute = attribute; + attribute->m_parent = this; + attribute->m_prev_attribute = 0; + } + + //! Appends a new attribute to the node. + //! \param attribute Attribute to append. + void append_attribute(xml_attribute *attribute) + { + assert(attribute && !attribute->parent()); + if (first_attribute()) + { + attribute->m_prev_attribute = m_last_attribute; + m_last_attribute->m_next_attribute = attribute; + } + else + { + attribute->m_prev_attribute = 0; + m_first_attribute = attribute; + } + m_last_attribute = attribute; + attribute->m_parent = this; + attribute->m_next_attribute = 0; + } + + //! Inserts a new attribute at specified place inside the node. + //! All attributes after and including the specified attribute are moved one position back. + //! \param where Place where to insert the attribute, or 0 to insert at the back. + //! \param attribute Attribute to insert. + void insert_attribute(xml_attribute *where, xml_attribute *attribute) + { + assert(!where || where->parent() == this); + assert(attribute && !attribute->parent()); + if (where == m_first_attribute) + prepend_attribute(attribute); + else if (where == 0) + append_attribute(attribute); + else + { + attribute->m_prev_attribute = where->m_prev_attribute; + attribute->m_next_attribute = where; + where->m_prev_attribute->m_next_attribute = attribute; + where->m_prev_attribute = attribute; + attribute->m_parent = this; + } + } + + //! Removes first attribute of the node. + //! If node has no attributes, behaviour is undefined. + //! Use first_attribute() to test if node has attributes. + void remove_first_attribute() + { + assert(first_attribute()); + xml_attribute *attribute = m_first_attribute; + if (attribute->m_next_attribute) + { + attribute->m_next_attribute->m_prev_attribute = 0; + } + else + m_last_attribute = 0; + attribute->m_parent = 0; + m_first_attribute = attribute->m_next_attribute; + } + + //! Removes last attribute of the node. + //! If node has no attributes, behaviour is undefined. + //! Use first_attribute() to test if node has attributes. + void remove_last_attribute() + { + assert(first_attribute()); + xml_attribute *attribute = m_last_attribute; + if (attribute->m_prev_attribute) + { + attribute->m_prev_attribute->m_next_attribute = 0; + m_last_attribute = attribute->m_prev_attribute; + } + else + m_first_attribute = 0; + attribute->m_parent = 0; + } + + //! Removes specified attribute from node. + //! \param where Pointer to attribute to be removed. + void remove_attribute(xml_attribute *where) + { + assert(first_attribute() && where->parent() == this); + if (where == m_first_attribute) + remove_first_attribute(); + else if (where == m_last_attribute) + remove_last_attribute(); + else + { + where->m_prev_attribute->m_next_attribute = where->m_next_attribute; + where->m_next_attribute->m_prev_attribute = where->m_prev_attribute; + where->m_parent = 0; + } + } + + //! Removes all attributes of node. + void remove_all_attributes() + { + for (xml_attribute *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute) + attribute->m_parent = 0; + m_first_attribute = 0; + } + + private: + + /////////////////////////////////////////////////////////////////////////// + // Restrictions + + // No copying + xml_node(const xml_node &); + void operator =(const xml_node &); + + /////////////////////////////////////////////////////////////////////////// + // Data members + + // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0. + // This is required for maximum performance, as it allows the parser to omit initialization of + // unneded/redundant values. + // + // The rules are as follows: + // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively + // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage + // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage + + node_type m_type; // Type of node; always valid + xml_node *m_first_node; // Pointer to first child node, or 0 if none; always valid + xml_node *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero + xml_attribute *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid + xml_attribute *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero + xml_node *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero + xml_node *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero + + }; + + /////////////////////////////////////////////////////////////////////////// + // XML document + + //! This class represents root of the DOM hierarchy. + //! It is also an xml_node and a memory_pool through public inheritance. + //! Use parse() function to build a DOM tree from a zero-terminated XML text string. + //! parse() function allocates memory for nodes and attributes by using functions of xml_document, + //! which are inherited from memory_pool. + //! To access root node of the document, use the document itself, as if it was an xml_node. + //! \param Ch Character type to use. + template + class xml_document: public xml_node, public memory_pool + { + + public: + + //! Constructs empty XML document + xml_document() + : xml_node(node_document) + { + } + + //! Parses zero-terminated XML string according to given flags. + //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used. + //! The string must persist for the lifetime of the document. + //! In case of error, rapidxml::parse_error exception will be thrown. + //!

+ //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning. + //! Make sure that data is zero-terminated. + //!

+ //! Document can be parsed into multiple times. + //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool. + //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser. + template + void parse(Ch *text) + { + assert(text); + + // Remove current contents + this->remove_all_nodes(); + this->remove_all_attributes(); + + // Parse BOM, if any + parse_bom(text); + + // Parse children + while (1) + { + // Skip whitespace before node + skip(text); + if (*text == 0) + break; + + // Parse and append new child + if (*text == Ch('<')) + { + ++text; // Skip '<' + if (xml_node *node = parse_node(text)) + this->append_node(node); + } + else + RAPIDXML_PARSE_ERROR("expected <", text); + } + + } + + //! Clears the document by deleting all nodes and clearing the memory pool. + //! All nodes owned by document pool are destroyed. + void clear() + { + this->remove_all_nodes(); + this->remove_all_attributes(); + memory_pool::clear(); + } + + private: + + /////////////////////////////////////////////////////////////////////// + // Internal character utility functions + + // Detect whitespace character + struct whitespace_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_whitespace[static_cast(ch)]; + } + }; + + // Detect node name character + struct node_name_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_node_name[static_cast(ch)]; + } + }; + + // Detect attribute name character + struct attribute_name_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_attribute_name[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) + struct text_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) that does not require processing + struct text_pure_no_ws_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) that does not require processing + struct text_pure_with_ws_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast(ch)]; + } + }; + + // Detect attribute value character + template + struct attribute_value_pred + { + static unsigned char test(Ch ch) + { + if (Quote == Ch('\'')) + return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast(ch)]; + if (Quote == Ch('\"')) + return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast(ch)]; + return 0; // Should never be executed, to avoid warnings on Comeau + } + }; + + // Detect attribute value character + template + struct attribute_value_pure_pred + { + static unsigned char test(Ch ch) + { + if (Quote == Ch('\'')) + return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast(ch)]; + if (Quote == Ch('\"')) + return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast(ch)]; + return 0; // Should never be executed, to avoid warnings on Comeau + } + }; + + // Insert coded character, using UTF8 or 8-bit ASCII + template + static void insert_coded_character(Ch *&text, unsigned long code) + { + if (Flags & parse_no_utf8) + { + // Insert 8-bit ASCII character + // Todo: possibly verify that code is less than 256 and use replacement char otherwise? + text[0] = static_cast(code); + text += 1; + } + else + { + // Insert UTF8 sequence + if (code < 0x80) // 1 byte sequence + { + text[0] = static_cast(code); + text += 1; + } + else if (code < 0x800) // 2 byte sequence + { + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xC0); + text += 2; + } + else if (code < 0x10000) // 3 byte sequence + { + text[2] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xE0); + text += 3; + } + else if (code < 0x110000) // 4 byte sequence + { + text[3] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[2] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xF0); + text += 4; + } + else // Invalid, only codes up to 0x10FFFF are allowed in Unicode + { + RAPIDXML_PARSE_ERROR("invalid numeric character entity", text); + } + } + } + + // Skip characters until predicate evaluates to true + template + static void skip(Ch *&text) + { + Ch *tmp = text; + while (StopPred::test(*tmp)) + ++tmp; + text = tmp; + } + + // Skip characters until predicate evaluates to true while doing the following: + // - replacing XML character entity references with proper characters (' & " < > &#...;) + // - condensing whitespace sequences to single space character + template + static Ch *skip_and_expand_character_refs(Ch *&text) + { + // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip + if (Flags & parse_no_entity_translation && + !(Flags & parse_normalize_whitespace) && + !(Flags & parse_trim_whitespace)) + { + skip(text); + return text; + } + + // Use simple skip until first modification is detected + skip(text); + + // Use translation skip + Ch *src = text; + Ch *dest = src; + while (StopPred::test(*src)) + { + // If entity translation is enabled + if (!(Flags & parse_no_entity_translation)) + { + // Test if replacement is needed + if (src[0] == Ch('&')) + { + switch (src[1]) + { + + // & ' + case Ch('a'): + if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) + { + *dest = Ch('&'); + ++dest; + src += 5; + continue; + } + if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';')) + { + *dest = Ch('\''); + ++dest; + src += 6; + continue; + } + break; + + // " + case Ch('q'): + if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';')) + { + *dest = Ch('"'); + ++dest; + src += 6; + continue; + } + break; + + // > + case Ch('g'): + if (src[2] == Ch('t') && src[3] == Ch(';')) + { + *dest = Ch('>'); + ++dest; + src += 4; + continue; + } + break; + + // < + case Ch('l'): + if (src[2] == Ch('t') && src[3] == Ch(';')) + { + *dest = Ch('<'); + ++dest; + src += 4; + continue; + } + break; + + // &#...; - assumes ASCII + case Ch('#'): + if (src[2] == Ch('x')) + { + unsigned long code = 0; + src += 3; // Skip &#x + while (1) + { + unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast(*src)]; + if (digit == 0xFF) + break; + code = code * 16 + digit; + ++src; + } + insert_coded_character(dest, code); // Put character in output + } + else + { + unsigned long code = 0; + src += 2; // Skip &# + while (1) + { + unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast(*src)]; + if (digit == 0xFF) + break; + code = code * 10 + digit; + ++src; + } + insert_coded_character(dest, code); // Put character in output + } + if (*src == Ch(';')) + ++src; + else + RAPIDXML_PARSE_ERROR("expected ;", src); + continue; + + // Something else + default: + // Ignore, just copy '&' verbatim + break; + + } + } + } + + // If whitespace condensing is enabled + if (Flags & parse_normalize_whitespace) + { + // Test if condensing is needed + if (whitespace_pred::test(*src)) + { + *dest = Ch(' '); ++dest; // Put single space in dest + ++src; // Skip first whitespace char + // Skip remaining whitespace chars + while (whitespace_pred::test(*src)) + ++src; + continue; + } + } + + // No replacement, only copy character + *dest++ = *src++; + + } + + // Return new end + text = src; + return dest; + + } + + /////////////////////////////////////////////////////////////////////// + // Internal parsing functions + + // Parse BOM, if any + template + void parse_bom(Ch *&text) + { + // UTF-8? + if (static_cast(text[0]) == 0xEF && + static_cast(text[1]) == 0xBB && + static_cast(text[2]) == 0xBF) + { + text += 3; // Skup utf-8 bom + } + } + + // Parse XML declaration ( + xml_node *parse_xml_declaration(Ch *&text) + { + // If parsing of declaration is disabled + if (!(Flags & parse_declaration_node)) + { + // Skip until end of declaration + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 2; // Skip '?>' + return 0; + } + + // Create declaration + xml_node *declaration = this->allocate_node(node_declaration); + + // Skip whitespace before attributes or ?> + skip(text); + + // Parse declaration attributes + parse_node_attributes(text, declaration); + + // Skip ?> + if (text[0] != Ch('?') || text[1] != Ch('>')) + RAPIDXML_PARSE_ERROR("expected ?>", text); + text += 2; + + return declaration; + } + + // Parse XML comment (' + return 0; // Do not produce comment node + } + + // Remember value start + Ch *value = text; + + // Skip until end of comment + while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Create comment node + xml_node *comment = this->allocate_node(node_comment); + comment->value(value, text - value); + + // Place zero terminator after comment value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 3; // Skip '-->' + return comment; + } + + // Parse DOCTYPE + template + xml_node *parse_doctype(Ch *&text) + { + // Remember value start + Ch *value = text; + + // Skip to > + while (*text != Ch('>')) + { + // Determine character type + switch (*text) + { + + // If '[' encountered, scan for matching ending ']' using naive algorithm with depth + // This works for all W3C test files except for 2 most wicked + case Ch('['): + { + ++text; // Skip '[' + int depth = 1; + while (depth > 0) + { + switch (*text) + { + case Ch('['): ++depth; break; + case Ch(']'): --depth; break; + case 0: RAPIDXML_PARSE_ERROR("unexpected end of data", text); + } + ++text; + } + break; + } + + // Error on end of text + case Ch('\0'): + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + + // Other character, skip it + default: + ++text; + + } + } + + // If DOCTYPE nodes enabled + if (Flags & parse_doctype_node) + { + // Create a new doctype node + xml_node *doctype = this->allocate_node(node_doctype); + doctype->value(value, text - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 1; // skip '>' + return doctype; + } + else + { + text += 1; // skip '>' + return 0; + } + + } + + // Parse PI + template + xml_node *parse_pi(Ch *&text) + { + // If creation of PI nodes is enabled + if (Flags & parse_pi_nodes) + { + // Create pi node + xml_node *pi = this->allocate_node(node_pi); + + // Extract PI target name + Ch *name = text; + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected PI target", text); + pi->name(name, text - name); + + // Skip whitespace between pi target and pi + skip(text); + + // Remember start of pi + Ch *value = text; + + // Skip to '?>' + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (*text == Ch('\0')) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Set pi value (verbatim, no entity expansion or whitespace normalization) + pi->value(value, text - value); + + // Place zero terminator after name and value + if (!(Flags & parse_no_string_terminators)) + { + pi->name()[pi->name_size()] = Ch('\0'); + pi->value()[pi->value_size()] = Ch('\0'); + } + + text += 2; // Skip '?>' + return pi; + } + else + { + // Skip to '?>' + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (*text == Ch('\0')) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 2; // Skip '?>' + return 0; + } + } + + // Parse and append data + // Return character that ends data. + // This is necessary because this character might have been overwritten by a terminating 0 + template + Ch parse_and_append_data(xml_node *node, Ch *&text, Ch *contents_start) + { + // Backup to contents start if whitespace trimming is disabled + if (!(Flags & parse_trim_whitespace)) + text = contents_start; + + // Skip until end of data + Ch *value = text, *end; + if (Flags & parse_normalize_whitespace) + end = skip_and_expand_character_refs(text); + else + end = skip_and_expand_character_refs(text); + + // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after > + if (Flags & parse_trim_whitespace) + { + if (Flags & parse_normalize_whitespace) + { + // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end + if (*(end - 1) == Ch(' ')) + --end; + } + else + { + // Backup until non-whitespace character is found + while (whitespace_pred::test(*(end - 1))) + --end; + } + } + + // If characters are still left between end and value (this test is only necessary if normalization is enabled) + // Create new data node + if (!(Flags & parse_no_data_nodes)) + { + xml_node *data = this->allocate_node(node_data); + data->value(value, end - value); + node->append_node(data); + } + + // Add data to parent node if no data exists yet + if (!(Flags & parse_no_element_values)) + if (*node->value() == Ch('\0')) + node->value(value, end - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + { + Ch ch = *text; + *end = Ch('\0'); + return ch; // Return character that ends data; this is required because zero terminator overwritten it + } + + // Return character that ends data + return *text; + } + + // Parse CDATA + template + xml_node *parse_cdata(Ch *&text) + { + // If CDATA is disabled + if (Flags & parse_no_data_nodes) + { + // Skip until end of cdata + while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 3; // Skip ]]> + return 0; // Do not produce CDATA node + } + + // Skip until end of cdata + Ch *value = text; + while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Create new cdata node + xml_node *cdata = this->allocate_node(node_cdata); + cdata->value(value, text - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 3; // Skip ]]> + return cdata; + } + + // Parse element node + template + xml_node *parse_element(Ch *&text) + { + // Create element node + xml_node *element = this->allocate_node(node_element); + + // Extract element name + Ch *name = text; + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected element name", text); + element->name(name, text - name); + + // Skip whitespace between element name and attributes or > + skip(text); + + // Parse attributes, if any + parse_node_attributes(text, element); + + // Determine ending type + if (*text == Ch('>')) + { + ++text; + parse_node_contents(text, element); + } + else if (*text == Ch('/')) + { + ++text; + if (*text != Ch('>')) + RAPIDXML_PARSE_ERROR("expected >", text); + ++text; + } + else + RAPIDXML_PARSE_ERROR("expected >", text); + + // Place zero terminator after name + if (!(Flags & parse_no_string_terminators)) + element->name()[element->name_size()] = Ch('\0'); + + // Return parsed element + return element; + } + + // Determine node type, and parse it + template + xml_node *parse_node(Ch *&text) + { + // Parse proper node type + switch (text[0]) + { + + // <... + default: + // Parse and append element node + return parse_element(text); + + // (text); + } + else + { + // Parse PI + return parse_pi(text); + } + + // (text); + } + break; + + // (text); + } + break; + + // (text); + } + + } // switch + + // Attempt to skip other, unrecognized node types starting with ')) + { + if (*text == 0) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + ++text; // Skip '>' + return 0; // No node recognized + + } + } + + // Parse contents of the node - children, data etc. + template + void parse_node_contents(Ch *&text, xml_node *node) + { + // For all children and text + while (1) + { + // Skip whitespace between > and node contents + Ch *contents_start = text; // Store start of node contents before whitespace is skipped + skip(text); + Ch next_char = *text; + + // After data nodes, instead of continuing the loop, control jumps here. + // This is because zero termination inside parse_and_append_data() function + // would wreak havoc with the above code. + // Also, skipping whitespace after data nodes is unnecessary. + after_data_node: + + // Determine what comes next: node closing, child node, data node, or 0? + switch (next_char) + { + + // Node closing or child node + case Ch('<'): + if (text[1] == Ch('/')) + { + // Node closing + text += 2; // Skip '(text); + if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true)) + RAPIDXML_PARSE_ERROR("invalid closing tag name", text); + } + else + { + // No validation, just skip name + skip(text); + } + // Skip remaining whitespace after node name + skip(text); + if (*text != Ch('>')) + RAPIDXML_PARSE_ERROR("expected >", text); + ++text; // Skip '>' + return; // Node closed, finished parsing contents + } + else + { + // Child node + ++text; // Skip '<' + if (xml_node *child = parse_node(text)) + node->append_node(child); + } + break; + + // End of data - error + case Ch('\0'): + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + + // Data node + default: + next_char = parse_and_append_data(node, text, contents_start); + goto after_data_node; // Bypass regular processing after data nodes + + } + } + } + + // Parse XML attributes of the node + template + void parse_node_attributes(Ch *&text, xml_node *node) + { + // For all attributes + while (attribute_name_pred::test(*text)) + { + // Extract attribute name + Ch *name = text; + ++text; // Skip first character of attribute name + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected attribute name", name); + + // Create new attribute + xml_attribute *attribute = this->allocate_attribute(); + attribute->name(name, text - name); + node->append_attribute(attribute); + + // Skip whitespace after attribute name + skip(text); + + // Skip = + if (*text != Ch('=')) + RAPIDXML_PARSE_ERROR("expected =", text); + ++text; + + // Add terminating zero after name + if (!(Flags & parse_no_string_terminators)) + attribute->name()[attribute->name_size()] = 0; + + // Skip whitespace after = + skip(text); + + // Skip quote and remember if it was ' or " + Ch quote = *text; + if (quote != Ch('\'') && quote != Ch('"')) + RAPIDXML_PARSE_ERROR("expected ' or \"", text); + ++text; + + // Extract attribute value and expand char refs in it + Ch *value = text, *end; + const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes + if (quote == Ch('\'')) + end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags>(text); + else + end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags>(text); + + // Set attribute value + attribute->value(value, end - value); + + // Make sure that end quote is present + if (*text != quote) + RAPIDXML_PARSE_ERROR("expected ' or \"", text); + ++text; // Skip quote + + // Add terminating zero after value + if (!(Flags & parse_no_string_terminators)) + attribute->value()[attribute->value_size()] = 0; + + // Skip whitespace after attribute value + skip(text); + } + } + + }; + + //! \cond internal + namespace internal + { + + // Whitespace (space \n \r \t) + template + const unsigned char lookup_tables::lookup_whitespace[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F + }; + + // Node name (anything but space \n \r \t / > ? \0) + template + const unsigned char lookup_tables::lookup_node_name[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) (anything but < \0) + template + const unsigned char lookup_tables::lookup_text[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled + // (anything but < \0 &) + template + const unsigned char lookup_tables::lookup_text_pure_no_ws[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 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, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled + // (anything but < \0 & space \n \r \t) + template + const unsigned char lookup_tables::lookup_text_pure_with_ws[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute name (anything but space \n \r \t / < > = ? ! \0) + template + const unsigned char lookup_tables::lookup_attribute_name[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with single quote (anything but ' \0) + template + const unsigned char lookup_tables::lookup_attribute_data_1[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 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, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with single quote that does not require processing (anything but ' \0 &) + template + const unsigned char lookup_tables::lookup_attribute_data_1_pure[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 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, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with double quote (anything but " \0) + template + const unsigned char lookup_tables::lookup_attribute_data_2[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 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, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with double quote that does not require processing (anything but " \0 &) + template + const unsigned char lookup_tables::lookup_attribute_data_2_pure[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 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, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Digits (dec and hex, 255 denotes end of numeric character reference) + template + const unsigned char lookup_tables::lookup_digits[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 1 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 2 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255, // 3 + 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 4 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 5 + 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 6 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 7 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 8 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 9 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // A + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // B + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // C + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // D + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // E + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 // F + }; + + // Upper case conversion + template + const unsigned char lookup_tables::lookup_upcase[256] = + { + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A B C D E F + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 + 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 6 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123,124,125,126,127, // 7 + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8 + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9 + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C + 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D + 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F + }; + } + //! \endcond + +} + +// Undefine internal macros +#undef RAPIDXML_PARSE_ERROR + +// On MSVC, restore warnings state +#ifdef _MSC_VER + #pragma warning(pop) +#endif + +#endif diff --git a/ext/native/ext/rapidxml/rapidxml_iterators.hpp b/ext/native/ext/rapidxml/rapidxml_iterators.hpp new file mode 100644 index 0000000000..52ebc298aa --- /dev/null +++ b/ext/native/ext/rapidxml/rapidxml_iterators.hpp @@ -0,0 +1,174 @@ +#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED +#define RAPIDXML_ITERATORS_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_iterators.hpp This file contains rapidxml iterators + +#include "rapidxml.hpp" + +namespace rapidxml +{ + + //! Iterator of child nodes of xml_node + template + class node_iterator + { + + public: + + typedef typename xml_node value_type; + typedef typename xml_node &reference; + typedef typename xml_node *pointer; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + node_iterator() + : m_node(0) + { + } + + node_iterator(xml_node *node) + : m_node(node->first_node()) + { + } + + reference operator *() const + { + assert(m_node); + return *m_node; + } + + pointer operator->() const + { + assert(m_node); + return m_node; + } + + node_iterator& operator++() + { + assert(m_node); + m_node = m_node->next_sibling(); + return *this; + } + + node_iterator operator++(int) + { + node_iterator tmp = *this; + ++this; + return tmp; + } + + node_iterator& operator--() + { + assert(m_node && m_node->previous_sibling()); + m_node = m_node->previous_sibling(); + return *this; + } + + node_iterator operator--(int) + { + node_iterator tmp = *this; + ++this; + return tmp; + } + + bool operator ==(const node_iterator &rhs) + { + return m_node == rhs.m_node; + } + + bool operator !=(const node_iterator &rhs) + { + return m_node != rhs.m_node; + } + + private: + + xml_node *m_node; + + }; + + //! Iterator of child attributes of xml_node + template + class attribute_iterator + { + + public: + + typedef typename xml_attribute value_type; + typedef typename xml_attribute &reference; + typedef typename xml_attribute *pointer; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + attribute_iterator() + : m_attribute(0) + { + } + + attribute_iterator(xml_node *node) + : m_attribute(node->first_attribute()) + { + } + + reference operator *() const + { + assert(m_attribute); + return *m_attribute; + } + + pointer operator->() const + { + assert(m_attribute); + return m_attribute; + } + + attribute_iterator& operator++() + { + assert(m_attribute); + m_attribute = m_attribute->next_attribute(); + return *this; + } + + attribute_iterator operator++(int) + { + attribute_iterator tmp = *this; + ++this; + return tmp; + } + + attribute_iterator& operator--() + { + assert(m_attribute && m_attribute->previous_attribute()); + m_attribute = m_attribute->previous_attribute(); + return *this; + } + + attribute_iterator operator--(int) + { + attribute_iterator tmp = *this; + ++this; + return tmp; + } + + bool operator ==(const attribute_iterator &rhs) + { + return m_attribute == rhs.m_attribute; + } + + bool operator !=(const attribute_iterator &rhs) + { + return m_attribute != rhs.m_attribute; + } + + private: + + xml_attribute *m_attribute; + + }; + +} + +#endif diff --git a/ext/native/ext/rapidxml/rapidxml_print.hpp b/ext/native/ext/rapidxml/rapidxml_print.hpp new file mode 100644 index 0000000000..0ae2b14faa --- /dev/null +++ b/ext/native/ext/rapidxml/rapidxml_print.hpp @@ -0,0 +1,421 @@ +#ifndef RAPIDXML_PRINT_HPP_INCLUDED +#define RAPIDXML_PRINT_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_print.hpp This file contains rapidxml printer implementation + +#include "rapidxml.hpp" + +// Only include streams if not disabled +#ifndef RAPIDXML_NO_STREAMS + #include + #include +#endif + +namespace rapidxml +{ + + /////////////////////////////////////////////////////////////////////// + // Printing flags + + const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function. + + /////////////////////////////////////////////////////////////////////// + // Internal + + //! \cond internal + namespace internal + { + + /////////////////////////////////////////////////////////////////////////// + // Internal character operations + + // Copy characters from given range to given output iterator + template + inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out) + { + while (begin != end) + *out++ = *begin++; + return out; + } + + // Copy characters from given range to given output iterator and expand + // characters into references (< > ' " &) + template + inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out) + { + while (begin != end) + { + if (*begin == noexpand) + { + *out++ = *begin; // No expansion, copy character + } + else + { + switch (*begin) + { + case Ch('<'): + *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';'); + break; + case Ch('>'): + *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';'); + break; + case Ch('\''): + *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';'); + break; + case Ch('"'): + *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';'); + break; + case Ch('&'): + *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';'); + break; + default: + *out++ = *begin; // No expansion, copy character + } + } + ++begin; // Step to next character + } + return out; + } + + // Fill given output iterator with repetitions of the same character + template + inline OutIt fill_chars(OutIt out, int n, Ch ch) + { + for (int i = 0; i < n; ++i) + *out++ = ch; + return out; + } + + // Find character + template + inline bool find_char(const Ch *begin, const Ch *end) + { + while (begin != end) + if (*begin++ == ch) + return true; + return false; + } + + /////////////////////////////////////////////////////////////////////////// + // Internal printing operations + + // Print node + template + inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent) + { + // Print proper node type + switch (node->type()) + { + + // Document + case node_document: + out = print_children(out, node, flags, indent); + break; + + // Element + case node_element: + out = print_element_node(out, node, flags, indent); + break; + + // Data + case node_data: + out = print_data_node(out, node, flags, indent); + break; + + // CDATA + case node_cdata: + out = print_cdata_node(out, node, flags, indent); + break; + + // Declaration + case node_declaration: + out = print_declaration_node(out, node, flags, indent); + break; + + // Comment + case node_comment: + out = print_comment_node(out, node, flags, indent); + break; + + // Doctype + case node_doctype: + out = print_doctype_node(out, node, flags, indent); + break; + + // Pi + case node_pi: + out = print_pi_node(out, node, flags, indent); + break; + + // Unknown + default: + assert(0); + break; + } + + // If indenting not disabled, add line break after node + if (!(flags & print_no_indenting)) + *out = Ch('\n'), ++out; + + // Return modified iterator + return out; + } + + // Print children of the node + template + inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent) + { + for (xml_node *child = node->first_node(); child; child = child->next_sibling()) + out = print_node(out, child, flags, indent); + return out; + } + + // Print attributes of the node + template + inline OutIt print_attributes(OutIt out, const xml_node *node, int flags) + { + for (xml_attribute *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + if (attribute->name() && attribute->value()) + { + // Print attribute name + *out = Ch(' '), ++out; + out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out); + *out = Ch('='), ++out; + // Print attribute value using appropriate quote type + if (find_char(attribute->value(), attribute->value() + attribute->value_size())) + { + *out = Ch('\''), ++out; + out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out); + *out = Ch('\''), ++out; + } + else + { + *out = Ch('"'), ++out; + out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out); + *out = Ch('"'), ++out; + } + } + } + return out; + } + + // Print data node + template + inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_data); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); + return out; + } + + // Print data node + template + inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_cdata); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'); ++out; + *out = Ch('!'); ++out; + *out = Ch('['); ++out; + *out = Ch('C'); ++out; + *out = Ch('D'); ++out; + *out = Ch('A'); ++out; + *out = Ch('T'); ++out; + *out = Ch('A'); ++out; + *out = Ch('['); ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch(']'); ++out; + *out = Ch(']'); ++out; + *out = Ch('>'); ++out; + return out; + } + + // Print element node + template + inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_element); + + // Print element name and attributes, if any + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + out = print_attributes(out, node, flags); + + // If node is childless + if (node->value_size() == 0 && !node->first_node()) + { + // Print childless node tag ending + *out = Ch('/'), ++out; + *out = Ch('>'), ++out; + } + else + { + // Print normal node tag ending + *out = Ch('>'), ++out; + + // Test if node contains a single data node only (and no other nodes) + xml_node *child = node->first_node(); + if (!child) + { + // If node has no children, only print its value without indenting + out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); + } + else if (child->next_sibling() == 0 && child->type() == node_data) + { + // If node has a sole data child, only print its value without indenting + out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out); + } + else + { + // Print all children with full indenting + if (!(flags & print_no_indenting)) + *out = Ch('\n'), ++out; + out = print_children(out, node, flags, indent + 1); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + } + + // Print node end + *out = Ch('<'), ++out; + *out = Ch('/'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + *out = Ch('>'), ++out; + } + return out; + } + + // Print declaration node + template + inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent) + { + // Print declaration start + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('?'), ++out; + *out = Ch('x'), ++out; + *out = Ch('m'), ++out; + *out = Ch('l'), ++out; + + // Print attributes + out = print_attributes(out, node, flags); + + // Print declaration end + *out = Ch('?'), ++out; + *out = Ch('>'), ++out; + + return out; + } + + // Print comment node + template + inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_comment); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('!'), ++out; + *out = Ch('-'), ++out; + *out = Ch('-'), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('-'), ++out; + *out = Ch('-'), ++out; + *out = Ch('>'), ++out; + return out; + } + + // Print doctype node + template + inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_doctype); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('!'), ++out; + *out = Ch('D'), ++out; + *out = Ch('O'), ++out; + *out = Ch('C'), ++out; + *out = Ch('T'), ++out; + *out = Ch('Y'), ++out; + *out = Ch('P'), ++out; + *out = Ch('E'), ++out; + *out = Ch(' '), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('>'), ++out; + return out; + } + + // Print pi node + template + inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_pi); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('?'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + *out = Ch(' '), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('?'), ++out; + *out = Ch('>'), ++out; + return out; + } + + } + //! \endcond + + /////////////////////////////////////////////////////////////////////////// + // Printing + + //! Prints XML to given output iterator. + //! \param out Output iterator to print to. + //! \param node Node to be printed. Pass xml_document to print entire document. + //! \param flags Flags controlling how XML is printed. + //! \return Output iterator pointing to position immediately after last character of printed text. + template + inline OutIt print(OutIt out, const xml_node &node, int flags = 0) + { + return internal::print_node(out, &node, flags, 0); + } + +#ifndef RAPIDXML_NO_STREAMS + + //! Prints XML to given output stream. + //! \param out Output stream to print to. + //! \param node Node to be printed. Pass xml_document to print entire document. + //! \param flags Flags controlling how XML is printed. + //! \return Output stream. + template + inline std::basic_ostream &print(std::basic_ostream &out, const xml_node &node, int flags = 0) + { + print(std::ostream_iterator(out), node, flags); + return out; + } + + //! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process. + //! \param out Output stream to print to. + //! \param node Node to be printed. + //! \return Output stream. + template + inline std::basic_ostream &operator <<(std::basic_ostream &out, const xml_node &node) + { + return print(out, node); + } + +#endif + +} + +#endif diff --git a/ext/native/ext/rapidxml/rapidxml_utils.hpp b/ext/native/ext/rapidxml/rapidxml_utils.hpp new file mode 100644 index 0000000000..37c29535f4 --- /dev/null +++ b/ext/native/ext/rapidxml/rapidxml_utils.hpp @@ -0,0 +1,122 @@ +#ifndef RAPIDXML_UTILS_HPP_INCLUDED +#define RAPIDXML_UTILS_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful +//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective. + +#include "rapidxml.hpp" +#include +#include +#include +#include + +namespace rapidxml +{ + + //! Represents data loaded from a file + template + class file + { + + public: + + //! Loads file into the memory. Data will be automatically destroyed by the destructor. + //! \param filename Filename to load. + file(const char *filename) + { + using namespace std; + + // Open stream + basic_ifstream stream(filename, ios::binary); + if (!stream) + throw runtime_error(string("cannot open file ") + filename); + stream.unsetf(ios::skipws); + + // Determine stream size + stream.seekg(0, ios::end); + size_t size = stream.tellg(); + stream.seekg(0); + + // Load data and add terminating 0 + m_data.resize(size + 1); + stream.read(&m_data.front(), static_cast(size)); + m_data[size] = 0; + } + + //! Loads file into the memory. Data will be automatically destroyed by the destructor + //! \param stream Stream to load from + file(std::basic_istream &stream) + { + using namespace std; + + // Load data and add terminating 0 + stream.unsetf(ios::skipws); + m_data.assign(istreambuf_iterator(stream), istreambuf_iterator()); + if (stream.fail() || stream.bad()) + throw runtime_error("error reading stream"); + m_data.push_back(0); + } + + //! Gets file data. + //! \return Pointer to data of file. + Ch *data() + { + return &m_data.front(); + } + + //! Gets file data. + //! \return Pointer to data of file. + const Ch *data() const + { + return &m_data.front(); + } + + //! Gets file data size. + //! \return Size of file data, in characters. + std::size_t size() const + { + return m_data.size(); + } + + private: + + std::vector m_data; // File data + + }; + + //! Counts children of node. Time complexity is O(n). + //! \return Number of children of node + template + inline std::size_t count_children(xml_node *node) + { + xml_node *child = node->first_node(); + std::size_t count = 0; + while (child) + { + ++count; + child = child->next_sibling(); + } + return count; + } + + //! Counts attributes of node. Time complexity is O(n). + //! \return Number of attributes of node + template + inline std::size_t count_attributes(xml_node *node) + { + xml_attribute *attr = node->first_attribute(); + std::size_t count = 0; + while (attr) + { + ++count; + attr = attr->next_attribute(); + } + return count; + } + +} + +#endif diff --git a/ext/native/ext/rg_etc1/CMakeLists.txt b/ext/native/ext/rg_etc1/CMakeLists.txt new file mode 100644 index 0000000000..70f73115f4 --- /dev/null +++ b/ext/native/ext/rg_etc1/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.6) + +add_library(rg_etc1 rg_etc1.cpp) diff --git a/ext/native/ext/rg_etc1/rg_etc1.cpp b/ext/native/ext/rg_etc1/rg_etc1.cpp new file mode 100644 index 0000000000..e003f14863 --- /dev/null +++ b/ext/native/ext/rg_etc1/rg_etc1.cpp @@ -0,0 +1,2448 @@ +// File: rg_etc1.cpp - Fast, high quality ETC1 block packer/unpacker - Rich Geldreich +// Please see ZLIB license at the end of rg_etc1.h. +// +// For more information Ericsson Texture Compression (ETC/ETC1), see: +// http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt +// +// v1.04 - 5/15/14 - Fix signed vs. unsigned subtraction problem (noticed when compiled with gcc) in pack_etc1_block_init(). +// This issue would cause an assert when this func. was called in debug. (Note this module was developed/testing with MSVC, +// I still need to test it throughly when compiled with gcc.) +// +// v1.03 - 5/12/13 - Initial public release +#include "rg_etc1.h" + +#include +#include +#include +//#include +#include + +#ifdef _MSC_VER +#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union +#endif + +#if defined(_DEBUG) || defined(DEBUG) +#define RG_ETC1_BUILD_DEBUG +#endif + +#define RG_ETC1_ASSERT assert + +namespace rg_etc1 +{ + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint; + typedef unsigned int uint32; + typedef long long int64; + typedef unsigned long long uint64; + + const uint32 cUINT32_MAX = 0xFFFFFFFFU; + const uint64 cUINT64_MAX = 0xFFFFFFFFFFFFFFFFULL; //0xFFFFFFFFFFFFFFFFui64; + + template inline T minimum(T a, T b) { return (a < b) ? a : b; } + template inline T minimum(T a, T b, T c) { return minimum(minimum(a, b), c); } + template inline T maximum(T a, T b) { return (a > b) ? a : b; } + template inline T maximum(T a, T b, T c) { return maximum(maximum(a, b), c); } + template inline T clamp(T value, T low, T high) { return (value < low) ? low : ((value > high) ? high : value); } + template inline T square(T value) { return value * value; } + template inline void zero_object(T& obj) { memset((void*)&obj, 0, sizeof(obj)); } + template inline void zero_this(T* pObj) { memset((void*)pObj, 0, sizeof(*pObj)); } + + template T decay_array_to_subtype(T (&a)[N]); + +#define RG_ETC1_ARRAY_SIZE(X) (sizeof(X) / sizeof(decay_array_to_subtype(X))) + + enum eNoClamp { cNoClamp }; + + struct color_quad_u8 + { + static inline int clamp(int v) { if (v & 0xFFFFFF00U) v = (~(static_cast(v) >> 31)) & 0xFF; return v; } + + struct component_traits { enum { cSigned = false, cFloat = false, cMin = 0U, cMax = 255U }; }; + + public: + typedef unsigned char component_t; + typedef int parameter_t; + + enum { cNumComps = 4 }; + + union + { + struct + { + component_t r; + component_t g; + component_t b; + component_t a; + }; + + component_t c[cNumComps]; + + uint32 m_u32; + }; + + inline color_quad_u8() + { + } + + inline color_quad_u8(const color_quad_u8& other) : m_u32(other.m_u32) + { + } + + explicit inline color_quad_u8(parameter_t y, parameter_t alpha = component_traits::cMax) + { + set(y, alpha); + } + + inline color_quad_u8(parameter_t red, parameter_t green, parameter_t blue, parameter_t alpha = component_traits::cMax) + { + set(red, green, blue, alpha); + } + + explicit inline color_quad_u8(eNoClamp, parameter_t y, parameter_t alpha = component_traits::cMax) + { + set_noclamp_y_alpha(y, alpha); + } + + inline color_quad_u8(eNoClamp, parameter_t red, parameter_t green, parameter_t blue, parameter_t alpha = component_traits::cMax) + { + set_noclamp_rgba(red, green, blue, alpha); + } + + inline void clear() + { + m_u32 = 0; + } + + inline color_quad_u8& operator= (const color_quad_u8& other) + { + m_u32 = other.m_u32; + return *this; + } + + inline color_quad_u8& set_rgb(const color_quad_u8& other) + { + r = other.r; + g = other.g; + b = other.b; + return *this; + } + + inline color_quad_u8& operator= (parameter_t y) + { + set(y, component_traits::cMax); + return *this; + } + + inline color_quad_u8& set(parameter_t y, parameter_t alpha = component_traits::cMax) + { + y = clamp(y); + alpha = clamp(alpha); + r = static_cast(y); + g = static_cast(y); + b = static_cast(y); + a = static_cast(alpha); + return *this; + } + + inline color_quad_u8& set_noclamp_y_alpha(parameter_t y, parameter_t alpha = component_traits::cMax) + { + RG_ETC1_ASSERT( (y >= component_traits::cMin) && (y <= component_traits::cMax) ); + RG_ETC1_ASSERT( (alpha >= component_traits::cMin) && (alpha <= component_traits::cMax) ); + + r = static_cast(y); + g = static_cast(y); + b = static_cast(y); + a = static_cast(alpha); + return *this; + } + + inline color_quad_u8& set(parameter_t red, parameter_t green, parameter_t blue, parameter_t alpha = component_traits::cMax) + { + r = static_cast(clamp(red)); + g = static_cast(clamp(green)); + b = static_cast(clamp(blue)); + a = static_cast(clamp(alpha)); + return *this; + } + + inline color_quad_u8& set_noclamp_rgba(parameter_t red, parameter_t green, parameter_t blue, parameter_t alpha) + { + RG_ETC1_ASSERT( (red >= component_traits::cMin) && (red <= component_traits::cMax) ); + RG_ETC1_ASSERT( (green >= component_traits::cMin) && (green <= component_traits::cMax) ); + RG_ETC1_ASSERT( (blue >= component_traits::cMin) && (blue <= component_traits::cMax) ); + RG_ETC1_ASSERT( (alpha >= component_traits::cMin) && (alpha <= component_traits::cMax) ); + + r = static_cast(red); + g = static_cast(green); + b = static_cast(blue); + a = static_cast(alpha); + return *this; + } + + inline color_quad_u8& set_noclamp_rgb(parameter_t red, parameter_t green, parameter_t blue) + { + RG_ETC1_ASSERT( (red >= component_traits::cMin) && (red <= component_traits::cMax) ); + RG_ETC1_ASSERT( (green >= component_traits::cMin) && (green <= component_traits::cMax) ); + RG_ETC1_ASSERT( (blue >= component_traits::cMin) && (blue <= component_traits::cMax) ); + + r = static_cast(red); + g = static_cast(green); + b = static_cast(blue); + return *this; + } + + static inline parameter_t get_min_comp() { return component_traits::cMin; } + static inline parameter_t get_max_comp() { return component_traits::cMax; } + static inline bool get_comps_are_signed() { return component_traits::cSigned; } + + inline component_t operator[] (uint i) const { RG_ETC1_ASSERT(i < cNumComps); return c[i]; } + inline component_t& operator[] (uint i) { RG_ETC1_ASSERT(i < cNumComps); return c[i]; } + + inline color_quad_u8& set_component(uint i, parameter_t f) + { + RG_ETC1_ASSERT(i < cNumComps); + + c[i] = static_cast(clamp(f)); + + return *this; + } + + inline color_quad_u8& set_grayscale(parameter_t l) + { + component_t x = static_cast(clamp(l)); + c[0] = x; + c[1] = x; + c[2] = x; + return *this; + } + + inline color_quad_u8& clamp(const color_quad_u8& l, const color_quad_u8& h) + { + for (uint i = 0; i < cNumComps; i++) + c[i] = static_cast(rg_etc1::clamp(c[i], l[i], h[i])); + return *this; + } + + inline color_quad_u8& clamp(parameter_t l, parameter_t h) + { + for (uint i = 0; i < cNumComps; i++) + c[i] = static_cast(rg_etc1::clamp(c[i], l, h)); + return *this; + } + + // Returns CCIR 601 luma (consistent with color_utils::RGB_To_Y). + inline parameter_t get_luma() const + { + return static_cast((19595U * r + 38470U * g + 7471U * b + 32768U) >> 16U); + } + + // Returns REC 709 luma. + inline parameter_t get_luma_rec709() const + { + return static_cast((13938U * r + 46869U * g + 4729U * b + 32768U) >> 16U); + } + + inline uint squared_distance_rgb(const color_quad_u8& c) const + { + return rg_etc1::square(r - c.r) + rg_etc1::square(g - c.g) + rg_etc1::square(b - c.b); + } + + inline uint squared_distance_rgba(const color_quad_u8& c) const + { + return rg_etc1::square(r - c.r) + rg_etc1::square(g - c.g) + rg_etc1::square(b - c.b) + rg_etc1::square(a - c.a); + } + + inline bool rgb_equals(const color_quad_u8& rhs) const + { + return (r == rhs.r) && (g == rhs.g) && (b == rhs.b); + } + + inline bool operator== (const color_quad_u8& rhs) const + { + return m_u32 == rhs.m_u32; + } + + color_quad_u8& operator+= (const color_quad_u8& other) + { + for (uint i = 0; i < 4; i++) + c[i] = static_cast(clamp(c[i] + other.c[i])); + return *this; + } + + color_quad_u8& operator-= (const color_quad_u8& other) + { + for (uint i = 0; i < 4; i++) + c[i] = static_cast(clamp(c[i] - other.c[i])); + return *this; + } + + friend color_quad_u8 operator+ (const color_quad_u8& lhs, const color_quad_u8& rhs) + { + color_quad_u8 result(lhs); + result += rhs; + return result; + } + + friend color_quad_u8 operator- (const color_quad_u8& lhs, const color_quad_u8& rhs) + { + color_quad_u8 result(lhs); + result -= rhs; + return result; + } + }; // class color_quad_u8 + + struct vec3F + { + float m_s[3]; + + inline vec3F() { } + inline vec3F(float s) { m_s[0] = s; m_s[1] = s; m_s[2] = s; } + inline vec3F(float x, float y, float z) { m_s[0] = x; m_s[1] = y; m_s[2] = z; } + + inline float operator[] (uint i) const { RG_ETC1_ASSERT(i < 3); return m_s[i]; } + + inline vec3F& operator += (const vec3F& other) { for (uint i = 0; i < 3; i++) m_s[i] += other.m_s[i]; return *this; } + + inline vec3F& operator *= (float s) { for (uint i = 0; i < 3; i++) m_s[i] *= s; return *this; } + }; + + enum etc_constants + { + cETC1BytesPerBlock = 8U, + + cETC1SelectorBits = 2U, + cETC1SelectorValues = 1U << cETC1SelectorBits, + cETC1SelectorMask = cETC1SelectorValues - 1U, + + cETC1BlockShift = 2U, + cETC1BlockSize = 1U << cETC1BlockShift, + + cETC1LSBSelectorIndicesBitOffset = 0, + cETC1MSBSelectorIndicesBitOffset = 16, + + cETC1FlipBitOffset = 32, + cETC1DiffBitOffset = 33, + + cETC1IntenModifierNumBits = 3, + cETC1IntenModifierValues = 1 << cETC1IntenModifierNumBits, + cETC1RightIntenModifierTableBitOffset = 34, + cETC1LeftIntenModifierTableBitOffset = 37, + + // Base+Delta encoding (5 bit bases, 3 bit delta) + cETC1BaseColorCompNumBits = 5, + cETC1BaseColorCompMax = 1 << cETC1BaseColorCompNumBits, + + cETC1DeltaColorCompNumBits = 3, + cETC1DeltaColorComp = 1 << cETC1DeltaColorCompNumBits, + cETC1DeltaColorCompMax = 1 << cETC1DeltaColorCompNumBits, + + cETC1BaseColor5RBitOffset = 59, + cETC1BaseColor5GBitOffset = 51, + cETC1BaseColor5BBitOffset = 43, + + cETC1DeltaColor3RBitOffset = 56, + cETC1DeltaColor3GBitOffset = 48, + cETC1DeltaColor3BBitOffset = 40, + + // Absolute (non-delta) encoding (two 4-bit per component bases) + cETC1AbsColorCompNumBits = 4, + cETC1AbsColorCompMax = 1 << cETC1AbsColorCompNumBits, + + cETC1AbsColor4R1BitOffset = 60, + cETC1AbsColor4G1BitOffset = 52, + cETC1AbsColor4B1BitOffset = 44, + + cETC1AbsColor4R2BitOffset = 56, + cETC1AbsColor4G2BitOffset = 48, + cETC1AbsColor4B2BitOffset = 40, + + cETC1ColorDeltaMin = -4, + cETC1ColorDeltaMax = 3, + + // Delta3: + // 0 1 2 3 4 5 6 7 + // 000 001 010 011 100 101 110 111 + // 0 1 2 3 -4 -3 -2 -1 + }; + + static uint8 g_quant5_tab[256+16]; + + static const int g_etc1_inten_tables[cETC1IntenModifierValues][cETC1SelectorValues] = + { + { -8, -2, 2, 8 }, { -17, -5, 5, 17 }, { -29, -9, 9, 29 }, { -42, -13, 13, 42 }, + { -60, -18, 18, 60 }, { -80, -24, 24, 80 }, { -106, -33, 33, 106 }, { -183, -47, 47, 183 } + }; + + static const uint8 g_etc1_to_selector_index[cETC1SelectorValues] = { 2, 3, 1, 0 }; + static const uint8 g_selector_index_to_etc1[cETC1SelectorValues] = { 3, 2, 0, 1 }; + + // Given an ETC1 diff/inten_table/selector, and an 8-bit desired color, this table encodes the best packed_color in the low byte, and the abs error in the high byte. + static uint16 g_etc1_inverse_lookup[2*8*4][256]; // [diff/inten_table/selector][desired_color] + + // g_color8_to_etc_block_config[color][table_index] = Supplies for each 8-bit color value a list of packed ETC1 diff/intensity table/selectors/packed_colors that map to that color. + // To pack: diff | (inten << 1) | (selector << 4) | (packed_c << 8) + static const uint16 g_color8_to_etc_block_config_0_255[2][33] = + { + { 0x0000, 0x0010, 0x0002, 0x0012, 0x0004, 0x0014, 0x0006, 0x0016, 0x0008, 0x0018, 0x000A, 0x001A, 0x000C, 0x001C, 0x000E, 0x001E, + 0x0001, 0x0011, 0x0003, 0x0013, 0x0005, 0x0015, 0x0007, 0x0017, 0x0009, 0x0019, 0x000B, 0x001B, 0x000D, 0x001D, 0x000F, 0x001F, 0xFFFF }, + { 0x0F20, 0x0F30, 0x0E32, 0x0F22, 0x0E34, 0x0F24, 0x0D36, 0x0F26, 0x0C38, 0x0E28, 0x0B3A, 0x0E2A, 0x093C, 0x0E2C, 0x053E, 0x0D2E, + 0x1E31, 0x1F21, 0x1D33, 0x1F23, 0x1C35, 0x1E25, 0x1A37, 0x1E27, 0x1839, 0x1D29, 0x163B, 0x1C2B, 0x133D, 0x1B2D, 0x093F, 0x1A2F, 0xFFFF }, + }; + + // Really only [254][11]. + static const uint16 g_color8_to_etc_block_config_1_to_254[254][12] = + { + { 0x021C, 0x0D0D, 0xFFFF }, { 0x0020, 0x0021, 0x0A0B, 0x061F, 0xFFFF }, { 0x0113, 0x0217, 0xFFFF }, { 0x0116, 0x031E, + 0x0B0E, 0x0405, 0xFFFF }, { 0x0022, 0x0204, 0x050A, 0x0023, 0xFFFF }, { 0x0111, 0x0319, 0x0809, 0x170F, 0xFFFF }, { + 0x0303, 0x0215, 0x0607, 0xFFFF }, { 0x0030, 0x0114, 0x0408, 0x0031, 0x0201, 0x051D, 0xFFFF }, { 0x0100, 0x0024, 0x0306, + 0x0025, 0x041B, 0x0E0D, 0xFFFF }, { 0x021A, 0x0121, 0x0B0B, 0x071F, 0xFFFF }, { 0x0213, 0x0317, 0xFFFF }, { 0x0112, + 0x0505, 0xFFFF }, { 0x0026, 0x070C, 0x0123, 0x0027, 0xFFFF }, { 0x0211, 0x0909, 0xFFFF }, { 0x0110, 0x0315, 0x0707, + 0x0419, 0x180F, 0xFFFF }, { 0x0218, 0x0131, 0x0301, 0x0403, 0x061D, 0xFFFF }, { 0x0032, 0x0202, 0x0033, 0x0125, 0x051B, + 0x0F0D, 0xFFFF }, { 0x0028, 0x031C, 0x0221, 0x0029, 0xFFFF }, { 0x0120, 0x0313, 0x0C0B, 0x081F, 0xFFFF }, { 0x0605, + 0x0417, 0xFFFF }, { 0x0216, 0x041E, 0x0C0E, 0x0223, 0x0127, 0xFFFF }, { 0x0122, 0x0304, 0x060A, 0x0311, 0x0A09, 0xFFFF + }, { 0x0519, 0x190F, 0xFFFF }, { 0x002A, 0x0231, 0x0503, 0x0415, 0x0807, 0x002B, 0x071D, 0xFFFF }, { 0x0130, 0x0214, + 0x0508, 0x0401, 0x0133, 0x0225, 0x061B, 0xFFFF }, { 0x0200, 0x0124, 0x0406, 0x0321, 0x0129, 0x100D, 0xFFFF }, { 0x031A, + 0x0D0B, 0x091F, 0xFFFF }, { 0x0413, 0x0705, 0x0517, 0xFFFF }, { 0x0212, 0x0034, 0x0323, 0x0035, 0x0227, 0xFFFF }, { + 0x0126, 0x080C, 0x0B09, 0xFFFF }, { 0x0411, 0x0619, 0x1A0F, 0xFFFF }, { 0x0210, 0x0331, 0x0603, 0x0515, 0x0907, 0x012B, + 0xFFFF }, { 0x0318, 0x002C, 0x0501, 0x0233, 0x0325, 0x071B, 0x002D, 0x081D, 0xFFFF }, { 0x0132, 0x0302, 0x0229, 0x110D, + 0xFFFF }, { 0x0128, 0x041C, 0x0421, 0x0E0B, 0x0A1F, 0xFFFF }, { 0x0220, 0x0513, 0x0617, 0xFFFF }, { 0x0135, 0x0805, + 0x0327, 0xFFFF }, { 0x0316, 0x051E, 0x0D0E, 0x0423, 0xFFFF }, { 0x0222, 0x0404, 0x070A, 0x0511, 0x0719, 0x0C09, 0x1B0F, + 0xFFFF }, { 0x0703, 0x0615, 0x0A07, 0x022B, 0xFFFF }, { 0x012A, 0x0431, 0x0601, 0x0333, 0x012D, 0x091D, 0xFFFF }, { + 0x0230, 0x0314, 0x0036, 0x0608, 0x0425, 0x0037, 0x0329, 0x081B, 0x120D, 0xFFFF }, { 0x0300, 0x0224, 0x0506, 0x0521, + 0x0F0B, 0x0B1F, 0xFFFF }, { 0x041A, 0x0613, 0x0717, 0xFFFF }, { 0x0235, 0x0905, 0xFFFF }, { 0x0312, 0x0134, 0x0523, + 0x0427, 0xFFFF }, { 0x0226, 0x090C, 0x002E, 0x0611, 0x0D09, 0x002F, 0xFFFF }, { 0x0715, 0x0B07, 0x0819, 0x032B, 0x1C0F, + 0xFFFF }, { 0x0310, 0x0531, 0x0701, 0x0803, 0x022D, 0x0A1D, 0xFFFF }, { 0x0418, 0x012C, 0x0433, 0x0525, 0x0137, 0x091B, + 0x130D, 0xFFFF }, { 0x0232, 0x0402, 0x0621, 0x0429, 0xFFFF }, { 0x0228, 0x051C, 0x0713, 0x100B, 0x0C1F, 0xFFFF }, { + 0x0320, 0x0335, 0x0A05, 0x0817, 0xFFFF }, { 0x0623, 0x0527, 0xFFFF }, { 0x0416, 0x061E, 0x0E0E, 0x0711, 0x0E09, 0x012F, + 0xFFFF }, { 0x0322, 0x0504, 0x080A, 0x0919, 0x1D0F, 0xFFFF }, { 0x0631, 0x0903, 0x0815, 0x0C07, 0x042B, 0x032D, 0x0B1D, + 0xFFFF }, { 0x022A, 0x0801, 0x0533, 0x0625, 0x0237, 0x0A1B, 0xFFFF }, { 0x0330, 0x0414, 0x0136, 0x0708, 0x0721, 0x0529, + 0x140D, 0xFFFF }, { 0x0400, 0x0324, 0x0606, 0x0038, 0x0039, 0x110B, 0x0D1F, 0xFFFF }, { 0x051A, 0x0813, 0x0B05, 0x0917, + 0xFFFF }, { 0x0723, 0x0435, 0x0627, 0xFFFF }, { 0x0412, 0x0234, 0x0F09, 0x022F, 0xFFFF }, { 0x0326, 0x0A0C, 0x012E, + 0x0811, 0x0A19, 0x1E0F, 0xFFFF }, { 0x0731, 0x0A03, 0x0915, 0x0D07, 0x052B, 0xFFFF }, { 0x0410, 0x0901, 0x0633, 0x0725, + 0x0337, 0x0B1B, 0x042D, 0x0C1D, 0xFFFF }, { 0x0518, 0x022C, 0x0629, 0x150D, 0xFFFF }, { 0x0332, 0x0502, 0x0821, 0x0139, + 0x120B, 0x0E1F, 0xFFFF }, { 0x0328, 0x061C, 0x0913, 0x0A17, 0xFFFF }, { 0x0420, 0x0535, 0x0C05, 0x0727, 0xFFFF }, { + 0x0823, 0x032F, 0xFFFF }, { 0x0516, 0x071E, 0x0F0E, 0x0911, 0x0B19, 0x1009, 0x1F0F, 0xFFFF }, { 0x0422, 0x0604, 0x090A, + 0x0B03, 0x0A15, 0x0E07, 0x062B, 0xFFFF }, { 0x0831, 0x0A01, 0x0733, 0x052D, 0x0D1D, 0xFFFF }, { 0x032A, 0x0825, 0x0437, + 0x0729, 0x0C1B, 0x160D, 0xFFFF }, { 0x0430, 0x0514, 0x0236, 0x0808, 0x0921, 0x0239, 0x130B, 0x0F1F, 0xFFFF }, { 0x0500, + 0x0424, 0x0706, 0x0138, 0x0A13, 0x0B17, 0xFFFF }, { 0x061A, 0x0635, 0x0D05, 0xFFFF }, { 0x0923, 0x0827, 0xFFFF }, { + 0x0512, 0x0334, 0x003A, 0x0A11, 0x1109, 0x003B, 0x042F, 0xFFFF }, { 0x0426, 0x0B0C, 0x022E, 0x0B15, 0x0F07, 0x0C19, + 0x072B, 0xFFFF }, { 0x0931, 0x0B01, 0x0C03, 0x062D, 0x0E1D, 0xFFFF }, { 0x0510, 0x0833, 0x0925, 0x0537, 0x0D1B, 0x170D, + 0xFFFF }, { 0x0618, 0x032C, 0x0A21, 0x0339, 0x0829, 0xFFFF }, { 0x0432, 0x0602, 0x0B13, 0x140B, 0x101F, 0xFFFF }, { + 0x0428, 0x071C, 0x0735, 0x0E05, 0x0C17, 0xFFFF }, { 0x0520, 0x0A23, 0x0927, 0xFFFF }, { 0x0B11, 0x1209, 0x013B, 0x052F, + 0xFFFF }, { 0x0616, 0x081E, 0x0D19, 0xFFFF }, { 0x0522, 0x0704, 0x0A0A, 0x0A31, 0x0D03, 0x0C15, 0x1007, 0x082B, 0x072D, + 0x0F1D, 0xFFFF }, { 0x0C01, 0x0933, 0x0A25, 0x0637, 0x0E1B, 0xFFFF }, { 0x042A, 0x0B21, 0x0929, 0x180D, 0xFFFF }, { + 0x0530, 0x0614, 0x0336, 0x0908, 0x0439, 0x150B, 0x111F, 0xFFFF }, { 0x0600, 0x0524, 0x0806, 0x0238, 0x0C13, 0x0F05, + 0x0D17, 0xFFFF }, { 0x071A, 0x0B23, 0x0835, 0x0A27, 0xFFFF }, { 0x1309, 0x023B, 0x062F, 0xFFFF }, { 0x0612, 0x0434, + 0x013A, 0x0C11, 0x0E19, 0xFFFF }, { 0x0526, 0x0C0C, 0x032E, 0x0B31, 0x0E03, 0x0D15, 0x1107, 0x092B, 0xFFFF }, { 0x0D01, + 0x0A33, 0x0B25, 0x0737, 0x0F1B, 0x082D, 0x101D, 0xFFFF }, { 0x0610, 0x0A29, 0x190D, 0xFFFF }, { 0x0718, 0x042C, 0x0C21, + 0x0539, 0x160B, 0x121F, 0xFFFF }, { 0x0532, 0x0702, 0x0D13, 0x0E17, 0xFFFF }, { 0x0528, 0x081C, 0x0935, 0x1005, 0x0B27, + 0xFFFF }, { 0x0620, 0x0C23, 0x033B, 0x072F, 0xFFFF }, { 0x0D11, 0x0F19, 0x1409, 0xFFFF }, { 0x0716, 0x003C, 0x091E, + 0x0F03, 0x0E15, 0x1207, 0x0A2B, 0x003D, 0xFFFF }, { 0x0622, 0x0804, 0x0B0A, 0x0C31, 0x0E01, 0x0B33, 0x092D, 0x111D, + 0xFFFF }, { 0x0C25, 0x0837, 0x0B29, 0x101B, 0x1A0D, 0xFFFF }, { 0x052A, 0x0D21, 0x0639, 0x170B, 0x131F, 0xFFFF }, { + 0x0630, 0x0714, 0x0436, 0x0A08, 0x0E13, 0x0F17, 0xFFFF }, { 0x0700, 0x0624, 0x0906, 0x0338, 0x0A35, 0x1105, 0xFFFF }, { + 0x081A, 0x0D23, 0x0C27, 0xFFFF }, { 0x0E11, 0x1509, 0x043B, 0x082F, 0xFFFF }, { 0x0712, 0x0534, 0x023A, 0x0F15, 0x1307, + 0x1019, 0x0B2B, 0x013D, 0xFFFF }, { 0x0626, 0x0D0C, 0x042E, 0x0D31, 0x0F01, 0x1003, 0x0A2D, 0x121D, 0xFFFF }, { 0x0C33, + 0x0D25, 0x0937, 0x111B, 0x1B0D, 0xFFFF }, { 0x0710, 0x0E21, 0x0739, 0x0C29, 0xFFFF }, { 0x0818, 0x052C, 0x0F13, 0x180B, + 0x141F, 0xFFFF }, { 0x0632, 0x0802, 0x0B35, 0x1205, 0x1017, 0xFFFF }, { 0x0628, 0x091C, 0x0E23, 0x0D27, 0xFFFF }, { + 0x0720, 0x0F11, 0x1609, 0x053B, 0x092F, 0xFFFF }, { 0x1119, 0x023D, 0xFFFF }, { 0x0816, 0x013C, 0x0A1E, 0x0E31, 0x1103, + 0x1015, 0x1407, 0x0C2B, 0x0B2D, 0x131D, 0xFFFF }, { 0x0722, 0x0904, 0x0C0A, 0x1001, 0x0D33, 0x0E25, 0x0A37, 0x121B, + 0xFFFF }, { 0x0F21, 0x0D29, 0x1C0D, 0xFFFF }, { 0x062A, 0x0839, 0x190B, 0x151F, 0xFFFF }, { 0x0730, 0x0814, 0x0536, + 0x0B08, 0x1013, 0x1305, 0x1117, 0xFFFF }, { 0x0800, 0x0724, 0x0A06, 0x0438, 0x0F23, 0x0C35, 0x0E27, 0xFFFF }, { 0x091A, + 0x1709, 0x063B, 0x0A2F, 0xFFFF }, { 0x1011, 0x1219, 0x033D, 0xFFFF }, { 0x0812, 0x0634, 0x033A, 0x0F31, 0x1203, 0x1115, + 0x1507, 0x0D2B, 0xFFFF }, { 0x0726, 0x0E0C, 0x052E, 0x1101, 0x0E33, 0x0F25, 0x0B37, 0x131B, 0x0C2D, 0x141D, 0xFFFF }, { + 0x0E29, 0x1D0D, 0xFFFF }, { 0x0810, 0x1021, 0x0939, 0x1A0B, 0x161F, 0xFFFF }, { 0x0918, 0x062C, 0x1113, 0x1217, 0xFFFF + }, { 0x0732, 0x0902, 0x0D35, 0x1405, 0x0F27, 0xFFFF }, { 0x0728, 0x0A1C, 0x1023, 0x073B, 0x0B2F, 0xFFFF }, { 0x0820, + 0x1111, 0x1319, 0x1809, 0xFFFF }, { 0x1303, 0x1215, 0x1607, 0x0E2B, 0x043D, 0xFFFF }, { 0x0916, 0x023C, 0x0B1E, 0x1031, + 0x1201, 0x0F33, 0x0D2D, 0x151D, 0xFFFF }, { 0x0822, 0x0A04, 0x0D0A, 0x1025, 0x0C37, 0x0F29, 0x141B, 0x1E0D, 0xFFFF }, { + 0x1121, 0x0A39, 0x1B0B, 0x171F, 0xFFFF }, { 0x072A, 0x1213, 0x1317, 0xFFFF }, { 0x0830, 0x0914, 0x0636, 0x0C08, 0x0E35, + 0x1505, 0xFFFF }, { 0x0900, 0x0824, 0x0B06, 0x0538, 0x1123, 0x1027, 0xFFFF }, { 0x0A1A, 0x1211, 0x1909, 0x083B, 0x0C2F, + 0xFFFF }, { 0x1315, 0x1707, 0x1419, 0x0F2B, 0x053D, 0xFFFF }, { 0x0912, 0x0734, 0x043A, 0x1131, 0x1301, 0x1403, 0x0E2D, + 0x161D, 0xFFFF }, { 0x0826, 0x0F0C, 0x062E, 0x1033, 0x1125, 0x0D37, 0x151B, 0x1F0D, 0xFFFF }, { 0x1221, 0x0B39, 0x1029, + 0xFFFF }, { 0x0910, 0x1313, 0x1C0B, 0x181F, 0xFFFF }, { 0x0A18, 0x072C, 0x0F35, 0x1605, 0x1417, 0xFFFF }, { 0x0832, + 0x0A02, 0x1223, 0x1127, 0xFFFF }, { 0x0828, 0x0B1C, 0x1311, 0x1A09, 0x093B, 0x0D2F, 0xFFFF }, { 0x0920, 0x1519, 0x063D, + 0xFFFF }, { 0x1231, 0x1503, 0x1415, 0x1807, 0x102B, 0x0F2D, 0x171D, 0xFFFF }, { 0x0A16, 0x033C, 0x0C1E, 0x1401, 0x1133, + 0x1225, 0x0E37, 0x161B, 0xFFFF }, { 0x0922, 0x0B04, 0x0E0A, 0x1321, 0x1129, 0xFFFF }, { 0x0C39, 0x1D0B, 0x191F, 0xFFFF + }, { 0x082A, 0x1413, 0x1705, 0x1517, 0xFFFF }, { 0x0930, 0x0A14, 0x0736, 0x0D08, 0x1323, 0x1035, 0x1227, 0xFFFF }, { + 0x0A00, 0x0924, 0x0C06, 0x0638, 0x1B09, 0x0A3B, 0x0E2F, 0xFFFF }, { 0x0B1A, 0x1411, 0x1619, 0x073D, 0xFFFF }, { 0x1331, + 0x1603, 0x1515, 0x1907, 0x112B, 0xFFFF }, { 0x0A12, 0x0834, 0x053A, 0x1501, 0x1233, 0x1325, 0x0F37, 0x171B, 0x102D, + 0x181D, 0xFFFF }, { 0x0926, 0x072E, 0x1229, 0xFFFF }, { 0x1421, 0x0D39, 0x1E0B, 0x1A1F, 0xFFFF }, { 0x0A10, 0x1513, + 0x1617, 0xFFFF }, { 0x0B18, 0x082C, 0x1135, 0x1805, 0x1327, 0xFFFF }, { 0x0932, 0x0B02, 0x1423, 0x0B3B, 0x0F2F, 0xFFFF + }, { 0x0928, 0x0C1C, 0x1511, 0x1719, 0x1C09, 0xFFFF }, { 0x0A20, 0x1703, 0x1615, 0x1A07, 0x122B, 0x083D, 0xFFFF }, { + 0x1431, 0x1601, 0x1333, 0x112D, 0x191D, 0xFFFF }, { 0x0B16, 0x043C, 0x0D1E, 0x1425, 0x1037, 0x1329, 0x181B, 0xFFFF }, { + 0x0A22, 0x0C04, 0x0F0A, 0x1521, 0x0E39, 0x1F0B, 0x1B1F, 0xFFFF }, { 0x1613, 0x1717, 0xFFFF }, { 0x092A, 0x1235, 0x1905, + 0xFFFF }, { 0x0A30, 0x0B14, 0x0836, 0x0E08, 0x1523, 0x1427, 0xFFFF }, { 0x0B00, 0x0A24, 0x0D06, 0x0738, 0x1611, 0x1D09, + 0x0C3B, 0x102F, 0xFFFF }, { 0x0C1A, 0x1715, 0x1B07, 0x1819, 0x132B, 0x093D, 0xFFFF }, { 0x1531, 0x1701, 0x1803, 0x122D, + 0x1A1D, 0xFFFF }, { 0x0B12, 0x0934, 0x063A, 0x1433, 0x1525, 0x1137, 0x191B, 0xFFFF }, { 0x0A26, 0x003E, 0x082E, 0x1621, + 0x0F39, 0x1429, 0x003F, 0xFFFF }, { 0x1713, 0x1C1F, 0xFFFF }, { 0x0B10, 0x1335, 0x1A05, 0x1817, 0xFFFF }, { 0x0C18, + 0x092C, 0x1623, 0x1527, 0xFFFF }, { 0x0A32, 0x0C02, 0x1711, 0x1E09, 0x0D3B, 0x112F, 0xFFFF }, { 0x0A28, 0x0D1C, 0x1919, + 0x0A3D, 0xFFFF }, { 0x0B20, 0x1631, 0x1903, 0x1815, 0x1C07, 0x142B, 0x132D, 0x1B1D, 0xFFFF }, { 0x1801, 0x1533, 0x1625, + 0x1237, 0x1A1B, 0xFFFF }, { 0x0C16, 0x053C, 0x0E1E, 0x1721, 0x1529, 0x013F, 0xFFFF }, { 0x0B22, 0x0D04, 0x1039, 0x1D1F, + 0xFFFF }, { 0x1813, 0x1B05, 0x1917, 0xFFFF }, { 0x0A2A, 0x1723, 0x1435, 0x1627, 0xFFFF }, { 0x0B30, 0x0C14, 0x0936, + 0x0F08, 0x1F09, 0x0E3B, 0x122F, 0xFFFF }, { 0x0C00, 0x0B24, 0x0E06, 0x0838, 0x1811, 0x1A19, 0x0B3D, 0xFFFF }, { 0x0D1A, + 0x1731, 0x1A03, 0x1915, 0x1D07, 0x152B, 0xFFFF }, { 0x1901, 0x1633, 0x1725, 0x1337, 0x1B1B, 0x142D, 0x1C1D, 0xFFFF }, { + 0x0C12, 0x0A34, 0x073A, 0x1629, 0x023F, 0xFFFF }, { 0x0B26, 0x013E, 0x092E, 0x1821, 0x1139, 0x1E1F, 0xFFFF }, { 0x1913, + 0x1A17, 0xFFFF }, { 0x0C10, 0x1535, 0x1C05, 0x1727, 0xFFFF }, { 0x0D18, 0x0A2C, 0x1823, 0x0F3B, 0x132F, 0xFFFF }, { + 0x0B32, 0x0D02, 0x1911, 0x1B19, 0xFFFF }, { 0x0B28, 0x0E1C, 0x1B03, 0x1A15, 0x1E07, 0x162B, 0x0C3D, 0xFFFF }, { 0x0C20, + 0x1831, 0x1A01, 0x1733, 0x152D, 0x1D1D, 0xFFFF }, { 0x1825, 0x1437, 0x1729, 0x1C1B, 0x033F, 0xFFFF }, { 0x0D16, 0x063C, + 0x0F1E, 0x1921, 0x1239, 0x1F1F, 0xFFFF }, { 0x0C22, 0x0E04, 0x1A13, 0x1B17, 0xFFFF }, { 0x1635, 0x1D05, 0xFFFF }, { + 0x0B2A, 0x1923, 0x1827, 0xFFFF }, { 0x0C30, 0x0D14, 0x0A36, 0x1A11, 0x103B, 0x142F, 0xFFFF }, { 0x0D00, 0x0C24, 0x0F06, + 0x0938, 0x1B15, 0x1F07, 0x1C19, 0x172B, 0x0D3D, 0xFFFF }, { 0x0E1A, 0x1931, 0x1B01, 0x1C03, 0x162D, 0x1E1D, 0xFFFF }, { + 0x1833, 0x1925, 0x1537, 0x1D1B, 0xFFFF }, { 0x0D12, 0x0B34, 0x083A, 0x1A21, 0x1339, 0x1829, 0x043F, 0xFFFF }, { 0x0C26, + 0x023E, 0x0A2E, 0x1B13, 0xFFFF }, { 0x1735, 0x1E05, 0x1C17, 0xFFFF }, { 0x0D10, 0x1A23, 0x1927, 0xFFFF }, { 0x0E18, + 0x0B2C, 0x1B11, 0x113B, 0x152F, 0xFFFF }, { 0x0C32, 0x0E02, 0x1D19, 0x0E3D, 0xFFFF }, { 0x0C28, 0x0F1C, 0x1A31, 0x1D03, + 0x1C15, 0x182B, 0x172D, 0x1F1D, 0xFFFF }, { 0x0D20, 0x1C01, 0x1933, 0x1A25, 0x1637, 0x1E1B, 0xFFFF }, { 0x1B21, 0x1929, + 0x053F, 0xFFFF }, { 0x0E16, 0x073C, 0x1439, 0xFFFF }, { 0x0D22, 0x0F04, 0x1C13, 0x1F05, 0x1D17, 0xFFFF }, { 0x1B23, + 0x1835, 0x1A27, 0xFFFF }, { 0x0C2A, 0x123B, 0x162F, 0xFFFF }, { 0x0D30, 0x0E14, 0x0B36, 0x1C11, 0x1E19, 0x0F3D, 0xFFFF + }, { 0x0E00, 0x0D24, 0x0A38, 0x1B31, 0x1E03, 0x1D15, 0x192B, 0xFFFF }, { 0x0F1A, 0x1D01, 0x1A33, 0x1B25, 0x1737, 0x1F1B, + 0x182D, 0xFFFF }, { 0x1A29, 0x063F, 0xFFFF }, { 0x0E12, 0x0C34, 0x093A, 0x1C21, 0x1539, 0xFFFF }, { 0x0D26, 0x033E, + 0x0B2E, 0x1D13, 0x1E17, 0xFFFF }, { 0x1935, 0x1B27, 0xFFFF }, { 0x0E10, 0x1C23, 0x133B, 0x172F, 0xFFFF }, { 0x0F18, + 0x0C2C, 0x1D11, 0x1F19, 0xFFFF }, { 0x0D32, 0x0F02, 0x1F03, 0x1E15, 0x1A2B, 0x103D, 0xFFFF }, { 0x0D28, 0x1C31, 0x1E01, + 0x1B33, 0x192D, 0xFFFF }, { 0x0E20, 0x1C25, 0x1837, 0x1B29, 0x073F, 0xFFFF }, { 0x1D21, 0x1639, 0xFFFF }, { 0x0F16, + 0x083C, 0x1E13, 0x1F17, 0xFFFF }, { 0x0E22, 0x1A35, 0xFFFF }, { 0x1D23, 0x1C27, 0xFFFF }, { 0x0D2A, 0x1E11, 0x143B, + 0x182F, 0xFFFF }, { 0x0E30, 0x0F14, 0x0C36, 0x1F15, 0x1B2B, 0x113D, 0xFFFF }, { 0x0F00, 0x0E24, 0x0B38, 0x1D31, 0x1F01, + 0x1A2D, 0xFFFF }, { 0x1C33, 0x1D25, 0x1937, 0xFFFF }, { 0x1E21, 0x1739, 0x1C29, 0x083F, 0xFFFF }, { 0x0F12, 0x0D34, + 0x0A3A, 0x1F13, 0xFFFF }, { 0x0E26, 0x043E, 0x0C2E, 0x1B35, 0xFFFF }, { 0x1E23, 0x1D27, 0xFFFF }, { 0x0F10, 0x1F11, + 0x153B, 0x192F, 0xFFFF }, { 0x0D2C, 0x123D, 0xFFFF }, + }; + + struct etc1_block + { + // big endian uint64: + // bit ofs: 56 48 40 32 24 16 8 0 + // byte ofs: b0, b1, b2, b3, b4, b5, b6, b7 + union + { + uint64 m_uint64; + uint8 m_bytes[8]; + }; + + uint8 m_low_color[2]; + uint8 m_high_color[2]; + + enum { cNumSelectorBytes = 4 }; + uint8 m_selectors[cNumSelectorBytes]; + + inline void clear() + { + zero_this(this); + } + + inline uint get_byte_bits(uint ofs, uint num) const + { + RG_ETC1_ASSERT((ofs + num) <= 64U); + RG_ETC1_ASSERT(num && (num <= 8U)); + RG_ETC1_ASSERT((ofs >> 3) == ((ofs + num - 1) >> 3)); + const uint byte_ofs = 7 - (ofs >> 3); + const uint byte_bit_ofs = ofs & 7; + return (m_bytes[byte_ofs] >> byte_bit_ofs) & ((1 << num) - 1); + } + + inline void set_byte_bits(uint ofs, uint num, uint bits) + { + RG_ETC1_ASSERT((ofs + num) <= 64U); + RG_ETC1_ASSERT(num && (num < 32U)); + RG_ETC1_ASSERT((ofs >> 3) == ((ofs + num - 1) >> 3)); + RG_ETC1_ASSERT(bits < (1U << num)); + const uint byte_ofs = 7 - (ofs >> 3); + const uint byte_bit_ofs = ofs & 7; + const uint mask = (1 << num) - 1; + m_bytes[byte_ofs] &= ~(mask << byte_bit_ofs); + m_bytes[byte_ofs] |= (bits << byte_bit_ofs); + } + + // false = left/right subblocks + // true = upper/lower subblocks + inline bool get_flip_bit() const + { + return (m_bytes[3] & 1) != 0; + } + + inline void set_flip_bit(bool flip) + { + m_bytes[3] &= ~1; + m_bytes[3] |= static_cast(flip); + } + + inline bool get_diff_bit() const + { + return (m_bytes[3] & 2) != 0; + } + + inline void set_diff_bit(bool diff) + { + m_bytes[3] &= ~2; + m_bytes[3] |= (static_cast(diff) << 1); + } + + // Returns intensity modifier table (0-7) used by subblock subblock_id. + // subblock_id=0 left/top (CW 1), 1=right/bottom (CW 2) + inline uint get_inten_table(uint subblock_id) const + { + RG_ETC1_ASSERT(subblock_id < 2); + const uint ofs = subblock_id ? 2 : 5; + return (m_bytes[3] >> ofs) & 7; + } + + // Sets intensity modifier table (0-7) used by subblock subblock_id (0 or 1) + inline void set_inten_table(uint subblock_id, uint t) + { + RG_ETC1_ASSERT(subblock_id < 2); + RG_ETC1_ASSERT(t < 8); + const uint ofs = subblock_id ? 2 : 5; + m_bytes[3] &= ~(7 << ofs); + m_bytes[3] |= (t << ofs); + } + + // Returned selector value ranges from 0-3 and is a direct index into g_etc1_inten_tables. + inline uint get_selector(uint x, uint y) const + { + RG_ETC1_ASSERT((x | y) < 4); + + const uint bit_index = x * 4 + y; + const uint byte_bit_ofs = bit_index & 7; + const uint8 *p = &m_bytes[7 - (bit_index >> 3)]; + const uint lsb = (p[0] >> byte_bit_ofs) & 1; + const uint msb = (p[-2] >> byte_bit_ofs) & 1; + const uint val = lsb | (msb << 1); + + return g_etc1_to_selector_index[val]; + } + + // Selector "val" ranges from 0-3 and is a direct index into g_etc1_inten_tables. + inline void set_selector(uint x, uint y, uint val) + { + RG_ETC1_ASSERT((x | y | val) < 4); + const uint bit_index = x * 4 + y; + + uint8 *p = &m_bytes[7 - (bit_index >> 3)]; + + const uint byte_bit_ofs = bit_index & 7; + const uint mask = 1 << byte_bit_ofs; + + const uint etc1_val = g_selector_index_to_etc1[val]; + + const uint lsb = etc1_val & 1; + const uint msb = etc1_val >> 1; + + p[0] &= ~mask; + p[0] |= (lsb << byte_bit_ofs); + + p[-2] &= ~mask; + p[-2] |= (msb << byte_bit_ofs); + } + + inline void set_base4_color(uint idx, uint16 c) + { + if (idx) + { + set_byte_bits(cETC1AbsColor4R2BitOffset, 4, (c >> 8) & 15); + set_byte_bits(cETC1AbsColor4G2BitOffset, 4, (c >> 4) & 15); + set_byte_bits(cETC1AbsColor4B2BitOffset, 4, c & 15); + } + else + { + set_byte_bits(cETC1AbsColor4R1BitOffset, 4, (c >> 8) & 15); + set_byte_bits(cETC1AbsColor4G1BitOffset, 4, (c >> 4) & 15); + set_byte_bits(cETC1AbsColor4B1BitOffset, 4, c & 15); + } + } + + inline uint16 get_base4_color(uint idx) const + { + uint r, g, b; + if (idx) + { + r = get_byte_bits(cETC1AbsColor4R2BitOffset, 4); + g = get_byte_bits(cETC1AbsColor4G2BitOffset, 4); + b = get_byte_bits(cETC1AbsColor4B2BitOffset, 4); + } + else + { + r = get_byte_bits(cETC1AbsColor4R1BitOffset, 4); + g = get_byte_bits(cETC1AbsColor4G1BitOffset, 4); + b = get_byte_bits(cETC1AbsColor4B1BitOffset, 4); + } + return static_cast(b | (g << 4U) | (r << 8U)); + } + + inline void set_base5_color(uint16 c) + { + set_byte_bits(cETC1BaseColor5RBitOffset, 5, (c >> 10) & 31); + set_byte_bits(cETC1BaseColor5GBitOffset, 5, (c >> 5) & 31); + set_byte_bits(cETC1BaseColor5BBitOffset, 5, c & 31); + } + + inline uint16 get_base5_color() const + { + const uint r = get_byte_bits(cETC1BaseColor5RBitOffset, 5); + const uint g = get_byte_bits(cETC1BaseColor5GBitOffset, 5); + const uint b = get_byte_bits(cETC1BaseColor5BBitOffset, 5); + return static_cast(b | (g << 5U) | (r << 10U)); + } + + void set_delta3_color(uint16 c) + { + set_byte_bits(cETC1DeltaColor3RBitOffset, 3, (c >> 6) & 7); + set_byte_bits(cETC1DeltaColor3GBitOffset, 3, (c >> 3) & 7); + set_byte_bits(cETC1DeltaColor3BBitOffset, 3, c & 7); + } + + inline uint16 get_delta3_color() const + { + const uint r = get_byte_bits(cETC1DeltaColor3RBitOffset, 3); + const uint g = get_byte_bits(cETC1DeltaColor3GBitOffset, 3); + const uint b = get_byte_bits(cETC1DeltaColor3BBitOffset, 3); + return static_cast(b | (g << 3U) | (r << 6U)); + } + + // Base color 5 + static uint16 pack_color5(const color_quad_u8& color, bool scaled, uint bias = 127U); + static uint16 pack_color5(uint r, uint g, uint b, bool scaled, uint bias = 127U); + + static color_quad_u8 unpack_color5(uint16 packed_color5, bool scaled, uint alpha = 255U); + static void unpack_color5(uint& r, uint& g, uint& b, uint16 packed_color, bool scaled); + + static bool unpack_color5(color_quad_u8& result, uint16 packed_color5, uint16 packed_delta3, bool scaled, uint alpha = 255U); + static bool unpack_color5(uint& r, uint& g, uint& b, uint16 packed_color5, uint16 packed_delta3, bool scaled, uint alpha = 255U); + + // Delta color 3 + // Inputs range from -4 to 3 (cETC1ColorDeltaMin to cETC1ColorDeltaMax) + static uint16 pack_delta3(int r, int g, int b); + + // Results range from -4 to 3 (cETC1ColorDeltaMin to cETC1ColorDeltaMax) + static void unpack_delta3(int& r, int& g, int& b, uint16 packed_delta3); + + // Abs color 4 + static uint16 pack_color4(const color_quad_u8& color, bool scaled, uint bias = 127U); + static uint16 pack_color4(uint r, uint g, uint b, bool scaled, uint bias = 127U); + + static color_quad_u8 unpack_color4(uint16 packed_color4, bool scaled, uint alpha = 255U); + static void unpack_color4(uint& r, uint& g, uint& b, uint16 packed_color4, bool scaled); + + // subblock colors + static void get_diff_subblock_colors(color_quad_u8* pDst, uint16 packed_color5, uint table_idx); + static bool get_diff_subblock_colors(color_quad_u8* pDst, uint16 packed_color5, uint16 packed_delta3, uint table_idx); + static void get_abs_subblock_colors(color_quad_u8* pDst, uint16 packed_color4, uint table_idx); + + static inline void unscaled_to_scaled_color(color_quad_u8& dst, const color_quad_u8& src, bool color4) + { + if (color4) + { + dst.r = src.r | (src.r << 4); + dst.g = src.g | (src.g << 4); + dst.b = src.b | (src.b << 4); + } + else + { + dst.r = (src.r >> 2) | (src.r << 3); + dst.g = (src.g >> 2) | (src.g << 3); + dst.b = (src.b >> 2) | (src.b << 3); + } + dst.a = src.a; + } + }; + + // Returns pointer to sorted array. + template + T* indirect_radix_sort(uint num_indices, T* pIndices0, T* pIndices1, const Q* pKeys, uint key_ofs, uint key_size, bool init_indices) + { + RG_ETC1_ASSERT((key_ofs >= 0) && (key_ofs < sizeof(T))); + RG_ETC1_ASSERT((key_size >= 1) && (key_size <= 4)); + + if (init_indices) + { + T* p = pIndices0; + T* q = pIndices0 + (num_indices >> 1) * 2; + uint i; + for (i = 0; p != q; p += 2, i += 2) + { + p[0] = static_cast(i); + p[1] = static_cast(i + 1); + } + + if (num_indices & 1) + *p = static_cast(i); + } + + uint hist[256 * 4]; + + memset(hist, 0, sizeof(hist[0]) * 256 * key_size); + +#define RG_ETC1_GET_KEY(p) (*(const uint*)((const uint8*)(pKeys + *(p)) + key_ofs)) +#define RG_ETC1_GET_KEY_FROM_INDEX(i) (*(const uint*)((const uint8*)(pKeys + (i)) + key_ofs)) + + if (key_size == 4) + { + T* p = pIndices0; + T* q = pIndices0 + num_indices; + for ( ; p != q; p++) + { + const uint key = RG_ETC1_GET_KEY(p); + + hist[ key & 0xFF]++; + hist[256 + ((key >> 8) & 0xFF)]++; + hist[512 + ((key >> 16) & 0xFF)]++; + hist[768 + ((key >> 24) & 0xFF)]++; + } + } + else if (key_size == 3) + { + T* p = pIndices0; + T* q = pIndices0 + num_indices; + for ( ; p != q; p++) + { + const uint key = RG_ETC1_GET_KEY(p); + + hist[ key & 0xFF]++; + hist[256 + ((key >> 8) & 0xFF)]++; + hist[512 + ((key >> 16) & 0xFF)]++; + } + } + else if (key_size == 2) + { + T* p = pIndices0; + T* q = pIndices0 + (num_indices >> 1) * 2; + + for ( ; p != q; p += 2) + { + const uint key0 = RG_ETC1_GET_KEY(p); + const uint key1 = RG_ETC1_GET_KEY(p+1); + + hist[ key0 & 0xFF]++; + hist[256 + ((key0 >> 8) & 0xFF)]++; + + hist[ key1 & 0xFF]++; + hist[256 + ((key1 >> 8) & 0xFF)]++; + } + + if (num_indices & 1) + { + const uint key = RG_ETC1_GET_KEY(p); + + hist[ key & 0xFF]++; + hist[256 + ((key >> 8) & 0xFF)]++; + } + } + else + { + RG_ETC1_ASSERT(key_size == 1); + if (key_size != 1) + return NULL; + + T* p = pIndices0; + T* q = pIndices0 + (num_indices >> 1) * 2; + + for ( ; p != q; p += 2) + { + const uint key0 = RG_ETC1_GET_KEY(p); + const uint key1 = RG_ETC1_GET_KEY(p+1); + + hist[key0 & 0xFF]++; + hist[key1 & 0xFF]++; + } + + if (num_indices & 1) + { + const uint key = RG_ETC1_GET_KEY(p); + + hist[key & 0xFF]++; + } + } + + T* pCur = pIndices0; + T* pNew = pIndices1; + + for (uint pass = 0; pass < key_size; pass++) + { + const uint* pHist = &hist[pass << 8]; + + uint offsets[256]; + + uint cur_ofs = 0; + for (uint i = 0; i < 256; i += 2) + { + offsets[i] = cur_ofs; + cur_ofs += pHist[i]; + + offsets[i+1] = cur_ofs; + cur_ofs += pHist[i+1]; + } + + const uint pass_shift = pass << 3; + + T* p = pCur; + T* q = pCur + (num_indices >> 1) * 2; + + for ( ; p != q; p += 2) + { + uint index0 = p[0]; + uint index1 = p[1]; + + uint c0 = (RG_ETC1_GET_KEY_FROM_INDEX(index0) >> pass_shift) & 0xFF; + uint c1 = (RG_ETC1_GET_KEY_FROM_INDEX(index1) >> pass_shift) & 0xFF; + + if (c0 == c1) + { + uint dst_offset0 = offsets[c0]; + + offsets[c0] = dst_offset0 + 2; + + pNew[dst_offset0] = static_cast(index0); + pNew[dst_offset0 + 1] = static_cast(index1); + } + else + { + uint dst_offset0 = offsets[c0]++; + uint dst_offset1 = offsets[c1]++; + + pNew[dst_offset0] = static_cast(index0); + pNew[dst_offset1] = static_cast(index1); + } + } + + if (num_indices & 1) + { + uint index = *p; + uint c = (RG_ETC1_GET_KEY_FROM_INDEX(index) >> pass_shift) & 0xFF; + + uint dst_offset = offsets[c]; + offsets[c] = dst_offset + 1; + + pNew[dst_offset] = static_cast(index); + } + + T* t = pCur; + pCur = pNew; + pNew = t; + } + + return pCur; + } + +#undef RG_ETC1_GET_KEY +#undef RG_ETC1_GET_KEY_FROM_INDEX + + uint16 etc1_block::pack_color5(const color_quad_u8& color, bool scaled, uint bias) + { + return pack_color5(color.r, color.g, color.b, scaled, bias); + } + + uint16 etc1_block::pack_color5(uint r, uint g, uint b, bool scaled, uint bias) + { + if (scaled) + { + r = (r * 31U + bias) / 255U; + g = (g * 31U + bias) / 255U; + b = (b * 31U + bias) / 255U; + } + + r = rg_etc1::minimum(r, 31U); + g = rg_etc1::minimum(g, 31U); + b = rg_etc1::minimum(b, 31U); + + return static_cast(b | (g << 5U) | (r << 10U)); + } + + color_quad_u8 etc1_block::unpack_color5(uint16 packed_color5, bool scaled, uint alpha) + { + uint b = packed_color5 & 31U; + uint g = (packed_color5 >> 5U) & 31U; + uint r = (packed_color5 >> 10U) & 31U; + + if (scaled) + { + b = (b << 3U) | (b >> 2U); + g = (g << 3U) | (g >> 2U); + r = (r << 3U) | (r >> 2U); + } + + return color_quad_u8(cNoClamp, r, g, b, rg_etc1::minimum(alpha, 255U)); + } + + void etc1_block::unpack_color5(uint& r, uint& g, uint& b, uint16 packed_color5, bool scaled) + { + color_quad_u8 c(unpack_color5(packed_color5, scaled, 0)); + r = c.r; + g = c.g; + b = c.b; + } + + bool etc1_block::unpack_color5(color_quad_u8& result, uint16 packed_color5, uint16 packed_delta3, bool scaled, uint alpha) + { + int dc_r, dc_g, dc_b; + unpack_delta3(dc_r, dc_g, dc_b, packed_delta3); + + int b = (packed_color5 & 31U) + dc_b; + int g = ((packed_color5 >> 5U) & 31U) + dc_g; + int r = ((packed_color5 >> 10U) & 31U) + dc_r; + + bool success = true; + if (static_cast(r | g | b) > 31U) + { + success = false; + r = rg_etc1::clamp(r, 0, 31); + g = rg_etc1::clamp(g, 0, 31); + b = rg_etc1::clamp(b, 0, 31); + } + + if (scaled) + { + b = (b << 3U) | (b >> 2U); + g = (g << 3U) | (g >> 2U); + r = (r << 3U) | (r >> 2U); + } + + result.set_noclamp_rgba(r, g, b, rg_etc1::minimum(alpha, 255U)); + return success; + } + + bool etc1_block::unpack_color5(uint& r, uint& g, uint& b, uint16 packed_color5, uint16 packed_delta3, bool scaled, uint alpha) + { + color_quad_u8 result; + const bool success = unpack_color5(result, packed_color5, packed_delta3, scaled, alpha); + r = result.r; + g = result.g; + b = result.b; + return success; + } + + uint16 etc1_block::pack_delta3(int r, int g, int b) + { + RG_ETC1_ASSERT((r >= cETC1ColorDeltaMin) && (r <= cETC1ColorDeltaMax)); + RG_ETC1_ASSERT((g >= cETC1ColorDeltaMin) && (g <= cETC1ColorDeltaMax)); + RG_ETC1_ASSERT((b >= cETC1ColorDeltaMin) && (b <= cETC1ColorDeltaMax)); + if (r < 0) r += 8; + if (g < 0) g += 8; + if (b < 0) b += 8; + return static_cast(b | (g << 3) | (r << 6)); + } + + void etc1_block::unpack_delta3(int& r, int& g, int& b, uint16 packed_delta3) + { + r = (packed_delta3 >> 6) & 7; + g = (packed_delta3 >> 3) & 7; + b = packed_delta3 & 7; + if (r >= 4) r -= 8; + if (g >= 4) g -= 8; + if (b >= 4) b -= 8; + } + + uint16 etc1_block::pack_color4(const color_quad_u8& color, bool scaled, uint bias) + { + return pack_color4(color.r, color.g, color.b, scaled, bias); + } + + uint16 etc1_block::pack_color4(uint r, uint g, uint b, bool scaled, uint bias) + { + if (scaled) + { + r = (r * 15U + bias) / 255U; + g = (g * 15U + bias) / 255U; + b = (b * 15U + bias) / 255U; + } + + r = rg_etc1::minimum(r, 15U); + g = rg_etc1::minimum(g, 15U); + b = rg_etc1::minimum(b, 15U); + + return static_cast(b | (g << 4U) | (r << 8U)); + } + + color_quad_u8 etc1_block::unpack_color4(uint16 packed_color4, bool scaled, uint alpha) + { + uint b = packed_color4 & 15U; + uint g = (packed_color4 >> 4U) & 15U; + uint r = (packed_color4 >> 8U) & 15U; + + if (scaled) + { + b = (b << 4U) | b; + g = (g << 4U) | g; + r = (r << 4U) | r; + } + + return color_quad_u8(cNoClamp, r, g, b, rg_etc1::minimum(alpha, 255U)); + } + + void etc1_block::unpack_color4(uint& r, uint& g, uint& b, uint16 packed_color4, bool scaled) + { + color_quad_u8 c(unpack_color4(packed_color4, scaled, 0)); + r = c.r; + g = c.g; + b = c.b; + } + + void etc1_block::get_diff_subblock_colors(color_quad_u8* pDst, uint16 packed_color5, uint table_idx) + { + RG_ETC1_ASSERT(table_idx < cETC1IntenModifierValues); + const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; + + uint r, g, b; + unpack_color5(r, g, b, packed_color5, true); + + const int ir = static_cast(r), ig = static_cast(g), ib = static_cast(b); + + const int y0 = pInten_modifer_table[0]; + pDst[0].set(ir + y0, ig + y0, ib + y0); + + const int y1 = pInten_modifer_table[1]; + pDst[1].set(ir + y1, ig + y1, ib + y1); + + const int y2 = pInten_modifer_table[2]; + pDst[2].set(ir + y2, ig + y2, ib + y2); + + const int y3 = pInten_modifer_table[3]; + pDst[3].set(ir + y3, ig + y3, ib + y3); + } + + bool etc1_block::get_diff_subblock_colors(color_quad_u8* pDst, uint16 packed_color5, uint16 packed_delta3, uint table_idx) + { + RG_ETC1_ASSERT(table_idx < cETC1IntenModifierValues); + const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; + + uint r, g, b; + bool success = unpack_color5(r, g, b, packed_color5, packed_delta3, true); + + const int ir = static_cast(r), ig = static_cast(g), ib = static_cast(b); + + const int y0 = pInten_modifer_table[0]; + pDst[0].set(ir + y0, ig + y0, ib + y0); + + const int y1 = pInten_modifer_table[1]; + pDst[1].set(ir + y1, ig + y1, ib + y1); + + const int y2 = pInten_modifer_table[2]; + pDst[2].set(ir + y2, ig + y2, ib + y2); + + const int y3 = pInten_modifer_table[3]; + pDst[3].set(ir + y3, ig + y3, ib + y3); + + return success; + } + + void etc1_block::get_abs_subblock_colors(color_quad_u8* pDst, uint16 packed_color4, uint table_idx) + { + RG_ETC1_ASSERT(table_idx < cETC1IntenModifierValues); + const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; + + uint r, g, b; + unpack_color4(r, g, b, packed_color4, true); + + const int ir = static_cast(r), ig = static_cast(g), ib = static_cast(b); + + const int y0 = pInten_modifer_table[0]; + pDst[0].set(ir + y0, ig + y0, ib + y0); + + const int y1 = pInten_modifer_table[1]; + pDst[1].set(ir + y1, ig + y1, ib + y1); + + const int y2 = pInten_modifer_table[2]; + pDst[2].set(ir + y2, ig + y2, ib + y2); + + const int y3 = pInten_modifer_table[3]; + pDst[3].set(ir + y3, ig + y3, ib + y3); + } + + bool unpack_etc1_block(const void* pETC1_block, unsigned int* pDst_pixels_rgba, int stride, bool preserve_alpha) + { + color_quad_u8* pDst = reinterpret_cast(pDst_pixels_rgba); + const etc1_block& block = *static_cast(pETC1_block); + + const bool diff_flag = block.get_diff_bit(); + const bool flip_flag = block.get_flip_bit(); + const uint table_index0 = block.get_inten_table(0); + const uint table_index1 = block.get_inten_table(1); + + color_quad_u8 subblock_colors0[4]; + color_quad_u8 subblock_colors1[4]; + bool success = true; + + if (diff_flag) + { + const uint16 base_color5 = block.get_base5_color(); + const uint16 delta_color3 = block.get_delta3_color(); + etc1_block::get_diff_subblock_colors(subblock_colors0, base_color5, table_index0); + + if (!etc1_block::get_diff_subblock_colors(subblock_colors1, base_color5, delta_color3, table_index1)) + success = false; + } + else + { + const uint16 base_color4_0 = block.get_base4_color(0); + etc1_block::get_abs_subblock_colors(subblock_colors0, base_color4_0, table_index0); + + const uint16 base_color4_1 = block.get_base4_color(1); + etc1_block::get_abs_subblock_colors(subblock_colors1, base_color4_1, table_index1); + } + + if (preserve_alpha) + { + if (flip_flag) + { + for (uint y = 0; y < 2; y++) + { + pDst[0].set_rgb(subblock_colors0[block.get_selector(0, y)]); + pDst[1].set_rgb(subblock_colors0[block.get_selector(1, y)]); + pDst[2].set_rgb(subblock_colors0[block.get_selector(2, y)]); + pDst[3].set_rgb(subblock_colors0[block.get_selector(3, y)]); + pDst += stride; + } + + for (uint y = 2; y < 4; y++) + { + pDst[0].set_rgb(subblock_colors1[block.get_selector(0, y)]); + pDst[1].set_rgb(subblock_colors1[block.get_selector(1, y)]); + pDst[2].set_rgb(subblock_colors1[block.get_selector(2, y)]); + pDst[3].set_rgb(subblock_colors1[block.get_selector(3, y)]); + pDst += stride; + } + } + else + { + for (uint y = 0; y < 4; y++) + { + pDst[0].set_rgb(subblock_colors0[block.get_selector(0, y)]); + pDst[1].set_rgb(subblock_colors0[block.get_selector(1, y)]); + pDst[2].set_rgb(subblock_colors1[block.get_selector(2, y)]); + pDst[3].set_rgb(subblock_colors1[block.get_selector(3, y)]); + pDst += stride; + } + } + } + else + { + if (flip_flag) + { + // 0000 + // 0000 + // 1111 + // 1111 + for (uint y = 0; y < 2; y++) + { + pDst[0] = subblock_colors0[block.get_selector(0, y)]; + pDst[1] = subblock_colors0[block.get_selector(1, y)]; + pDst[2] = subblock_colors0[block.get_selector(2, y)]; + pDst[3] = subblock_colors0[block.get_selector(3, y)]; + pDst += stride; + } + + for (uint y = 2; y < 4; y++) + { + pDst[0] = subblock_colors1[block.get_selector(0, y)]; + pDst[1] = subblock_colors1[block.get_selector(1, y)]; + pDst[2] = subblock_colors1[block.get_selector(2, y)]; + pDst[3] = subblock_colors1[block.get_selector(3, y)]; + pDst += stride; + } + } + else + { + // 0011 + // 0011 + // 0011 + // 0011 + for (uint y = 0; y < 4; y++) + { + pDst[0] = subblock_colors0[block.get_selector(0, y)]; + pDst[1] = subblock_colors0[block.get_selector(1, y)]; + pDst[2] = subblock_colors1[block.get_selector(2, y)]; + pDst[3] = subblock_colors1[block.get_selector(3, y)]; + pDst += stride; + } + } + } + + return success; + } + + struct etc1_solution_coordinates + { + inline etc1_solution_coordinates() : + m_unscaled_color(0, 0, 0, 0), + m_inten_table(0), + m_color4(false) + { + } + + inline etc1_solution_coordinates(uint r, uint g, uint b, uint inten_table, bool color4) : + m_unscaled_color(r, g, b, 255), + m_inten_table(inten_table), + m_color4(color4) + { + } + + inline etc1_solution_coordinates(const color_quad_u8& c, uint inten_table, bool color4) : + m_unscaled_color(c), + m_inten_table(inten_table), + m_color4(color4) + { + } + + inline etc1_solution_coordinates(const etc1_solution_coordinates& other) + { + *this = other; + } + + inline etc1_solution_coordinates& operator= (const etc1_solution_coordinates& rhs) + { + m_unscaled_color = rhs.m_unscaled_color; + m_inten_table = rhs.m_inten_table; + m_color4 = rhs.m_color4; + return *this; + } + + inline void clear() + { + m_unscaled_color.clear(); + m_inten_table = 0; + m_color4 = false; + } + + inline color_quad_u8 get_scaled_color() const + { + int br, bg, bb; + if (m_color4) + { + br = m_unscaled_color.r | (m_unscaled_color.r << 4); + bg = m_unscaled_color.g | (m_unscaled_color.g << 4); + bb = m_unscaled_color.b | (m_unscaled_color.b << 4); + } + else + { + br = (m_unscaled_color.r >> 2) | (m_unscaled_color.r << 3); + bg = (m_unscaled_color.g >> 2) | (m_unscaled_color.g << 3); + bb = (m_unscaled_color.b >> 2) | (m_unscaled_color.b << 3); + } + return color_quad_u8(br, bg, bb); + } + + inline void get_block_colors(color_quad_u8* pBlock_colors) + { + int br, bg, bb; + if (m_color4) + { + br = m_unscaled_color.r | (m_unscaled_color.r << 4); + bg = m_unscaled_color.g | (m_unscaled_color.g << 4); + bb = m_unscaled_color.b | (m_unscaled_color.b << 4); + } + else + { + br = (m_unscaled_color.r >> 2) | (m_unscaled_color.r << 3); + bg = (m_unscaled_color.g >> 2) | (m_unscaled_color.g << 3); + bb = (m_unscaled_color.b >> 2) | (m_unscaled_color.b << 3); + } + const int* pInten_table = g_etc1_inten_tables[m_inten_table]; + pBlock_colors[0].set(br + pInten_table[0], bg + pInten_table[0], bb + pInten_table[0]); + pBlock_colors[1].set(br + pInten_table[1], bg + pInten_table[1], bb + pInten_table[1]); + pBlock_colors[2].set(br + pInten_table[2], bg + pInten_table[2], bb + pInten_table[2]); + pBlock_colors[3].set(br + pInten_table[3], bg + pInten_table[3], bb + pInten_table[3]); + } + + color_quad_u8 m_unscaled_color; + uint m_inten_table; + bool m_color4; + }; + + class etc1_optimizer + { + etc1_optimizer(const etc1_optimizer&); + etc1_optimizer& operator= (const etc1_optimizer&); + + public: + etc1_optimizer() + { + clear(); + } + + void clear() + { + m_pParams = NULL; + m_pResult = NULL; + m_pSorted_luma = NULL; + m_pSorted_luma_indices = NULL; + } + + struct params : etc1_pack_params + { + params() + { + clear(); + } + + params(const etc1_pack_params& base_params) : + etc1_pack_params(base_params) + { + clear_optimizer_params(); + } + + void clear() + { + etc1_pack_params::clear(); + clear_optimizer_params(); + } + + void clear_optimizer_params() + { + m_num_src_pixels = 0; + m_pSrc_pixels = 0; + + m_use_color4 = false; + static const int s_default_scan_delta[] = { 0 }; + m_pScan_deltas = s_default_scan_delta; + m_scan_delta_size = 1; + + m_base_color5.clear(); + m_constrain_against_base_color5 = false; + } + + uint m_num_src_pixels; + const color_quad_u8* m_pSrc_pixels; + + bool m_use_color4; + const int* m_pScan_deltas; + uint m_scan_delta_size; + + color_quad_u8 m_base_color5; + bool m_constrain_against_base_color5; + }; + + struct results + { + uint64 m_error; + color_quad_u8 m_block_color_unscaled; + uint m_block_inten_table; + uint m_n; + uint8* m_pSelectors; + bool m_block_color4; + + inline results& operator= (const results& rhs) + { + m_block_color_unscaled = rhs.m_block_color_unscaled; + m_block_color4 = rhs.m_block_color4; + m_block_inten_table = rhs.m_block_inten_table; + m_error = rhs.m_error; + RG_ETC1_ASSERT(m_n == rhs.m_n); + memcpy(m_pSelectors, rhs.m_pSelectors, rhs.m_n); + return *this; + } + }; + + void init(const params& params, results& result); + bool compute(); + + private: + struct potential_solution + { + potential_solution() : m_coords(), m_error(cUINT64_MAX), m_valid(false) + { + } + + etc1_solution_coordinates m_coords; + uint8 m_selectors[8]; + uint64 m_error; + bool m_valid; + + void clear() + { + m_coords.clear(); + m_error = cUINT64_MAX; + m_valid = false; + } + }; + + const params* m_pParams; + results* m_pResult; + + int m_limit; + + vec3F m_avg_color; + int m_br, m_bg, m_bb; + uint16 m_luma[8]; + uint32 m_sorted_luma[2][8]; + const uint32* m_pSorted_luma_indices; + uint32* m_pSorted_luma; + + uint8 m_selectors[8]; + uint8 m_best_selectors[8]; + + potential_solution m_best_solution; + potential_solution m_trial_solution; + uint8 m_temp_selectors[8]; + + bool evaluate_solution(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution); + bool evaluate_solution_fast(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution); + }; + + bool etc1_optimizer::compute() + { + const uint n = m_pParams->m_num_src_pixels; + const int scan_delta_size = m_pParams->m_scan_delta_size; + + // Scan through a subset of the 3D lattice centered around the avg block color trying each 3D (555 or 444) lattice point as a potential block color. + // Each time a better solution is found try to refine the current solution's block color based of the current selectors and intensity table index. + for (int zdi = 0; zdi < scan_delta_size; zdi++) + { + const int zd = m_pParams->m_pScan_deltas[zdi]; + const int mbb = m_bb + zd; + if (mbb < 0) continue; else if (mbb > m_limit) break; + + for (int ydi = 0; ydi < scan_delta_size; ydi++) + { + const int yd = m_pParams->m_pScan_deltas[ydi]; + const int mbg = m_bg + yd; + if (mbg < 0) continue; else if (mbg > m_limit) break; + + for (int xdi = 0; xdi < scan_delta_size; xdi++) + { + const int xd = m_pParams->m_pScan_deltas[xdi]; + const int mbr = m_br + xd; + if (mbr < 0) continue; else if (mbr > m_limit) break; + + etc1_solution_coordinates coords(mbr, mbg, mbb, 0, m_pParams->m_use_color4); + if (m_pParams->m_quality == cHighQuality) + { + if (!evaluate_solution(coords, m_trial_solution, &m_best_solution)) + continue; + } + else + { + if (!evaluate_solution_fast(coords, m_trial_solution, &m_best_solution)) + continue; + } + + // Now we have the input block, the avg. color of the input pixels, a set of trial selector indices, and the block color+intensity index. + // Now, for each component, attempt to refine the current solution by solving a simple linear equation. For example, for 4 colors: + // The goal is: + // pixel0 - (block_color+inten_table[selector0]) + pixel1 - (block_color+inten_table[selector1]) + pixel2 - (block_color+inten_table[selector2]) + pixel3 - (block_color+inten_table[selector3]) = 0 + // Rearranging this: + // (pixel0 + pixel1 + pixel2 + pixel3) - (block_color+inten_table[selector0]) - (block_color+inten_table[selector1]) - (block_color+inten_table[selector2]) - (block_color+inten_table[selector3]) = 0 + // (pixel0 + pixel1 + pixel2 + pixel3) - block_color - inten_table[selector0] - block_color-inten_table[selector1] - block_color-inten_table[selector2] - block_color-inten_table[selector3] = 0 + // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - inten_table[selector0] - inten_table[selector1] - inten_table[selector2] - inten_table[selector3] = 0 + // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3]) = 0 + // (pixel0 + pixel1 + pixel2 + pixel3)/4 - block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4 = 0 + // block_color = (pixel0 + pixel1 + pixel2 + pixel3)/4 - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4 + // So what this means: + // optimal_block_color = avg_input - avg_inten_delta + // So the optimal block color can be computed by taking the average block color and subtracting the current average of the intensity delta. + // Unfortunately, optimal_block_color must then be quantized to 555 or 444 so it's not always possible to improve matters using this formula. + // Also, the above formula is for unclamped intensity deltas. The actual implementation takes into account clamping. + + const uint max_refinement_trials = (m_pParams->m_quality == cLowQuality) ? 2 : (((xd | yd | zd) == 0) ? 4 : 2); + for (uint refinement_trial = 0; refinement_trial < max_refinement_trials; refinement_trial++) + { + const uint8* pSelectors = m_best_solution.m_selectors; + const int* pInten_table = g_etc1_inten_tables[m_best_solution.m_coords.m_inten_table]; + + int delta_sum_r = 0, delta_sum_g = 0, delta_sum_b = 0; + const color_quad_u8 base_color(m_best_solution.m_coords.get_scaled_color()); + for (uint r = 0; r < n; r++) + { + const uint s = *pSelectors++; + const int yd = pInten_table[s]; + // Compute actual delta being applied to each pixel, taking into account clamping. + delta_sum_r += rg_etc1::clamp(base_color.r + yd, 0, 255) - base_color.r; + delta_sum_g += rg_etc1::clamp(base_color.g + yd, 0, 255) - base_color.g; + delta_sum_b += rg_etc1::clamp(base_color.b + yd, 0, 255) - base_color.b; + } + if ((!delta_sum_r) && (!delta_sum_g) && (!delta_sum_b)) + break; + const float avg_delta_r_f = static_cast(delta_sum_r) / n; + const float avg_delta_g_f = static_cast(delta_sum_g) / n; + const float avg_delta_b_f = static_cast(delta_sum_b) / n; + const int br1 = rg_etc1::clamp(static_cast((m_avg_color[0] - avg_delta_r_f) * m_limit / 255.0f + .5f), 0, m_limit); + const int bg1 = rg_etc1::clamp(static_cast((m_avg_color[1] - avg_delta_g_f) * m_limit / 255.0f + .5f), 0, m_limit); + const int bb1 = rg_etc1::clamp(static_cast((m_avg_color[2] - avg_delta_b_f) * m_limit / 255.0f + .5f), 0, m_limit); + + bool skip = false; + + if ((mbr == br1) && (mbg == bg1) && (mbb == bb1)) + skip = true; + else if ((br1 == m_best_solution.m_coords.m_unscaled_color.r) && (bg1 == m_best_solution.m_coords.m_unscaled_color.g) && (bb1 == m_best_solution.m_coords.m_unscaled_color.b)) + skip = true; + else if ((m_br == br1) && (m_bg == bg1) && (m_bb == bb1)) + skip = true; + + if (skip) + break; + + etc1_solution_coordinates coords1(br1, bg1, bb1, 0, m_pParams->m_use_color4); + if (m_pParams->m_quality == cHighQuality) + { + if (!evaluate_solution(coords1, m_trial_solution, &m_best_solution)) + break; + } + else + { + if (!evaluate_solution_fast(coords1, m_trial_solution, &m_best_solution)) + break; + } + + } // refinement_trial + + } // xdi + } // ydi + } // zdi + + if (!m_best_solution.m_valid) + { + m_pResult->m_error = cUINT32_MAX; + return false; + } + + const uint8* pSelectors = m_best_solution.m_selectors; + +#ifdef RG_ETC1_BUILD_DEBUG + { + color_quad_u8 block_colors[4]; + m_best_solution.m_coords.get_block_colors(block_colors); + + const color_quad_u8* pSrc_pixels = m_pParams->m_pSrc_pixels; + uint64 actual_error = 0; + for (uint i = 0; i < n; i++) + actual_error += pSrc_pixels[i].squared_distance_rgb(block_colors[pSelectors[i]]); + + RG_ETC1_ASSERT(actual_error == m_best_solution.m_error); + } +#endif + + m_pResult->m_error = m_best_solution.m_error; + + m_pResult->m_block_color_unscaled = m_best_solution.m_coords.m_unscaled_color; + m_pResult->m_block_color4 = m_best_solution.m_coords.m_color4; + + m_pResult->m_block_inten_table = m_best_solution.m_coords.m_inten_table; + memcpy(m_pResult->m_pSelectors, pSelectors, n); + m_pResult->m_n = n; + + return true; + } + + void etc1_optimizer::init(const params& p, results& r) + { + // This version is hardcoded for 8 pixel subblocks. + RG_ETC1_ASSERT(p.m_num_src_pixels == 8); + + m_pParams = &p; + m_pResult = &r; + + const uint n = 8; + + m_limit = m_pParams->m_use_color4 ? 15 : 31; + + vec3F avg_color(0.0f); + + for (uint i = 0; i < n; i++) + { + const color_quad_u8& c = m_pParams->m_pSrc_pixels[i]; + const vec3F fc(c.r, c.g, c.b); + + avg_color += fc; + + m_luma[i] = static_cast(c.r + c.g + c.b); + m_sorted_luma[0][i] = i; + } + avg_color *= (1.0f / static_cast(n)); + m_avg_color = avg_color; + + m_br = rg_etc1::clamp(static_cast(m_avg_color[0] * m_limit / 255.0f + .5f), 0, m_limit); + m_bg = rg_etc1::clamp(static_cast(m_avg_color[1] * m_limit / 255.0f + .5f), 0, m_limit); + m_bb = rg_etc1::clamp(static_cast(m_avg_color[2] * m_limit / 255.0f + .5f), 0, m_limit); + + if (m_pParams->m_quality <= cMediumQuality) + { + m_pSorted_luma_indices = indirect_radix_sort(n, m_sorted_luma[0], m_sorted_luma[1], m_luma, 0, sizeof(m_luma[0]), false); + m_pSorted_luma = m_sorted_luma[0]; + if (m_pSorted_luma_indices == m_sorted_luma[0]) + m_pSorted_luma = m_sorted_luma[1]; + + for (uint i = 0; i < n; i++) + m_pSorted_luma[i] = m_luma[m_pSorted_luma_indices[i]]; + } + + m_best_solution.m_coords.clear(); + m_best_solution.m_valid = false; + m_best_solution.m_error = cUINT64_MAX; + } + + bool etc1_optimizer::evaluate_solution(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution) + { + trial_solution.m_valid = false; + + if (m_pParams->m_constrain_against_base_color5) + { + const int dr = coords.m_unscaled_color.r - m_pParams->m_base_color5.r; + const int dg = coords.m_unscaled_color.g - m_pParams->m_base_color5.g; + const int db = coords.m_unscaled_color.b - m_pParams->m_base_color5.b; + + if ((rg_etc1::minimum(dr, dg, db) < cETC1ColorDeltaMin) || (rg_etc1::maximum(dr, dg, db) > cETC1ColorDeltaMax)) + return false; + } + + const color_quad_u8 base_color(coords.get_scaled_color()); + + const uint n = 8; + + trial_solution.m_error = cUINT64_MAX; + + for (uint inten_table = 0; inten_table < cETC1IntenModifierValues; inten_table++) + { + const int* pInten_table = g_etc1_inten_tables[inten_table]; + + color_quad_u8 block_colors[4]; + for (uint s = 0; s < 4; s++) + { + const int yd = pInten_table[s]; + block_colors[s].set(base_color.r + yd, base_color.g + yd, base_color.b + yd, 0); + } + + uint64 total_error = 0; + + const color_quad_u8* pSrc_pixels = m_pParams->m_pSrc_pixels; + for (uint c = 0; c < n; c++) + { + const color_quad_u8& src_pixel = *pSrc_pixels++; + + uint best_selector_index = 0; + uint best_error = rg_etc1::square(src_pixel.r - block_colors[0].r) + rg_etc1::square(src_pixel.g - block_colors[0].g) + rg_etc1::square(src_pixel.b - block_colors[0].b); + + uint trial_error = rg_etc1::square(src_pixel.r - block_colors[1].r) + rg_etc1::square(src_pixel.g - block_colors[1].g) + rg_etc1::square(src_pixel.b - block_colors[1].b); + if (trial_error < best_error) + { + best_error = trial_error; + best_selector_index = 1; + } + + trial_error = rg_etc1::square(src_pixel.r - block_colors[2].r) + rg_etc1::square(src_pixel.g - block_colors[2].g) + rg_etc1::square(src_pixel.b - block_colors[2].b); + if (trial_error < best_error) + { + best_error = trial_error; + best_selector_index = 2; + } + + trial_error = rg_etc1::square(src_pixel.r - block_colors[3].r) + rg_etc1::square(src_pixel.g - block_colors[3].g) + rg_etc1::square(src_pixel.b - block_colors[3].b); + if (trial_error < best_error) + { + best_error = trial_error; + best_selector_index = 3; + } + + m_temp_selectors[c] = static_cast(best_selector_index); + + total_error += best_error; + if (total_error >= trial_solution.m_error) + break; + } + + if (total_error < trial_solution.m_error) + { + trial_solution.m_error = total_error; + trial_solution.m_coords.m_inten_table = inten_table; + memcpy(trial_solution.m_selectors, m_temp_selectors, 8); + trial_solution.m_valid = true; + } + } + trial_solution.m_coords.m_unscaled_color = coords.m_unscaled_color; + trial_solution.m_coords.m_color4 = m_pParams->m_use_color4; + + bool success = false; + if (pBest_solution) + { + if (trial_solution.m_error < pBest_solution->m_error) + { + *pBest_solution = trial_solution; + success = true; + } + } + + return success; + } + + bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution) + { + if (m_pParams->m_constrain_against_base_color5) + { + const int dr = coords.m_unscaled_color.r - m_pParams->m_base_color5.r; + const int dg = coords.m_unscaled_color.g - m_pParams->m_base_color5.g; + const int db = coords.m_unscaled_color.b - m_pParams->m_base_color5.b; + + if ((rg_etc1::minimum(dr, dg, db) < cETC1ColorDeltaMin) || (rg_etc1::maximum(dr, dg, db) > cETC1ColorDeltaMax)) + { + trial_solution.m_valid = false; + return false; + } + } + + const color_quad_u8 base_color(coords.get_scaled_color()); + + const uint n = 8; + + trial_solution.m_error = cUINT64_MAX; + + for (int inten_table = cETC1IntenModifierValues - 1; inten_table >= 0; --inten_table) + { + const int* pInten_table = g_etc1_inten_tables[inten_table]; + + uint block_inten[4]; + color_quad_u8 block_colors[4]; + for (uint s = 0; s < 4; s++) + { + const int yd = pInten_table[s]; + color_quad_u8 block_color(base_color.r + yd, base_color.g + yd, base_color.b + yd, 0); + block_colors[s] = block_color; + block_inten[s] = block_color.r + block_color.g + block_color.b; + } + + // evaluate_solution_fast() enforces/assumesd a total ordering of the input colors along the intensity (1,1,1) axis to more quickly classify the inputs to selectors. + // The inputs colors have been presorted along the projection onto this axis, and ETC1 block colors are always ordered along the intensity axis, so this classification is fast. + // 0 1 2 3 + // 01 12 23 + const uint block_inten_midpoints[3] = { block_inten[0] + block_inten[1], block_inten[1] + block_inten[2], block_inten[2] + block_inten[3] }; + + uint64 total_error = 0; + const color_quad_u8* pSrc_pixels = m_pParams->m_pSrc_pixels; + if ((m_pSorted_luma[n - 1] * 2) < block_inten_midpoints[0]) + { + if (block_inten[0] > m_pSorted_luma[n - 1]) + { + const uint min_error = (uint)(labs(block_inten[0] - m_pSorted_luma[n - 1])); + if (min_error >= trial_solution.m_error) + continue; + } + + memset(&m_temp_selectors[0], 0, n); + + for (uint c = 0; c < n; c++) + total_error += block_colors[0].squared_distance_rgb(pSrc_pixels[c]); + } + else if ((m_pSorted_luma[0] * 2) >= block_inten_midpoints[2]) + { + if (m_pSorted_luma[0] > block_inten[3]) + { + const uint min_error = (uint)(labs(m_pSorted_luma[0] - block_inten[3])); + if (min_error >= trial_solution.m_error) + continue; + } + + memset(&m_temp_selectors[0], 3, n); + + for (uint c = 0; c < n; c++) + total_error += block_colors[3].squared_distance_rgb(pSrc_pixels[c]); + } + else + { + uint cur_selector = 0, c; + for (c = 0; c < n; c++) + { + const uint y = m_pSorted_luma[c]; + while ((y * 2) >= block_inten_midpoints[cur_selector]) + if (++cur_selector > 2) + goto done; + const uint sorted_pixel_index = m_pSorted_luma_indices[c]; + m_temp_selectors[sorted_pixel_index] = static_cast(cur_selector); + total_error += block_colors[cur_selector].squared_distance_rgb(pSrc_pixels[sorted_pixel_index]); + } +done: + while (c < n) + { + const uint sorted_pixel_index = m_pSorted_luma_indices[c]; + m_temp_selectors[sorted_pixel_index] = 3; + total_error += block_colors[3].squared_distance_rgb(pSrc_pixels[sorted_pixel_index]); + ++c; + } + } + + if (total_error < trial_solution.m_error) + { + trial_solution.m_error = total_error; + trial_solution.m_coords.m_inten_table = inten_table; + memcpy(trial_solution.m_selectors, m_temp_selectors, n); + trial_solution.m_valid = true; + if (!total_error) + break; + } + } + trial_solution.m_coords.m_unscaled_color = coords.m_unscaled_color; + trial_solution.m_coords.m_color4 = m_pParams->m_use_color4; + + bool success = false; + if (pBest_solution) + { + if (trial_solution.m_error < pBest_solution->m_error) + { + *pBest_solution = trial_solution; + success = true; + } + } + + return success; + } + + static uint etc1_decode_value(uint diff, uint inten, uint selector, uint packed_c) + { + //const uint limit = diff ? 32 : 16; limit; + //RG_ETC1_ASSERT((diff < 2) && (inten < 8) && (selector < 4) && (packed_c < limit)); + int c; + if (diff) + c = (packed_c >> 2) | (packed_c << 3); + else + c = packed_c | (packed_c << 4); + c += g_etc1_inten_tables[inten][selector]; + c = rg_etc1::clamp(c, 0, 255); + return c; + } + + static inline int mul_8bit(int a, int b) { int t = a*b + 128; return (t + (t >> 8)) >> 8; } + + void pack_etc1_block_init() + { + for (uint diff = 0; diff < 2; diff++) + { + const uint limit = diff ? 32 : 16; + + for (uint inten = 0; inten < 8; inten++) + { + for (uint selector = 0; selector < 4; selector++) + { + const uint inverse_table_index = diff + (inten << 1) + (selector << 4); + for (uint color = 0; color < 256; color++) + { + uint best_error = cUINT32_MAX, best_packed_c = 0; + for (uint packed_c = 0; packed_c < limit; packed_c++) + { + int v = etc1_decode_value(diff, inten, selector, packed_c); + uint err = (uint)labs(v - static_cast(color)); + if (err < best_error) + { + best_error = err; + best_packed_c = packed_c; + if (!best_error) + break; + } + } + RG_ETC1_ASSERT(best_error <= 255); + g_etc1_inverse_lookup[inverse_table_index][color] = static_cast(best_packed_c | (best_error << 8)); + } + } + } + } + + uint expand5[32]; + for(int i = 0; i < 32; i++) + expand5[i] = (i << 3) | (i >> 2); + + for(int i = 0; i < 256 + 16; i++) + { + int v = clamp(i - 8, 0, 255); + g_quant5_tab[i] = static_cast(expand5[mul_8bit(v,31)]); + } + } + + // Packs solid color blocks efficiently using a set of small precomputed tables. + // For random 888 inputs, MSE results are better than Erricson's ETC1 packer in "slow" mode ~9.5% of the time, is slightly worse only ~.01% of the time, and is equal the rest of the time. + static uint64 pack_etc1_block_solid_color(etc1_block& block, const uint8* pColor, etc1_pack_params& pack_params) + { + // pack_params; + RG_ETC1_ASSERT(g_etc1_inverse_lookup[0][255]); + + static uint s_next_comp[4] = { 1, 2, 0, 1 }; + + uint best_error = cUINT32_MAX, best_i = 0; + int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0; + + // For each possible 8-bit value, there is a precomputed list of diff/inten/selector configurations that allow that 8-bit value to be encoded with no error. + for (uint i = 0; i < 3; i++) + { + const uint c1 = pColor[s_next_comp[i]], c2 = pColor[s_next_comp[i + 1]]; + + const int delta_range = 1; + for (int delta = -delta_range; delta <= delta_range; delta++) + { + const int c_plus_delta = rg_etc1::clamp(pColor[i] + delta, 0, 255); + + const uint16* pTable; + if (!c_plus_delta) + pTable = g_color8_to_etc_block_config_0_255[0]; + else if (c_plus_delta == 255) + pTable = g_color8_to_etc_block_config_0_255[1]; + else + pTable = g_color8_to_etc_block_config_1_to_254[c_plus_delta - 1]; + + do + { + const uint x = *pTable++; + +#ifdef RG_ETC1_BUILD_DEBUG + const uint diff = x & 1; + const uint inten = (x >> 1) & 7; + const uint selector = (x >> 4) & 3; + const uint p0 = (x >> 8) & 255; + RG_ETC1_ASSERT(etc1_decode_value(diff, inten, selector, p0) == (uint)c_plus_delta); +#endif + + const uint16* pInverse_table = g_etc1_inverse_lookup[x & 0xFF]; + uint16 p1 = pInverse_table[c1]; + uint16 p2 = pInverse_table[c2]; + const uint trial_error = rg_etc1::square(c_plus_delta - pColor[i]) + rg_etc1::square(p1 >> 8) + rg_etc1::square(p2 >> 8); + if (trial_error < best_error) + { + best_error = trial_error; + best_x = x; + best_packed_c1 = p1 & 0xFF; + best_packed_c2 = p2 & 0xFF; + best_i = i; + if (!best_error) + goto found_perfect_match; + } + } while (*pTable != 0xFFFF); + } + } +found_perfect_match: + + const uint diff = best_x & 1; + const uint inten = (best_x >> 1) & 7; + + block.m_bytes[3] = static_cast(((inten | (inten << 3)) << 2) | (diff << 1)); + + const uint etc1_selector = g_selector_index_to_etc1[(best_x >> 4) & 3]; + *reinterpret_cast(&block.m_bytes[4]) = (etc1_selector & 2) ? 0xFFFF : 0; + *reinterpret_cast(&block.m_bytes[6]) = (etc1_selector & 1) ? 0xFFFF : 0; + + const uint best_packed_c0 = (best_x >> 8) & 255; + if (diff) + { + block.m_bytes[best_i] = static_cast(best_packed_c0 << 3); + block.m_bytes[s_next_comp[best_i]] = static_cast(best_packed_c1 << 3); + block.m_bytes[s_next_comp[best_i+1]] = static_cast(best_packed_c2 << 3); + } + else + { + block.m_bytes[best_i] = static_cast(best_packed_c0 | (best_packed_c0 << 4)); + block.m_bytes[s_next_comp[best_i]] = static_cast(best_packed_c1 | (best_packed_c1 << 4)); + block.m_bytes[s_next_comp[best_i+1]] = static_cast(best_packed_c2 | (best_packed_c2 << 4)); + } + + return best_error; + } + + static uint pack_etc1_block_solid_color_constrained( + etc1_optimizer::results& results, + uint num_colors, const uint8* pColor, + etc1_pack_params& pack_params, + bool use_diff, + const color_quad_u8* pBase_color5_unscaled) + { + RG_ETC1_ASSERT(g_etc1_inverse_lookup[0][255]); + + //pack_params; + static uint s_next_comp[4] = { 1, 2, 0, 1 }; + + uint best_error = cUINT32_MAX, best_i = 0; + int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0; + + // For each possible 8-bit value, there is a precomputed list of diff/inten/selector configurations that allow that 8-bit value to be encoded with no error. + for (uint i = 0; i < 3; i++) + { + const uint c1 = pColor[s_next_comp[i]], c2 = pColor[s_next_comp[i + 1]]; + + const int delta_range = 1; + for (int delta = -delta_range; delta <= delta_range; delta++) + { + const int c_plus_delta = rg_etc1::clamp(pColor[i] + delta, 0, 255); + + const uint16* pTable; + if (!c_plus_delta) + pTable = g_color8_to_etc_block_config_0_255[0]; + else if (c_plus_delta == 255) + pTable = g_color8_to_etc_block_config_0_255[1]; + else + pTable = g_color8_to_etc_block_config_1_to_254[c_plus_delta - 1]; + + do + { + const uint x = *pTable++; + const uint diff = x & 1; + if (static_cast(use_diff) != diff) + { + if (*pTable == 0xFFFF) + break; + continue; + } + + if ((diff) && (pBase_color5_unscaled)) + { + const int p0 = (x >> 8) & 255; + int delta = p0 - static_cast(pBase_color5_unscaled->c[i]); + if ((delta < cETC1ColorDeltaMin) || (delta > cETC1ColorDeltaMax)) + { + if (*pTable == 0xFFFF) + break; + continue; + } + } + +#ifdef RG_ETC1_BUILD_DEBUG + { + const uint inten = (x >> 1) & 7; + const uint selector = (x >> 4) & 3; + const uint p0 = (x >> 8) & 255; + RG_ETC1_ASSERT(etc1_decode_value(diff, inten, selector, p0) == (uint)c_plus_delta); + } +#endif + + const uint16* pInverse_table = g_etc1_inverse_lookup[x & 0xFF]; + uint16 p1 = pInverse_table[c1]; + uint16 p2 = pInverse_table[c2]; + + if ((diff) && (pBase_color5_unscaled)) + { + int delta1 = (p1 & 0xFF) - static_cast(pBase_color5_unscaled->c[s_next_comp[i]]); + int delta2 = (p2 & 0xFF) - static_cast(pBase_color5_unscaled->c[s_next_comp[i + 1]]); + if ((delta1 < cETC1ColorDeltaMin) || (delta1 > cETC1ColorDeltaMax) || (delta2 < cETC1ColorDeltaMin) || (delta2 > cETC1ColorDeltaMax)) + { + if (*pTable == 0xFFFF) + break; + continue; + } + } + + const uint trial_error = rg_etc1::square(c_plus_delta - pColor[i]) + rg_etc1::square(p1 >> 8) + rg_etc1::square(p2 >> 8); + if (trial_error < best_error) + { + best_error = trial_error; + best_x = x; + best_packed_c1 = p1 & 0xFF; + best_packed_c2 = p2 & 0xFF; + best_i = i; + if (!best_error) + goto found_perfect_match; + } + } while (*pTable != 0xFFFF); + } + } +found_perfect_match: + + if (best_error == cUINT32_MAX) + return best_error; + + best_error *= num_colors; + + results.m_n = num_colors; + results.m_block_color4 = !(best_x & 1); + results.m_block_inten_table = (best_x >> 1) & 7; + memset(results.m_pSelectors, (best_x >> 4) & 3, num_colors); + + const uint best_packed_c0 = (best_x >> 8) & 255; + results.m_block_color_unscaled[best_i] = static_cast(best_packed_c0); + results.m_block_color_unscaled[s_next_comp[best_i]] = static_cast(best_packed_c1); + results.m_block_color_unscaled[s_next_comp[best_i + 1]] = static_cast(best_packed_c2); + results.m_error = best_error; + + return best_error; + } + + // Function originally from RYG's public domain real-time DXT1 compressor, modified for 555. + static void dither_block_555(color_quad_u8* dest, const color_quad_u8* block) + { + int err[8],*ep1 = err,*ep2 = err+4; + uint8 *quant = g_quant5_tab+8; + + memset(dest, 0xFF, sizeof(color_quad_u8)*16); + + // process channels seperately + for(int ch=0;ch<3;ch++) + { + uint8* bp = (uint8*)block; + uint8* dp = (uint8*)dest; + + bp += ch; dp += ch; + + memset(err,0, sizeof(err)); + for(int y = 0; y < 4; y++) + { + // pixel 0 + dp[ 0] = quant[bp[ 0] + ((3*ep2[1] + 5*ep2[0]) >> 4)]; + ep1[0] = bp[ 0] - dp[ 0]; + + // pixel 1 + dp[ 4] = quant[bp[ 4] + ((7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]) >> 4)]; + ep1[1] = bp[ 4] - dp[ 4]; + + // pixel 2 + dp[ 8] = quant[bp[ 8] + ((7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]) >> 4)]; + ep1[2] = bp[ 8] - dp[ 8]; + + // pixel 3 + dp[12] = quant[bp[12] + ((7*ep1[2] + 5*ep2[3] + ep2[2]) >> 4)]; + ep1[3] = bp[12] - dp[12]; + + // advance to next line + int* tmp = ep1; ep1 = ep2; ep2 = tmp; + bp += 16; + dp += 16; + } + } + } + + unsigned int pack_etc1_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, etc1_pack_params& pack_params) + { + const color_quad_u8* pSrc_pixels = reinterpret_cast(pSrc_pixels_rgba); + etc1_block& dst_block = *static_cast(pETC1_block); + +#ifdef RG_ETC1_BUILD_DEBUG + // Ensure all alpha values are 0xFF. + for (uint i = 0; i < 16; i++) + { + RG_ETC1_ASSERT(pSrc_pixels[i].a == 255); + } +#endif + + color_quad_u8 src_pixel0(pSrc_pixels[0]); + + // Check for solid block. + const uint32 first_pixel_u32 = pSrc_pixels->m_u32; + int r; + for (r = 15; r >= 1; --r) + if (pSrc_pixels[r].m_u32 != first_pixel_u32) + break; + if (!r) + return static_cast(16 * pack_etc1_block_solid_color(dst_block, &pSrc_pixels[0].r, pack_params)); + + color_quad_u8 dithered_pixels[16]; + if (pack_params.m_dithering) + { + dither_block_555(dithered_pixels, pSrc_pixels); + pSrc_pixels = dithered_pixels; + } + + etc1_optimizer optimizer; + + uint64 best_error = cUINT64_MAX; + uint best_flip = false, best_use_color4 = false; + + uint8 best_selectors[2][8]; + etc1_optimizer::results best_results[2]; + for (uint i = 0; i < 2; i++) + { + best_results[i].m_n = 8; + best_results[i].m_pSelectors = best_selectors[i]; + } + + uint8 selectors[3][8]; + etc1_optimizer::results results[3]; + + for (uint i = 0; i < 3; i++) + { + results[i].m_n = 8; + results[i].m_pSelectors = selectors[i]; + } + + color_quad_u8 subblock_pixels[8]; + + etc1_optimizer::params params(pack_params); + params.m_num_src_pixels = 8; + params.m_pSrc_pixels = subblock_pixels; + + for (uint flip = 0; flip < 2; flip++) + { + for (uint use_color4 = 0; use_color4 < 2; use_color4++) + { + uint64 trial_error = 0; + + uint subblock; + for (subblock = 0; subblock < 2; subblock++) + { + if (flip) + memcpy(subblock_pixels, pSrc_pixels + subblock * 8, sizeof(color_quad_u8) * 8); + else + { + const color_quad_u8* pSrc_col = pSrc_pixels + subblock * 2; + subblock_pixels[0] = pSrc_col[0]; subblock_pixels[1] = pSrc_col[4]; subblock_pixels[2] = pSrc_col[8]; subblock_pixels[3] = pSrc_col[12]; + subblock_pixels[4] = pSrc_col[1]; subblock_pixels[5] = pSrc_col[5]; subblock_pixels[6] = pSrc_col[9]; subblock_pixels[7] = pSrc_col[13]; + } + + results[2].m_error = cUINT64_MAX; + if ((params.m_quality >= cMediumQuality) && ((subblock) || (use_color4))) + { + const uint32 subblock_pixel0_u32 = subblock_pixels[0].m_u32; + for (r = 7; r >= 1; --r) + if (subblock_pixels[r].m_u32 != subblock_pixel0_u32) + break; + if (!r) + { + pack_etc1_block_solid_color_constrained(results[2], 8, &subblock_pixels[0].r, pack_params, !use_color4, (subblock && !use_color4) ? &results[0].m_block_color_unscaled : NULL); + } + } + + params.m_use_color4 = (use_color4 != 0); + params.m_constrain_against_base_color5 = false; + + if ((!use_color4) && (subblock)) + { + params.m_constrain_against_base_color5 = true; + params.m_base_color5 = results[0].m_block_color_unscaled; + } + + if (params.m_quality == cHighQuality) + { + static const int s_scan_delta_0_to_4[] = { -4, -3, -2, -1, 0, 1, 2, 3, 4 }; + params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0_to_4); + params.m_pScan_deltas = s_scan_delta_0_to_4; + } + else if (params.m_quality == cMediumQuality) + { + static const int s_scan_delta_0_to_1[] = { -1, 0, 1 }; + params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0_to_1); + params.m_pScan_deltas = s_scan_delta_0_to_1; + } + else + { + static const int s_scan_delta_0[] = { 0 }; + params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0); + params.m_pScan_deltas = s_scan_delta_0; + } + + optimizer.init(params, results[subblock]); + if (!optimizer.compute()) + break; + + if (params.m_quality >= cMediumQuality) + { + // TODO: Fix fairly arbitrary/unrefined thresholds that control how far away to scan for potentially better solutions. + const uint refinement_error_thresh0 = 3000; + const uint refinement_error_thresh1 = 6000; + if (results[subblock].m_error > refinement_error_thresh0) + { + if (params.m_quality == cMediumQuality) + { + static const int s_scan_delta_2_to_3[] = { -3, -2, 2, 3 }; + params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_2_to_3); + params.m_pScan_deltas = s_scan_delta_2_to_3; + } + else + { + static const int s_scan_delta_5_to_5[] = { -5, 5 }; + static const int s_scan_delta_5_to_8[] = { -8, -7, -6, -5, 5, 6, 7, 8 }; + if (results[subblock].m_error > refinement_error_thresh1) + { + params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_5_to_8); + params.m_pScan_deltas = s_scan_delta_5_to_8; + } + else + { + params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_5_to_5); + params.m_pScan_deltas = s_scan_delta_5_to_5; + } + } + + if (!optimizer.compute()) + break; + } + + if (results[2].m_error < results[subblock].m_error) + results[subblock] = results[2]; + } + + trial_error += results[subblock].m_error; + if (trial_error >= best_error) + break; + } + + if (subblock < 2) + continue; + + best_error = trial_error; + best_results[0] = results[0]; + best_results[1] = results[1]; + best_flip = flip; + best_use_color4 = use_color4; + + } // use_color4 + + } // flip + + int dr = best_results[1].m_block_color_unscaled.r - best_results[0].m_block_color_unscaled.r; + int dg = best_results[1].m_block_color_unscaled.g - best_results[0].m_block_color_unscaled.g; + int db = best_results[1].m_block_color_unscaled.b - best_results[0].m_block_color_unscaled.b; + RG_ETC1_ASSERT(best_use_color4 || (rg_etc1::minimum(dr, dg, db) >= cETC1ColorDeltaMin) && (rg_etc1::maximum(dr, dg, db) <= cETC1ColorDeltaMax)); + + if (best_use_color4) + { + dst_block.m_bytes[0] = static_cast(best_results[1].m_block_color_unscaled.r | (best_results[0].m_block_color_unscaled.r << 4)); + dst_block.m_bytes[1] = static_cast(best_results[1].m_block_color_unscaled.g | (best_results[0].m_block_color_unscaled.g << 4)); + dst_block.m_bytes[2] = static_cast(best_results[1].m_block_color_unscaled.b | (best_results[0].m_block_color_unscaled.b << 4)); + } + else + { + if (dr < 0) dr += 8; dst_block.m_bytes[0] = static_cast((best_results[0].m_block_color_unscaled.r << 3) | dr); + if (dg < 0) dg += 8; dst_block.m_bytes[1] = static_cast((best_results[0].m_block_color_unscaled.g << 3) | dg); + if (db < 0) db += 8; dst_block.m_bytes[2] = static_cast((best_results[0].m_block_color_unscaled.b << 3) | db); + } + + dst_block.m_bytes[3] = static_cast( (best_results[1].m_block_inten_table << 2) | (best_results[0].m_block_inten_table << 5) | ((~best_use_color4 & 1) << 1) | best_flip ); + + uint selector0 = 0, selector1 = 0; + if (best_flip) + { + // flipped: + // { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, + // { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 } + // + // { 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 }, + // { 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 3 } + const uint8* pSelectors0 = best_results[0].m_pSelectors; + const uint8* pSelectors1 = best_results[1].m_pSelectors; + for (int x = 3; x >= 0; --x) + { + uint b; + b = g_selector_index_to_etc1[pSelectors1[4 + x]]; + selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1); + + b = g_selector_index_to_etc1[pSelectors1[x]]; + selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1); + + b = g_selector_index_to_etc1[pSelectors0[4 + x]]; + selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1); + + b = g_selector_index_to_etc1[pSelectors0[x]]; + selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1); + } + } + else + { + // non-flipped: + // { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, + // { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 } + // + // { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, + // { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 } + for (int subblock = 1; subblock >= 0; --subblock) + { + const uint8* pSelectors = best_results[subblock].m_pSelectors + 4; + for (uint i = 0; i < 2; i++) + { + uint b; + b = g_selector_index_to_etc1[pSelectors[3]]; + selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1); + + b = g_selector_index_to_etc1[pSelectors[2]]; + selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1); + + b = g_selector_index_to_etc1[pSelectors[1]]; + selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1); + + b = g_selector_index_to_etc1[pSelectors[0]]; + selector0 = (selector0 << 1) | (b & 1);selector1 = (selector1 << 1) | (b >> 1); + + pSelectors -= 4; + } + } + } + + dst_block.m_bytes[4] = static_cast(selector1 >> 8); dst_block.m_bytes[5] = static_cast(selector1 & 0xFF); + dst_block.m_bytes[6] = static_cast(selector0 >> 8); dst_block.m_bytes[7] = static_cast(selector0 & 0xFF); + + return static_cast(best_error); + } + +} // namespace rg_etc1 diff --git a/ext/native/ext/rg_etc1/rg_etc1.h b/ext/native/ext/rg_etc1/rg_etc1.h new file mode 100644 index 0000000000..bb2961c361 --- /dev/null +++ b/ext/native/ext/rg_etc1/rg_etc1.h @@ -0,0 +1,76 @@ +// File: rg_etc1.h - Fast, high quality ETC1 block packer/unpacker - Rich Geldreich +// Please see ZLIB license at the end of this file. +#pragma once + +namespace rg_etc1 +{ + // Unpacks an 8-byte ETC1 compressed block to a block of 4x4 32bpp RGBA pixels. + // Returns false if the block is invalid. Invalid blocks will still be unpacked with clamping. + // This function is thread safe, and does not dynamically allocate any memory. + // If preserve_alpha is true, the alpha channel of the destination pixels will not be overwritten. Otherwise, alpha will be set to 255. + bool unpack_etc1_block(const void *pETC1_block, unsigned int* pDst_pixels_rgba, int stride, bool preserve_alpha = false); + + // Quality setting = the higher the quality, the slower. + // To pack large textures, it is highly recommended to call pack_etc1_block() in parallel, on different blocks, from multiple threads (particularly when using cHighQuality). + enum etc1_quality + { + cLowQuality, + cMediumQuality, + cHighQuality, + }; + + struct etc1_pack_params + { + etc1_quality m_quality; + bool m_dithering; + + inline etc1_pack_params() + { + clear(); + } + + void clear() + { + m_quality = cHighQuality; + m_dithering = false; + } + }; + + // Important: pack_etc1_block_init() must be called before calling pack_etc1_block(). + void pack_etc1_block_init(); + + // Packs a 4x4 block of 32bpp RGBA pixels to an 8-byte ETC1 block. + // 32-bit RGBA pixels must always be arranged as (R,G,B,A) (R first, A last) in memory, independent of platform endianness. A should always be 255. + // Returns squared error of result. + // This function is thread safe, and does not dynamically allocate any memory. + // pack_etc1_block() does not currently support "perceptual" colorspace metrics - it primarily optimizes for RGB RMSE. + unsigned int pack_etc1_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, etc1_pack_params& pack_params); + +} // namespace rg_etc1 + +//------------------------------------------------------------------------------ +// +// rg_etc1 uses the ZLIB license: +// http://opensource.org/licenses/Zlib +// +// Copyright (c) 2012 Rich Geldreich +// +// 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. +// +//------------------------------------------------------------------------------ diff --git a/ext/native/ext/sha1/CMakeLists.txt b/ext/native/ext/sha1/CMakeLists.txt new file mode 100644 index 0000000000..cb83b1eaec --- /dev/null +++ b/ext/native/ext/sha1/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 2.6) + +#if(UNIX) +add_definitions(-fPIC) +add_definitions(-g) +add_definitions(-O2) +add_definitions(-Wall) +#endif(UNIX) + +add_library(sha1 sha1.cpp) diff --git a/ext/native/ext/sha1/sha1.cpp b/ext/native/ext/sha1/sha1.cpp new file mode 100644 index 0000000000..263c6b5927 --- /dev/null +++ b/ext/native/ext/sha1/sha1.cpp @@ -0,0 +1,259 @@ +/* + 100% free public domain implementation of the SHA-1 algorithm + by Dominik Reichl + Web: http://www.dominik-reichl.de/ + + See header file for version history and test vectors. +*/ + +// If compiling with MFC, you might want to add #include "StdAfx.h" + +#define _CRT_SECURE_NO_WARNINGS +#include "sha1.h" + +#ifdef SHA1_UTILITY_FUNCTIONS +#define SHA1_MAX_FILE_BUFFER (32 * 20 * 820) +#endif + +// Rotate _val32 by _nBits bits to the left +#ifndef ROL32 +#ifdef _MSC_VER +#define ROL32(_val32,_nBits) _rotl(_val32,_nBits) +#else +#define ROL32(_val32,_nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits)))) +#endif +#endif + +#ifdef SHA1_LITTLE_ENDIAN +#define SHABLK0(i) (m_block->l[i] = \ + (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF)) +#else +#define SHABLK0(i) (m_block->l[i]) +#endif + +#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ \ + m_block->l[(i+8)&15] ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) + +// SHA-1 rounds +#define _R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);} +#define _R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);} +#define _R2(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5);w=ROL32(w,30);} +#define _R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5);w=ROL32(w,30);} +#define _R4(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5);w=ROL32(w,30);} + +#ifdef _MSC_VER +#pragma warning(push) +// Disable compiler warning 'Conditional expression is constant' +#pragma warning(disable: 4127) +#endif + +CSHA1::CSHA1() +{ + m_block = (SHA1_WORKSPACE_BLOCK*)m_workspace; + + Reset(); +} + +CSHA1::~CSHA1() +{ + Reset(); +} + +void CSHA1::Reset() +{ + // SHA1 initialization constants + m_state[0] = 0x67452301; + m_state[1] = 0xEFCDAB89; + m_state[2] = 0x98BADCFE; + m_state[3] = 0x10325476; + m_state[4] = 0xC3D2E1F0; + + m_count[0] = 0; + m_count[1] = 0; +} + +void CSHA1::Transform(UINT_32* pState, const UINT_8* pBuffer) +{ + UINT_32 a = pState[0], b = pState[1], c = pState[2], d = pState[3], e = pState[4]; + + memcpy(m_block, pBuffer, 64); + + // 4 rounds of 20 operations each, loop unrolled + _R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3); + _R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7); + _R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11); + _R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15); + _R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19); + _R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23); + _R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27); + _R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31); + _R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35); + _R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39); + _R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43); + _R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47); + _R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51); + _R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55); + _R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59); + _R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63); + _R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67); + _R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71); + _R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75); + _R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79); + + // Add the working vars back into state + pState[0] += a; + pState[1] += b; + pState[2] += c; + pState[3] += d; + pState[4] += e; + + // Wipe variables +#ifdef SHA1_WIPE_VARIABLES + a = b = c = d = e = 0; +#endif +} + +void CSHA1::Update(const UINT_8* pbData, UINT_32 uLen) +{ + UINT_32 j = ((m_count[0] >> 3) & 0x3F); + + if((m_count[0] += (uLen << 3)) < (uLen << 3)) + ++m_count[1]; // Overflow + + m_count[1] += (uLen >> 29); + + UINT_32 i; + if((j + uLen) > 63) + { + i = 64 - j; + memcpy(&m_buffer[j], pbData, i); + Transform(m_state, m_buffer); + + for( ; (i + 63) < uLen; i += 64) + Transform(m_state, &pbData[i]); + + j = 0; + } + else i = 0; + + if((uLen - i) != 0) + memcpy(&m_buffer[j], &pbData[i], uLen - i); +} + +#ifdef SHA1_UTILITY_FUNCTIONS +bool CSHA1::HashFile(const TCHAR* tszFileName) +{ + if(tszFileName == NULL) return false; + + FILE* fpIn = _tfopen(tszFileName, _T("rb")); + if(fpIn == NULL) return false; + + UINT_8* pbData = new UINT_8[SHA1_MAX_FILE_BUFFER]; + if(pbData == NULL) { fclose(fpIn); return false; } + + bool bSuccess = true; + while(true) + { + const size_t uRead = fread(pbData, 1, SHA1_MAX_FILE_BUFFER, fpIn); + + if(uRead > 0) + Update(pbData, static_cast(uRead)); + + if(uRead < SHA1_MAX_FILE_BUFFER) + { + if(feof(fpIn) == 0) bSuccess = false; + break; + } + } + + fclose(fpIn); + delete[] pbData; + return bSuccess; +} +#endif + +void CSHA1::Final() +{ + UINT_32 i; + + UINT_8 finalcount[8]; + for(i = 0; i < 8; ++i) + finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)] + >> ((3 - (i & 3)) * 8) ) & 255); // Endian independent + + Update((UINT_8*)"\200", 1); + + while ((m_count[0] & 504) != 448) + Update((UINT_8*)"\0", 1); + + Update(finalcount, 8); // Cause a SHA1Transform() + + for(i = 0; i < 20; ++i) + m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xFF); + + // Wipe variables for security reasons +#ifdef SHA1_WIPE_VARIABLES + memset(m_buffer, 0, 64); + memset(m_state, 0, 20); + memset(m_count, 0, 8); + memset(finalcount, 0, 8); + Transform(m_state, m_buffer); +#endif +} + +#ifdef SHA1_UTILITY_FUNCTIONS +bool CSHA1::ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType) const +{ + if(tszReport == NULL) return false; + + TCHAR tszTemp[16]; + + if((rtReportType == REPORT_HEX) || (rtReportType == REPORT_HEX_SHORT)) + { + _sntprintf(tszTemp, 15, _T("%02X"), m_digest[0]); + _tcscpy(tszReport, tszTemp); + + const TCHAR* lpFmt = ((rtReportType == REPORT_HEX) ? _T(" %02X") : _T("%02X")); + for(size_t i = 1; i < 20; ++i) + { + _sntprintf(tszTemp, 15, lpFmt, m_digest[i]); + _tcscat(tszReport, tszTemp); + } + } + else if(rtReportType == REPORT_DIGIT) + { + _sntprintf(tszTemp, 15, _T("%u"), m_digest[0]); + _tcscpy(tszReport, tszTemp); + + for(size_t i = 1; i < 20; ++i) + { + _sntprintf(tszTemp, 15, _T(" %u"), m_digest[i]); + _tcscat(tszReport, tszTemp); + } + } + else return false; + + return true; +} +#endif + +#ifdef SHA1_STL_FUNCTIONS +bool CSHA1::ReportHashStl(std::basic_string& strOut, REPORT_TYPE rtReportType) const +{ + TCHAR tszOut[84]; + const bool bResult = ReportHash(tszOut, rtReportType); + if(bResult) strOut = tszOut; + return bResult; +} +#endif + +bool CSHA1::GetHash(UINT_8* pbDest20) const +{ + if(pbDest20 == NULL) return false; + memcpy(pbDest20, m_digest, 20); + return true; +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif diff --git a/ext/native/ext/sha1/sha1.h b/ext/native/ext/sha1/sha1.h new file mode 100644 index 0000000000..77f39e6699 --- /dev/null +++ b/ext/native/ext/sha1/sha1.h @@ -0,0 +1,263 @@ +/* + 100% free public domain implementation of the SHA-1 algorithm + by Dominik Reichl + Web: http://www.dominik-reichl.de/ + + Version 1.9 - 2011-11-10 + - Added Unicode test vectors. + - Improved support for hashing files using the HashFile method that + are larger than 4 GB. + - Improved file hashing performance (by using a larger buffer). + - Disabled unnecessary compiler warnings. + - Internal variables are now private. + + Version 1.8 - 2009-03-16 + - Converted project files to Visual Studio 2008 format. + - Added Unicode support for HashFile utility method. + - Added support for hashing files using the HashFile method that are + larger than 2 GB. + - HashFile now returns an error code instead of copying an error + message into the output buffer. + - GetHash now returns an error code and validates the input parameter. + - Added ReportHashStl STL utility method. + - Added REPORT_HEX_SHORT reporting mode. + - Improved Linux compatibility of test program. + + Version 1.7 - 2006-12-21 + - Fixed buffer underrun warning that appeared when compiling with + Borland C Builder (thanks to Rex Bloom and Tim Gallagher for the + patch). + - Breaking change: ReportHash writes the final hash to the start + of the buffer, i.e. it's not appending it to the string anymore. + - Made some function parameters const. + - Added Visual Studio 2005 project files to demo project. + + Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches) + - You can set the endianness in your files, no need to modify the + header file of the CSHA1 class anymore. + - Aligned data support. + - Made support/compilation of the utility functions (ReportHash and + HashFile) optional (useful when bytes count, for example in embedded + environments). + + Version 1.5 - 2005-01-01 + - 64-bit compiler compatibility added. + - Made variable wiping optional (define SHA1_WIPE_VARIABLES). + - Removed unnecessary variable initializations. + - ROL32 improvement for the Microsoft compiler (using _rotl). + + Version 1.4 - 2004-07-22 + - CSHA1 now compiles fine with GCC 3.3 under MacOS X (thanks to Larry + Hastings). + + Version 1.3 - 2003-08-17 + - Fixed a small memory bug and made a buffer array a class member to + ensure correct working when using multiple CSHA1 class instances at + one time. + + Version 1.2 - 2002-11-16 + - Borlands C++ compiler seems to have problems with string addition + using sprintf. Fixed the bug which caused the digest report function + not to work properly. CSHA1 is now Borland compatible. + + Version 1.1 - 2002-10-11 + - Removed two unnecessary header file includes and changed BOOL to + bool. Fixed some minor bugs in the web page contents. + + Version 1.0 - 2002-06-20 + - First official release. + + ================ Test Vectors ================ + + SHA1("abc" in ANSI) = + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + SHA1("abc" in Unicode LE) = + 9F04F41A 84851416 2050E3D6 8C1A7ABB 441DC2B5 + + SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + in ANSI) = + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + in Unicode LE) = + 51D7D876 9AC72C40 9C5B0E3F 69C60ADC 9A039014 + + SHA1(A million repetitions of "a" in ANSI) = + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F + SHA1(A million repetitions of "a" in Unicode LE) = + C4609560 A108A0C6 26AA7F2B 38A65566 739353C5 +*/ + +#ifndef ___SHA1_HDR___ +#define ___SHA1_HDR___ + +#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS) +#define SHA1_UTILITY_FUNCTIONS +#endif + +#if !defined(SHA1_STL_FUNCTIONS) && !defined(SHA1_NO_STL_FUNCTIONS) +#define SHA1_STL_FUNCTIONS +#if !defined(SHA1_UTILITY_FUNCTIONS) +#error STL functions require SHA1_UTILITY_FUNCTIONS. +#endif +#endif + +#include + +#ifdef SHA1_UTILITY_FUNCTIONS +#include +#include +#endif + +#ifdef SHA1_STL_FUNCTIONS +#include +#endif + +#ifdef _MSC_VER +#include +#endif + +// You can define the endian mode in your files without modifying the SHA-1 +// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN +// in your files, before including the SHA1.h header file. If you don't +// define anything, the class defaults to little endian. +#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN) +#define SHA1_LITTLE_ENDIAN +#endif + +// If you want variable wiping, #define SHA1_WIPE_VARIABLES, if not, +// #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it +// defaults to wiping. +#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES) +#define SHA1_WIPE_VARIABLES +#endif + +#if defined(SHA1_HAS_TCHAR) +#include +#else +#ifdef _MSC_VER +#include +#else +#ifndef TCHAR +#define TCHAR char +#endif +#ifndef _T +#define _T(__x) (__x) +#define _tmain main +#define _tprintf printf +#define _getts gets +#define _tcslen strlen +#define _tfopen fopen +#define _tcscpy strcpy +#define _tcscat strcat +#define _sntprintf snprintf +#endif +#endif +#endif + +/////////////////////////////////////////////////////////////////////////// +// Define variable types + +#ifndef UINT_8 +#ifdef _MSC_VER // Compiling with Microsoft compiler +#define UINT_8 unsigned __int8 +#else // !_MSC_VER +#define UINT_8 unsigned char +#endif // _MSC_VER +#endif + +#ifndef UINT_32 +#ifdef _MSC_VER // Compiling with Microsoft compiler +#define UINT_32 unsigned __int32 +#else // !_MSC_VER +#if (ULONG_MAX == 0xFFFFFFFF) +#define UINT_32 unsigned long +#else +#define UINT_32 unsigned int +#endif +#endif // _MSC_VER +#endif // UINT_32 + +#ifndef INT_64 +#ifdef _MSC_VER // Compiling with Microsoft compiler +#define INT_64 __int64 +#else // !_MSC_VER +#define INT_64 long long +#endif // _MSC_VER +#endif // INT_64 + +#ifndef UINT_64 +#ifdef _MSC_VER // Compiling with Microsoft compiler +#define UINT_64 unsigned __int64 +#else // !_MSC_VER +#define UINT_64 unsigned long long +#endif // _MSC_VER +#endif // UINT_64 + +/////////////////////////////////////////////////////////////////////////// +// Declare SHA-1 workspace + +typedef union +{ + UINT_8 c[64]; + UINT_32 l[16]; +} SHA1_WORKSPACE_BLOCK; + +class CSHA1 +{ +public: +#ifdef SHA1_UTILITY_FUNCTIONS + // Different formats for ReportHash + enum REPORT_TYPE + { + REPORT_HEX = 0, + REPORT_DIGIT = 1, + REPORT_HEX_SHORT = 2 + }; +#endif + + // Constructor and destructor + CSHA1(); + ~CSHA1(); + + void Reset(); + + // Hash in binary data and strings + void Update(const UINT_8* pbData, UINT_32 uLen); + +#ifdef SHA1_UTILITY_FUNCTIONS + // Hash in file contents + bool HashFile(const TCHAR* tszFileName); +#endif + + // Finalize hash, call before using ReportHash(Stl) + void Final(); + +#ifdef SHA1_UTILITY_FUNCTIONS + bool ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType = REPORT_HEX) const; +#endif + +#ifdef SHA1_STL_FUNCTIONS + bool ReportHashStl(std::basic_string& strOut, REPORT_TYPE rtReportType = + REPORT_HEX) const; +#endif + + // Get the raw message digest (20 bytes) + bool GetHash(UINT_8* pbDest20) const; + +private: + // Private SHA-1 transformation + void Transform(UINT_32* pState, const UINT_8* pBuffer); + + // Member variables + UINT_32 m_state[5]; + UINT_32 m_count[2]; + UINT_32 m_reserved0[1]; // Memory alignment padding + UINT_8 m_buffer[64]; + UINT_8 m_digest[20]; + UINT_32 m_reserved1[3]; // Memory alignment padding + + UINT_8 m_workspace[64]; + SHA1_WORKSPACE_BLOCK* m_block; // SHA1 pointer to the byte array above +}; + +#endif // ___SHA1_HDR___ diff --git a/ext/native/ext/stb_image/CMakeLists.txt b/ext/native/ext/stb_image/CMakeLists.txt new file mode 100644 index 0000000000..3f4c2fae09 --- /dev/null +++ b/ext/native/ext/stb_image/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.6) + +#if(UNIX) +add_definitions(-fPIC) +#endif(UNIX) + +add_library(stb_image stb_image.c) diff --git a/ext/native/ext/stb_image/stb_image.c b/ext/native/ext/stb_image/stb_image.c new file mode 100644 index 0000000000..1d996da7b3 --- /dev/null +++ b/ext/native/ext/stb_image/stb_image.c @@ -0,0 +1,4410 @@ +/* stbi-1.33 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c + when you control the images you're loading + no warranty implied; use at your own risk + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline (no JPEG progressive) + PNG 8-bit-per-channel only + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD) + + Latest revisions: + 1.33 (2011-07-14) minor fixes suggested by Dave Moore + 1.32 (2011-07-13) info support for all filetypes (SpartanJ) + 1.31 (2011-06-19) a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) added ability to load files via io callbacks (Ben Wenger) + 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila) + allow trailing 0s at end of image data (Laurent Gomila) + 1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ + + See end of file for full revision history. + + TODO: + stbi_info support for BMP,PSD,HDR,PIC + + + ============================ Contributors ========================= + + Image formats Optimizations & bugfixes + Sean Barrett (jpeg, png, bmp) Fabian "ryg" Giesen + Nicolas Schulz (hdr, psd) + Jonathan Dummer (tga) Bug fixes & warning fixes + Jean-Marc Lienher (gif) Marc LeBlanc + Tom Seddon (pic) Christpher Lloyd + Thatcher Ulrich (psd) Dave Moore + Won Chun + the Horde3D community + Extensions, features Janez Zemva + Jetro Lauha (stbi_info) Jonathan Blow + James "moose2000" Brown (iPhone PNG) Laurent Gomila + Ben "Disch" Wenger (io callbacks) Aruelien Pocheville + Martin "SpartanJ" Golini Ryamond Barbiero + David Woo + + + If your name should be here but isn't, let Sean know. + +*/ + +#include "stb_image.h" + +#ifndef STBI_HEADER_FILE_ONLY + +#ifndef STBI_NO_HDR +#include // ldexp +#include // strcmp, strtok +#endif + +#ifndef STBI_NO_STDIO +#include +#endif +#include +#include +#include +#include + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + + +// implementation: +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +#ifndef __SYMBIAN32__ +typedef unsigned int uint; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(uint32)==4 ? 1 : -1]; + +#if defined(STBI_NO_STDIO) && !defined(STBI_NO_WRITE) +#define STBI_NO_WRITE +#endif + +#define STBI_NOTUSED(v) (void)sizeof(v) + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +/////////////////////////////////////////////// +// +// stbi struct and start_xxx functions + +// stbi structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + uint8 buffer_start[128]; + + uint8 *img_buffer, *img_buffer_end; + uint8 *img_buffer_original; +} stbi; + + +static void refill_buffer(stbi *s); + +// initialize a memory-decode context +static void start_mem(stbi *s, uint8 const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (uint8 *) buffer; + s->img_buffer_end = (uint8 *) buffer+len; +} + +// initialize a callback-based context +static void start_callbacks(stbi *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->img_buffer_original = s->buffer_start; + refill_buffer(s); +} + +#ifndef STBI_NO_STDIO + +static int stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stdio_skip(void *user, unsigned n) +{ + fseek((FILE*) user, n, SEEK_CUR); +} + +static int stdio_eof(void *user) +{ + return feof((FILE*) user); +} + +static stbi_io_callbacks stbi_stdio_callbacks = +{ + stdio_read, + stdio_skip, + stdio_eof, +}; + +static void start_file(stbi *s, FILE *f) +{ + start_callbacks(s, &stbi_stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi_rewind(stbi *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; +} + +static int stbi_jpeg_test(stbi *s); +static stbi_uc *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp); +static int stbi_png_test(stbi *s); +static stbi_uc *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_png_info(stbi *s, int *x, int *y, int *comp); +static int stbi_bmp_test(stbi *s); +static stbi_uc *stbi_bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_tga_test(stbi *s); +static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_tga_info(stbi *s, int *x, int *y, int *comp); +static int stbi_psd_test(stbi *s); +static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_hdr_test(stbi *s); +static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_pic_test(stbi *s); +static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_gif_test(stbi *s); +static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_gif_info(stbi *s, int *x, int *y, int *comp); + + +// this is not threadsafe +static const char *failure_reason; + +const char *stbi_failure_reason(void) +{ + return failure_reason; +} + +static int e(const char *str) +{ + failure_reason = str; + return 0; +} + +// e - error +// epf - error returning pointer to float +// epuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define e(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define e(x,y) e(y) +#else + #define e(x,y) e(x) +#endif + +#define epf(x,y) ((float *) (e(x,y)?NULL:NULL)) +#define epuc(x,y) ((unsigned char *) (e(x,y)?NULL:NULL)) + +void stbi_image_free(void *retval_from_stbi_load) +{ + free(retval_from_stbi_load); +} + +#ifndef STBI_NO_HDR +static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static unsigned char *stbi_load_main(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + if (stbi_jpeg_test(s)) return stbi_jpeg_load(s,x,y,comp,req_comp); + if (stbi_png_test(s)) return stbi_png_load(s,x,y,comp,req_comp); + if (stbi_bmp_test(s)) return stbi_bmp_load(s,x,y,comp,req_comp); + if (stbi_gif_test(s)) return stbi_gif_load(s,x,y,comp,req_comp); + if (stbi_psd_test(s)) return stbi_psd_load(s,x,y,comp,req_comp); + if (stbi_pic_test(s)) return stbi_pic_load(s,x,y,comp,req_comp); + + #ifndef STBI_NO_HDR + if (stbi_hdr_test(s)) { + float *hdr = stbi_hdr_load(s, x,y,comp,req_comp); + return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + // test tga last because it's a crappy test! + if (stbi_tga_test(s)) + return stbi_tga_load(s,x,y,comp,req_comp); + return epuc("unknown image type", "Image not of any known type, or corrupt"); +} + +#ifndef STBI_NO_STDIO +unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = fopen(filename, "rb"); + unsigned char *result; + if (!f) return epuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s,f); + return stbi_load_main(&s,x,y,comp,req_comp); +} +#endif //!STBI_NO_STDIO + +unsigned char *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s,buffer,len); + return stbi_load_main(&s,x,y,comp,req_comp); +} + +unsigned char *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi_load_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_HDR + +float *stbi_loadf_main(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi_hdr_test(s)) + return stbi_hdr_load(s,x,y,comp,req_comp); + #endif + data = stbi_load_main(s, x, y, comp, req_comp); + if (data) + return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return epf("unknown image type", "Image not of any known type, or corrupt"); +} + +float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s,buffer,len); + return stbi_loadf_main(&s,x,y,comp,req_comp); +} + +float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi_loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = fopen(filename, "rb"); + float *result; + if (!f) return epf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s,f); + return stbi_loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_HDR + +// these is-hdr-or-not is defined independent of whether STBI_NO_HDR is +// defined, for API simplicity; if STBI_NO_HDR is defined, it always +// reports false! + +int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi s; + start_mem(&s,buffer,len); + return stbi_hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +extern int stbi_is_hdr (char const *filename) +{ + FILE *f = fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +extern int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + stbi s; + start_file(&s,f); + return stbi_hdr_test(&s); + #else + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi s; + start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi_hdr_test(&s); + #else + return 0; + #endif +} + +#ifndef STBI_NO_HDR +static float h2l_gamma_i=1.0f/2.2f, h2l_scale_i=1.0f; +static float l2h_gamma=2.2f, l2h_scale=1.0f; + +void stbi_hdr_to_ldr_gamma(float gamma) { h2l_gamma_i = 1/gamma; } +void stbi_hdr_to_ldr_scale(float scale) { h2l_scale_i = 1/scale; } + +void stbi_ldr_to_hdr_gamma(float gamma) { l2h_gamma = gamma; } +void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; } +#endif + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + SCAN_load=0, + SCAN_type, + SCAN_header +}; + +static void refill_buffer(stbi *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + if (n == 0) { + // at end of file, treat same as if from memory + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_end-1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static int get8(stbi *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +stbi_inline static int at_eof(stbi *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} + +stbi_inline static uint8 get8u(stbi *s) +{ + return (uint8) get8(s); +} + +static void skip(stbi *s, int n) +{ + if (s->io.read) { + int blen = s->img_buffer_end - s->img_buffer; + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} + +static int getn(stbi *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = s->img_buffer_end - s->img_buffer; + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} + +static int get16(stbi *s) +{ + int z = get8(s); + return (z << 8) + get8(s); +} + +static uint32 get32(stbi *s) +{ + uint32 z = get16(s); + return (z << 16) + get16(s); +} + +static int get16le(stbi *s) +{ + int z = get8(s); + return z + (get8(s) << 8); +} + +static uint32 get32le(stbi *s) +{ + uint32 z = get16le(s); + return z + (get16le(s) << 16); +} + +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static uint8 compute_y(int r, int g, int b) +{ + return (uint8) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static unsigned char *convert_format(unsigned char *data, int img_n, int req_comp, uint x, uint y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + assert(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) malloc(req_comp * x * y); + if (good == NULL) { + free(data); + return epuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define COMBO(a,b) ((a)*8+(b)) + #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (COMBO(img_n, req_comp)) { + CASE(1,2) dest[0]=src[0], dest[1]=255; break; + CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; + CASE(2,1) dest[0]=src[0]; break; + CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; + CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; + CASE(3,1) dest[0]=compute_y(src[0],src[1],src[2]); break; + CASE(3,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = 255; break; + CASE(4,1) dest[0]=compute_y(src[0],src[1],src[2]); break; + CASE(4,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; + CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; + default: assert(0); + } + #undef CASE + } + + free(data); + return good; +} + +#ifndef STBI_NO_HDR +static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output = (float *) malloc(x * y * comp * sizeof(float)); + if (output == NULL) { free(data); return epf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) pow(data[i*comp+k]/255.0f, l2h_gamma) * l2h_scale; + } + if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; + } + free(data); + return output; +} + +#define float2int(x) ((int) (x)) +static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output = (stbi_uc *) malloc(x * y * comp); + if (output == NULL) { free(data); return epuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*h2l_scale_i, h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (uint8) float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (uint8) float2int(z); + } + } + free(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder (not actually fully baseline implementation) +// +// simple implementation +// - channel subsampling of at most 2 in each dimension +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - uses a lot of intermediate memory, could cache poorly +// - load http://nothings.org/remote/anemones.jpg 3 times on 2.8Ghz P4 +// stb_jpeg: 1.34 seconds (MSVC6, default release build) +// stb_jpeg: 1.06 seconds (MSVC6, processor = Pentium Pro) +// IJL11.dll: 1.08 seconds (compiled by intel) +// IJG 1998: 0.98 seconds (MSVC6, makefile provided by IJG) +// IJG 1998: 0.95 seconds (MSVC6, makefile + proc=PPro) + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + uint8 fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + uint16 code[256]; + uint8 values[256]; + uint8 size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} huffman; + +typedef struct +{ + #ifdef STBI_SIMD + unsigned short dequant2[4][64]; + #endif + stbi *s; + huffman huff_dc[4]; + huffman huff_ac[4]; + uint8 dequant[4][64]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + uint8 *data; + void *raw_data; + uint8 *linebuf; + } img_comp[4]; + + uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int scan_n, order[4]; + int restart_interval, todo; +} jpeg; + +static int build_huffman(huffman *h, int *count) +{ + int i,j,k=0,code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (uint8) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (uint16) (code++); + if (code-1 >= (1 << j)) return e("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (uint8) i; + } + } + } + return 1; +} + +static void grow_buffer_unsafe(jpeg *j) +{ + do { + int b = j->nomore ? 0 : get8(j->s); + if (b == 0xff) { + int c = get8(j->s); + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static uint32 bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int decode(jpeg *j, huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & bmask[k]) + h->delta[k]; + assert((((j->code_buffer) >> (32 - h->size[c])) & bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// combined JPEG 'receive' and JPEG 'extend', since baseline +// always extends everything it receives. +stbi_inline static int extend_receive(jpeg *j, int n) +{ + unsigned int m = 1 << (n-1); + unsigned int k; + if (j->code_bits < n) grow_buffer_unsafe(j); + + #if 1 + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~bmask[n]; + k &= bmask[n]; + j->code_bits -= n; + #else + k = (j->code_buffer >> (32 - n)) & bmask[n]; + j->code_bits -= n; + j->code_buffer <<= n; + #endif + // the following test is probably a random branch that won't + // predict well. I tried to table accelerate it but failed. + // maybe it's compiling as a conditional move? + if (k < m) + return (-1 << n) + k + 1; + else + return k; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static uint8 dezigzag[64+15] = +{ + 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, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int decode_block(jpeg *j, short data[64], huffman *hdc, huffman *hac, int b) +{ + int diff,dc,k; + int t = decode(j, hdc); + if (t < 0) return e("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) dc; + + // decode AC components, see JPEG spec + k = 1; + do { + int r,s; + int rs = decode(j, hac); + if (rs < 0) return e("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + data[dezigzag[k++]] = (short) extend_receive(j,s); + } + } while (k < 64); + return 1; +} + +// take a -128..127 value and clamp it and convert to 0..255 +stbi_inline static uint8 clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (uint8) x; +} + +#define f2f(x) (int) (((x) * 4096 + 0.5)) +#define fsh(x) ((x) << 12) + +// derived from jidctint -- DCT_ISLOW +#define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * f2f(0.5411961f); \ + t2 = p1 + p3*f2f(-1.847759065f); \ + t3 = p1 + p2*f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = fsh(p2+p3); \ + t1 = fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*f2f( 1.175875602f); \ + t0 = t0*f2f( 0.298631336f); \ + t1 = t1*f2f( 2.053119869f); \ + t2 = t2*f2f( 3.072711026f); \ + t3 = t3*f2f( 1.501321110f); \ + p1 = p5 + p1*f2f(-0.899976223f); \ + p2 = p5 + p2*f2f(-2.562915447f); \ + p3 = p3*f2f(-1.961570560f); \ + p4 = p4*f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +#ifdef STBI_SIMD +typedef unsigned short stbi_dequantize_t; +#else +typedef uint8 stbi_dequantize_t; +#endif + +// .344 seconds on 3*anemones.jpg +static void idct_block(uint8 *out, int out_stride, short data[64], stbi_dequantize_t *dequantize) +{ + int i,val[64],*v=val; + stbi_dequantize_t *dq = dequantize; + uint8 *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d,++dq, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0] * dq[0] << 2; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + IDCT_1D(d[ 0]*dq[ 0],d[ 8]*dq[ 8],d[16]*dq[16],d[24]*dq[24], + d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = clamp((x0+t3) >> 17); + o[7] = clamp((x0-t3) >> 17); + o[1] = clamp((x1+t2) >> 17); + o[6] = clamp((x1-t2) >> 17); + o[2] = clamp((x2+t1) >> 17); + o[5] = clamp((x2-t1) >> 17); + o[3] = clamp((x3+t0) >> 17); + o[4] = clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SIMD +static stbi_idct_8x8 stbi_idct_installed = idct_block; + +void stbi_install_idct(stbi_idct_8x8 func) +{ + stbi_idct_installed = func; +} +#endif + +#define MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static uint8 get_marker(jpeg *j) +{ + uint8 x; + if (j->marker != MARKER_none) { x = j->marker; j->marker = MARKER_none; return x; } + x = get8u(j->s); + if (x != 0xff) return MARKER_none; + while (x == 0xff) + x = get8u(j->s); + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, reset the entropy decoder and +// the dc prediction +static void reset(jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->marker = MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int parse_entropy_coded_data(jpeg *z) +{ + reset(z); + if (z->scan_n == 1) { + int i,j; + #ifdef STBI_SIMD + __declspec(align(16)) + #endif + short data[64]; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; + #ifdef STBI_SIMD + stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); + #else + idct_block(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); + #endif + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RESTART(z->marker)) return 1; + reset(z); + } + } + } + } else { // interleaved! + int i,j,k,x,y; + short data[64]; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; + #ifdef STBI_SIMD + stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); + #else + idct_block(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); + #endif + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RESTART(z->marker)) return 1; + reset(z); + } + } + } + } + return 1; +} + +static int process_marker(jpeg *z, int m) +{ + int L; + switch (m) { + case MARKER_none: // no marker found + return e("expected marker","Corrupt JPEG"); + + case 0xC2: // SOF - progressive + return e("progressive jpeg","JPEG format not supported (progressive)"); + + case 0xDD: // DRI - specify restart interval + if (get16(z->s) != 4) return e("bad DRI len","Corrupt JPEG"); + z->restart_interval = get16(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = get16(z->s)-2; + while (L > 0) { + int q = get8(z->s); + int p = q >> 4; + int t = q & 15,i; + if (p != 0) return e("bad DQT type","Corrupt JPEG"); + if (t > 3) return e("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) + z->dequant[t][dezigzag[i]] = get8u(z->s); + #ifdef STBI_SIMD + for (i=0; i < 64; ++i) + z->dequant2[t][i] = z->dequant[t][i]; + #endif + L -= 65; + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = get16(z->s)-2; + while (L > 0) { + uint8 *v; + int sizes[16],i,m=0; + int q = get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return e("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = get8(z->s); + m += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < m; ++i) + v[i] = get8u(z->s); + L -= m; + } + return L==0; + } + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + skip(z->s, get16(z->s)-2); + return 1; + } + return 0; +} + +// after we see SOS +static int process_scan_header(jpeg *z) +{ + int i; + int Ls = get16(z->s); + z->scan_n = get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return e("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return e("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = get8(z->s), which; + int q = get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return e("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return e("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG"); + get8(z->s); // should be 63, but might be 0 + if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG"); + + return 1; +} + +static int process_frame_header(jpeg *z, int scan) +{ + stbi *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = get16(s); if (Lf < 11) return e("bad SOF len","Corrupt JPEG"); // JPEG + p = get8(s); if (p != 8) return e("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = get16(s); if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = get16(s); if (s->img_x == 0) return e("0 width","Corrupt JPEG"); // JPEG requires + c = get8(s); + if (c != 3 && c != 1) return e("bad component count","Corrupt JPEG"); // JFIF requires + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return e("bad SOF len","Corrupt JPEG"); + + for (i=0; i < s->img_n; ++i) { + z->img_comp[i].id = get8(s); + if (z->img_comp[i].id != i+1) // JFIF requires + if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! + return e("bad component ID","Corrupt JPEG"); + q = get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return e("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return e("bad V","Corrupt JPEG"); + z->img_comp[i].tq = get8(s); if (z->img_comp[i].tq > 3) return e("bad TQ","Corrupt JPEG"); + } + + if (scan != SCAN_load) return 1; + + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); + if (z->img_comp[i].raw_data == NULL) { + for(--i; i >= 0; --i) { + free(z->img_comp[i].raw_data); + z->img_comp[i].data = NULL; + } + return e("outofmem", "Out of memory"); + } + // align blocks for installable-idct using mmx/sse + z->img_comp[i].data = (uint8*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + z->img_comp[i].linebuf = NULL; + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define DNL(x) ((x) == 0xdc) +#define SOI(x) ((x) == 0xd8) +#define EOI(x) ((x) == 0xd9) +#define SOF(x) ((x) == 0xc0 || (x) == 0xc1) +#define SOS(x) ((x) == 0xda) + +static int decode_jpeg_header(jpeg *z, int scan) +{ + int m; + z->marker = MARKER_none; // initialize cached marker to empty + m = get_marker(z); + if (!SOI(m)) return e("no SOI","Corrupt JPEG"); + if (scan == SCAN_type) return 1; + m = get_marker(z); + while (!SOF(m)) { + if (!process_marker(z,m)) return 0; + m = get_marker(z); + while (m == MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (at_eof(z->s)) return e("no SOF", "Corrupt JPEG"); + m = get_marker(z); + } + } + if (!process_frame_header(z, scan)) return 0; + return 1; +} + +static int decode_jpeg_image(jpeg *j) +{ + int m; + j->restart_interval = 0; + if (!decode_jpeg_header(j, SCAN_load)) return 0; + m = get_marker(j); + while (!EOI(m)) { + if (SOS(m)) { + if (!process_scan_header(j)) return 0; + if (!parse_entropy_coded_data(j)) return 0; + if (j->marker == MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!at_eof(j->s)) { + int x = get8(j->s); + if (x == 255) { + j->marker = get8u(j->s); + break; + } else if (x != 0) { + return 0; + } + } + // if we reach eof without hitting a marker, get_marker() below will fail and we'll eventually return 0 + } + } else { + if (!process_marker(j, m)) return 0; + } + m = get_marker(j); + } + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef uint8 *(*resample_row_func)(uint8 *out, uint8 *in0, uint8 *in1, + int w, int hs); + +#define div4(x) ((uint8) ((x) >> 2)) + +static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + uint8 *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = div4(n+input[i-1]); + out[i*2+1] = div4(n+input[i+1]); + } + out[i*2+0] = div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define div16(x) ((uint8) ((x) >> 4)) + +static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = div16(3*t0 + t1 + 8); + out[i*2 ] = div16(3*t1 + t0 + 8); + } + out[w*2-1] = div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + in_far = in_far; + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) + +// 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro) +// VC6 without processor=Pro is generating multiple LEAs per multiply! +static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 16) + 32768; // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr*float2fixed(1.40200f); + g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); + b = y_fixed + cb*float2fixed(1.77200f); + r >>= 16; + g >>= 16; + b >>= 16; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (uint8)r; + out[1] = (uint8)g; + out[2] = (uint8)b; + out[3] = 255; + out += step; + } +} + +#ifdef STBI_SIMD +static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row; + +void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func) +{ + stbi_YCbCr_installed = func; +} +#endif + + +// clean up the temporary component buffers +static void cleanup_jpeg(jpeg *j) +{ + int i; + for (i=0; i < j->s->img_n; ++i) { + if (j->img_comp[i].data) { + free(j->img_comp[i].raw_data); + j->img_comp[i].data = NULL; + } + if (j->img_comp[i].linebuf) { + free(j->img_comp[i].linebuf); + j->img_comp[i].linebuf = NULL; + } + } +} + +typedef struct +{ + resample_row_func resample; + uint8 *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi_resample; + +static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n; + // validate req_comp + if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); + z->s->img_n = 0; + + // load a jpeg image from whichever source + if (!decode_jpeg_image(z)) { cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n; + + if (z->s->img_n == 3 && n < 3) + decode_n = 1; + else + decode_n = z->s->img_n; + + // resample and color-convert + { + int k; + uint i,j; + uint8 *output; + uint8 *coutput[4]; + + stbi_resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi_resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (uint8 *) malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = resample_row_hv_2; + else r->resample = resample_row_generic; + } + + // can't error after this so, this is safe + output = (uint8 *) malloc(n * z->s->img_x * z->s->img_y + 1); + if (!output) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + uint8 *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi_resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + uint8 *y = coutput[0]; + if (z->s->img_n == 3) { + #ifdef STBI_SIMD + stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n); + #else + YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s->img_x, n); + #endif + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + uint8 *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } + } + cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n; // report original components, not output + return output; + } +} + +static unsigned char *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + jpeg j; + j.s = s; + return load_jpeg_image(&j, x,y,comp,req_comp); +} + +static int stbi_jpeg_test(stbi *s) +{ + int r; + jpeg j; + j.s = s; + r = decode_jpeg_header(&j, SCAN_type); + stbi_rewind(s); + return r; +} + +static int stbi_jpeg_info_raw(jpeg *j, int *x, int *y, int *comp) +{ + if (!decode_jpeg_header(j, SCAN_header)) { + stbi_rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n; + return 1; +} + +static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp) +{ + jpeg j; + j.s = s; + return stbi_jpeg_info_raw(&j, x, y, comp); +} + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define ZFAST_BITS 9 // accelerate all cases in default tables +#define ZFAST_MASK ((1 << ZFAST_BITS) - 1) + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + uint16 fast[1 << ZFAST_BITS]; + uint16 firstcode[16]; + int maxcode[17]; + uint16 firstsymbol[16]; + uint8 size[288]; + uint16 value[288]; +} zhuffman; + +stbi_inline static int bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int bit_reverse(int v, int bits) +{ + assert(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return bitreverse16(v) >> (16-bits); +} + +static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 255, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + assert(sizes[i] <= (1 << i)); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (uint16) code; + z->firstsymbol[i] = (uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return e("bad codelengths","Corrupt JPEG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + z->size[c] = (uint8)s; + z->value[c] = (uint16)i; + if (s <= ZFAST_BITS) { + int k = bit_reverse(next_code[s],s); + while (k < (1 << ZFAST_BITS)) { + z->fast[k] = (uint16) c; + k += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + uint8 *zbuffer, *zbuffer_end; + int num_bits; + uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + zhuffman z_length, z_distance; +} zbuf; + +stbi_inline static int zget8(zbuf *z) +{ + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; +} + +static void fill_bits(zbuf *z) +{ + do { + assert(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int zreceive(zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +stbi_inline static int zhuffman_decode(zbuf *a, zhuffman *z) +{ + int b,s,k; + if (a->num_bits < 16) fill_bits(a); + b = z->fast[a->code_buffer & ZFAST_MASK]; + if (b < 0xffff) { + s = z->size[b]; + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; + } + + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = bit_reverse(a->code_buffer, 16); + for (s=ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + assert(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +static int expand(zbuf *z, int n) // need to make room for n bytes +{ + char *q; + int cur, limit; + if (!z->z_expandable) return e("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) realloc(z->zout_start, limit); + if (q == NULL) return e("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static int length_base[31] = { + 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 int length_extra[31]= +{ 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,0,0 }; + +static int dist_base[32] = { 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 int dist_extra[32] = +{ 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}; + +static int parse_huffman_block(zbuf *a) +{ + for(;;) { + int z = zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return e("bad huffman code","Corrupt PNG"); // error in huffman codes + if (a->zout >= a->zout_end) if (!expand(a, 1)) return 0; + *a->zout++ = (char) z; + } else { + uint8 *p; + int len,dist; + if (z == 256) return 1; + z -= 257; + len = length_base[z]; + if (length_extra[z]) len += zreceive(a, length_extra[z]); + z = zhuffman_decode(a, &a->z_distance); + if (z < 0) return e("bad huffman code","Corrupt PNG"); + dist = dist_base[z]; + if (dist_extra[z]) dist += zreceive(a, dist_extra[z]); + if (a->zout - a->zout_start < dist) return e("bad dist","Corrupt PNG"); + if (a->zout + len > a->zout_end) if (!expand(a, len)) return 0; + p = (uint8 *) (a->zout - dist); + while (len--) + *a->zout++ = *p++; + } + } +} + +static int compute_huffman_codes(zbuf *a) +{ + static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + zhuffman z_codelength; + uint8 lencodes[286+32+137];//padding for maximum single op + uint8 codelength_sizes[19]; + int i,n; + + int hlit = zreceive(a,5) + 257; + int hdist = zreceive(a,5) + 1; + int hclen = zreceive(a,4) + 4; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (uint8) s; + } + if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < hlit + hdist) { + int c = zhuffman_decode(a, &z_codelength); + assert(c >= 0 && c < 19); + if (c < 16) + lencodes[n++] = (uint8) c; + else if (c == 16) { + c = zreceive(a,2)+3; + memset(lencodes+n, lencodes[n-1], c); + n += c; + } else if (c == 17) { + c = zreceive(a,3)+3; + memset(lencodes+n, 0, c); + n += c; + } else { + assert(c == 18); + c = zreceive(a,7)+11; + memset(lencodes+n, 0, c); + n += c; + } + } + if (n != hlit+hdist) return e("bad codelengths","Corrupt PNG"); + if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int parse_uncompressed_block(zbuf *a) +{ + uint8 header[4]; + int len,nlen,k; + if (a->num_bits & 7) + zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (uint8) (a->code_buffer & 255); // wtf this warns? + a->code_buffer >>= 8; + a->num_bits -= 8; + } + assert(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = (uint8) zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return e("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!expand(a, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int parse_zlib_header(zbuf *a) +{ + int cmf = zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = zget8(a); + if ((cmf*256+flg) % 31 != 0) return e("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return e("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return e("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +// @TODO: should statically initialize these for optimal thread safety +static uint8 default_length[288], default_distance[32]; +static void init_defaults(void) +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) default_length[i] = 8; + for ( ; i <= 255; ++i) default_length[i] = 9; + for ( ; i <= 279; ++i) default_length[i] = 7; + for ( ; i <= 287; ++i) default_length[i] = 8; + + for (i=0; i <= 31; ++i) default_distance[i] = 5; +} + +static int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead +static int parse_zlib(zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = zreceive(a,1); + type = zreceive(a,2); + if (type == 0) { + if (!parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!default_distance[31]) init_defaults(); + if (!zbuild_huffman(&a->z_length , default_length , 288)) return 0; + if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0; + } else { + if (!compute_huffman_codes(a)) return 0; + } + if (!parse_huffman_block(a)) return 0; + } + if (stbi_png_partial && a->zout - a->zout_start > 65536) + break; + } while (!final); + return 1; +} + +static int do_zlib(zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return parse_zlib(a, parse_header); +} + +char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + zbuf a; + char *p = (char *) malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer + len; + if (do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + zbuf a; + char *p = (char *) malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer + len; + if (do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + zbuf a; + a.zbuffer = (uint8 *) ibuffer; + a.zbuffer_end = (uint8 *) ibuffer + ilen; + if (do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + zbuf a; + char *p = (char *) malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer+len; + if (do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + zbuf a; + a.zbuffer = (uint8 *) ibuffer; + a.zbuffer_end = (uint8 *) ibuffer + ilen; + if (do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + + +typedef struct +{ + uint32 length; + uint32 type; +} chunk; + +#define PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) + +static chunk get_chunk_header(stbi *s) +{ + chunk c; + c.length = get32(s); + c.type = get32(s); + return c; +} + +static int check_png_header(stbi *s) +{ + static uint8 png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (get8u(s) != png_sig[i]) return e("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi *s; + uint8 *idata, *expanded, *out; +} png; + + +enum { + F_none=0, F_sub=1, F_up=2, F_avg=3, F_paeth=4, + F_avg_first, F_paeth_first +}; + +static uint8 first_row_filter[5] = +{ + F_none, F_sub, F_none, F_avg_first, F_paeth_first +}; + +static int paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +// create the png data from post-deflated data +static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y) +{ + stbi *s = a->s; + uint32 i,j,stride = x*out_n; + int k; + int img_n = s->img_n; // copy it into a local for later + assert(out_n == s->img_n || out_n == s->img_n+1); + if (stbi_png_partial) y = 1; + a->out = (uint8 *) malloc(x * y * out_n); + if (!a->out) return e("outofmem", "Out of memory"); + if (!stbi_png_partial) { + if (s->img_x == x && s->img_y == y) { + if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); + } else { // interlaced: + if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); + } + } + for (j=0; j < y; ++j) { + uint8 *cur = a->out + stride*j; + uint8 *prior = cur - stride; + int filter = *raw++; + if (filter > 4) return e("invalid filter","Corrupt PNG"); + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + // handle first pixel explicitly + for (k=0; k < img_n; ++k) { + switch (filter) { + case F_none : cur[k] = raw[k]; break; + case F_sub : cur[k] = raw[k]; break; + case F_up : cur[k] = raw[k] + prior[k]; break; + case F_avg : cur[k] = raw[k] + (prior[k]>>1); break; + case F_paeth : cur[k] = (uint8) (raw[k] + paeth(0,prior[k],0)); break; + case F_avg_first : cur[k] = raw[k]; break; + case F_paeth_first: cur[k] = raw[k]; break; + } + } + if (img_n != out_n) cur[img_n] = 255; + raw += img_n; + cur += out_n; + prior += out_n; + // this is a little gross, so that we don't switch per-pixel or per-component + if (img_n == out_n) { + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ + for (k=0; k < img_n; ++k) + switch (filter) { + CASE(F_none) cur[k] = raw[k]; break; + CASE(F_sub) cur[k] = raw[k] + cur[k-img_n]; break; + CASE(F_up) cur[k] = raw[k] + prior[k]; break; + CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-img_n])>>1); break; + CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],prior[k],prior[k-img_n])); break; + CASE(F_avg_first) cur[k] = raw[k] + (cur[k-img_n] >> 1); break; + CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],0,0)); break; + } + #undef CASE + } else { + assert(img_n+1 == out_n); + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ + for (k=0; k < img_n; ++k) + switch (filter) { + CASE(F_none) cur[k] = raw[k]; break; + CASE(F_sub) cur[k] = raw[k] + cur[k-out_n]; break; + CASE(F_up) cur[k] = raw[k] + prior[k]; break; + CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-out_n])>>1); break; + CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; + CASE(F_avg_first) cur[k] = raw[k] + (cur[k-out_n] >> 1); break; + CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],0,0)); break; + } + #undef CASE + } + } + return 1; +} + +static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced) +{ + uint8 *final; + int p; + int save; + if (!interlaced) + return create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y); + save = stbi_png_partial; + stbi_png_partial = 0; + + // de-interlacing + final = (uint8 *) malloc(a->s->img_x * a->s->img_y * out_n); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) { + free(final); + return 0; + } + for (j=0; j < y; ++j) + for (i=0; i < x; ++i) + memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n, + a->out + (j*x+i)*out_n, out_n); + free(a->out); + raw += (x*out_n+1)*y; + raw_len -= (x*out_n+1)*y; + } + } + a->out = final; + + stbi_png_partial = save; + return 1; +} + +static int compute_transparency(png *z, uint8 tc[3], int out_n) +{ + stbi *s = z->s; + uint32 i, pixel_count = s->img_x * s->img_y; + uint8 *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + assert(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n) +{ + uint32 i, pixel_count = a->s->img_x * a->s->img_y; + uint8 *p, *temp_out, *orig = a->out; + + p = (uint8 *) malloc(pixel_count * pal_img_n); + if (p == NULL) return e("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + free(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi_unpremultiply_on_load = 0; +static int stbi_de_iphone_flag = 0; + +void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi_unpremultiply_on_load = flag_true_if_should_unpremultiply; +} +void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi_de_iphone_flag = flag_true_if_should_convert; +} + +static void stbi_de_iphone(png *z) +{ + stbi *s = z->s; + uint32 i, pixel_count = s->img_x * s->img_y; + uint8 *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + uint8 t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + assert(s->img_out_n == 4); + if (stbi_unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + uint8 a = p[3]; + uint8 t = p[0]; + if (a) { + p[0] = p[2] * 255 / a; + p[1] = p[1] * 255 / a; + p[2] = t * 255 / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + uint8 t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +static int parse_png_file(png *z, int scan, int req_comp) +{ + uint8 palette[1024], pal_img_n=0; + uint8 has_trans=0, tc[3]; + uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, iphone=0; + stbi *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!check_png_header(s)) return 0; + + if (scan == SCAN_type) return 1; + + for (;;) { + chunk c = get_chunk_header(s); + switch (c.type) { + case PNG_TYPE('C','g','B','I'): + iphone = stbi_de_iphone_flag; + skip(s, c.length); + break; + case PNG_TYPE('I','H','D','R'): { + int depth,color,comp,filter; + if (!first) return e("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return e("bad IHDR len","Corrupt PNG"); + s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)"); + s->img_y = get32(s); if (s->img_y > (1 << 24)) return e("too large","Very large image (corrupt?)"); + depth = get8(s); if (depth != 8) return e("8bit only","PNG not supported: 8-bit only"); + color = get8(s); if (color > 6) return e("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG"); + comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG"); + filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG"); + interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); + if (scan == SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case PNG_TYPE('P','L','T','E'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return e("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return e("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = get8u(s); + palette[i*4+1] = get8u(s); + palette[i*4+2] = get8u(s); + palette[i*4+3] = 255; + } + break; + } + + case PNG_TYPE('t','R','N','S'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (z->idata) return e("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return e("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return e("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = get8u(s); + } else { + if (!(s->img_n & 1)) return e("tRNS with alpha","Corrupt PNG"); + if (c.length != (uint32) s->img_n*2) return e("bad tRNS len","Corrupt PNG"); + has_trans = 1; + for (k=0; k < s->img_n; ++k) + tc[k] = (uint8) get16(s); // non 8-bit images will be larger + } + break; + } + + case PNG_TYPE('I','D','A','T'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return e("no PLTE","Corrupt PNG"); + if (scan == SCAN_header) { s->img_n = pal_img_n; return 1; } + if (ioff + c.length > idata_limit) { + uint8 *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + p = (uint8 *) realloc(z->idata, idata_limit); if (p == NULL) return e("outofmem", "Out of memory"); + z->idata = p; + } + if (!getn(s, z->idata+ioff,c.length)) return e("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case PNG_TYPE('I','E','N','D'): { + uint32 raw_len; + if (first) return e("first not IHDR", "Corrupt PNG"); + if (scan != SCAN_load) return 1; + if (z->idata == NULL) return e("no IDAT","Corrupt PNG"); + z->expanded = (uint8 *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, 16384, (int *) &raw_len, !iphone); + if (z->expanded == NULL) return 0; // zlib should set error + free(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; + if (has_trans) + if (!compute_transparency(z, tc, s->img_out_n)) return 0; + if (iphone && s->img_out_n > 2) + stbi_de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!expand_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + free(z->expanded); z->expanded = NULL; + return 1; + } + + default: + // if critical, fail + if (first) return e("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX chunk not known"; + invalid_chunk[0] = (uint8) (c.type >> 24); + invalid_chunk[1] = (uint8) (c.type >> 16); + invalid_chunk[2] = (uint8) (c.type >> 8); + invalid_chunk[3] = (uint8) (c.type >> 0); + #endif + return e(invalid_chunk, "PNG not supported: unknown chunk type"); + } + skip(s, c.length); + break; + } + // end of chunk, read and skip CRC + get32(s); + } +} + +static unsigned char *do_png(png *p, int *x, int *y, int *n, int req_comp) +{ + unsigned char *result=NULL; + if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); + if (parse_png_file(p, SCAN_load, req_comp)) { + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + result = convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + free(p->out); p->out = NULL; + free(p->expanded); p->expanded = NULL; + free(p->idata); p->idata = NULL; + + return result; +} + +static unsigned char *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + png p; + p.s = s; + return do_png(&p, x,y,comp,req_comp); +} + +static int stbi_png_test(stbi *s) +{ + int r; + r = check_png_header(s); + stbi_rewind(s); + return r; +} + +static int stbi_png_info_raw(png *p, int *x, int *y, int *comp) +{ + if (!parse_png_file(p, SCAN_header, 0)) { + stbi_rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi_png_info(stbi *s, int *x, int *y, int *comp) +{ + png p; + p.s = s; + return stbi_png_info_raw(&p, x, y, comp); +} + +// Microsoft/Windows BMP image + +static int bmp_test(stbi *s) +{ + int sz; + if (get8(s) != 'B') return 0; + if (get8(s) != 'M') return 0; + get32le(s); // discard filesize + get16le(s); // discard reserved + get16le(s); // discard reserved + get32le(s); // discard data offset + sz = get32le(s); + if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1; + return 0; +} + +static int stbi_bmp_test(stbi *s) +{ + int r = bmp_test(s); + stbi_rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) n += 16, z >>= 16; + if (z >= 0x00100) n += 8, z >>= 8; + if (z >= 0x00010) n += 4, z >>= 4; + if (z >= 0x00004) n += 2, z >>= 2; + if (z >= 0x00002) n += 1, z >>= 1; + return n; +} + +static int bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +static int shiftsigned(int v, int shift, int bits) +{ + int result; + int z=0; + + if (shift < 0) v <<= -shift; + else v >>= shift; + result = v; + + z = bits; + while (z < 8) { + result += v >> z; + z += bits; + } + return result; +} + +static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + uint8 *out; + unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0; + stbi_uc pal[256][4]; + int psize=0,i,j,compress=0,width; + int bpp, flip_vertically, pad, target, offset, hsz; + if (get8(s) != 'B' || get8(s) != 'M') return epuc("not BMP", "Corrupt BMP"); + get32le(s); // discard filesize + get16le(s); // discard reserved + get16le(s); // discard reserved + offset = get32le(s); + hsz = get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return epuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = get16le(s); + s->img_y = get16le(s); + } else { + s->img_x = get32le(s); + s->img_y = get32le(s); + } + if (get16le(s) != 1) return epuc("bad BMP", "bad BMP"); + bpp = get16le(s); + if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit"); + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + if (hsz == 12) { + if (bpp < 24) + psize = (offset - 14 - 24) / 3; + } else { + compress = get32le(s); + if (compress == 1 || compress == 2) return epuc("BMP RLE", "BMP type not supported: RLE"); + get32le(s); // discard sizeof + get32le(s); // discard hres + get32le(s); // discard vres + get32le(s); // discard colorsused + get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + get32le(s); + get32le(s); + get32le(s); + get32le(s); + } + if (bpp == 16 || bpp == 32) { + mr = mg = mb = 0; + if (compress == 0) { + if (bpp == 32) { + mr = 0xffu << 16; + mg = 0xffu << 8; + mb = 0xffu << 0; + ma = 0xffu << 24; + fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 + } else { + mr = 31u << 10; + mg = 31u << 5; + mb = 31u << 0; + } + } else if (compress == 3) { + mr = get32le(s); + mg = get32le(s); + mb = get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (mr == mg && mg == mb) { + // ?!?!? + return epuc("bad BMP", "bad BMP"); + } + } else + return epuc("bad BMP", "bad BMP"); + } + } else { + assert(hsz == 108); + mr = get32le(s); + mg = get32le(s); + mb = get32le(s); + ma = get32le(s); + get32le(s); // discard color space + for (i=0; i < 12; ++i) + get32le(s); // discard color space parameters + } + if (bpp < 16) + psize = (offset - 14 - hsz) >> 2; + } + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + out = (stbi_uc *) malloc(target * s->img_x * s->img_y); + if (!out) return epuc("outofmem", "Out of memory"); + if (bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = get8u(s); + pal[i][1] = get8u(s); + pal[i][0] = get8u(s); + if (hsz != 12) get8(s); + pal[i][3] = 255; + } + skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); + if (bpp == 4) width = (s->img_x + 1) >> 1; + else if (bpp == 8) width = s->img_x; + else { free(out); return epuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=get8(s),v2=0; + if (bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (bpp == 8) ? get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + skip(s, pad); + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + skip(s, offset - 14 - hsz); + if (bpp == 24) width = 3 * s->img_x; + else if (bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (bpp == 24) { + easy = 1; + } else if (bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { free(out); return epuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = high_bit(mr)-7; rcount = bitcount(mr); + gshift = high_bit(mg)-7; gcount = bitcount(mr); + bshift = high_bit(mb)-7; bcount = bitcount(mr); + ashift = high_bit(ma)-7; acount = bitcount(mr); + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + int a; + out[z+2] = get8u(s); + out[z+1] = get8u(s); + out[z+0] = get8u(s); + z += 3; + a = (easy == 2 ? get8(s) : 255); + if (target == 4) out[z++] = (uint8) a; + } + } else { + for (i=0; i < (int) s->img_x; ++i) { + uint32 v = (bpp == 16 ? get16le(s) : get32le(s)); + int a; + out[z++] = (uint8) shiftsigned(v & mr, rshift, rcount); + out[z++] = (uint8) shiftsigned(v & mg, gshift, gcount); + out[z++] = (uint8) shiftsigned(v & mb, bshift, bcount); + a = (ma ? shiftsigned(v & ma, ashift, acount) : 255); + if (target == 4) out[z++] = (uint8) a; + } + } + skip(s, pad); + } + } + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i], p1[i] = p2[i], p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} + +static stbi_uc *stbi_bmp_load(stbi *s,int *x, int *y, int *comp, int req_comp) +{ + return bmp_load(s, x,y,comp,req_comp); +} + + +// Targa Truevision - TGA +// by Jonathan Dummer + +static int tga_info(stbi *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp; + int sz; + get8u(s); // discard Offset + sz = get8u(s); // color type + if( sz > 1 ) { + stbi_rewind(s); + return 0; // only RGB or indexed allowed + } + sz = get8u(s); // image type + // only RGB or grey allowed, +/- RLE + if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; + skip(s,9); + tga_w = get16le(s); + if( tga_w < 1 ) { + stbi_rewind(s); + return 0; // test width + } + tga_h = get16le(s); + if( tga_h < 1 ) { + stbi_rewind(s); + return 0; // test height + } + sz = get8(s); // bits per pixel + // only RGB or RGBA or grey allowed + if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) { + stbi_rewind(s); + return 0; + } + tga_comp = sz; + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp / 8; + return 1; // seems to have passed everything +} + +int stbi_tga_info(stbi *s, int *x, int *y, int *comp) +{ + return tga_info(s, x, y, comp); +} + +static int tga_test(stbi *s) +{ + int sz; + get8u(s); // discard Offset + sz = get8u(s); // color type + if ( sz > 1 ) return 0; // only RGB or indexed allowed + sz = get8u(s); // image type + if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE + get16(s); // discard palette start + get16(s); // discard palette length + get8(s); // discard bits per palette color entry + get16(s); // discard x origin + get16(s); // discard y origin + if ( get16(s) < 1 ) return 0; // test width + if ( get16(s) < 1 ) return 0; // test height + sz = get8(s); // bits per pixel + if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) return 0; // only RGB or RGBA or grey allowed + return 1; // seems to have passed everything +} + +static int stbi_tga_test(stbi *s) +{ + int res = tga_test(s); + stbi_rewind(s); + return res; +} + +static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + // read in the TGA header stuff + int tga_offset = get8u(s); + int tga_indexed = get8u(s); + int tga_image_type = get8u(s); + int tga_is_RLE = 0; + int tga_palette_start = get16le(s); + int tga_palette_len = get16le(s); + int tga_palette_bits = get8u(s); + int tga_x_origin = get16le(s); + int tga_y_origin = get16le(s); + int tga_width = get16le(s); + int tga_height = get16le(s); + int tga_bits_per_pixel = get8u(s); + int tga_inverted = get8u(s); + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4]; + unsigned char trans_data[4]; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + /* int tga_alpha_bits = tga_inverted & 15; */ + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // error check + if ( //(tga_indexed) || + (tga_width < 1) || (tga_height < 1) || + (tga_image_type < 1) || (tga_image_type > 3) || + ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && + (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) + ) + { + return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA + } + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) + { + tga_bits_per_pixel = tga_palette_bits; + } + + // tga info + *x = tga_width; + *y = tga_height; + if ( (req_comp < 1) || (req_comp > 4) ) + { + // just use whatever the file was + req_comp = tga_bits_per_pixel / 8; + *comp = req_comp; + } else + { + // force a new number of components + *comp = tga_bits_per_pixel/8; + } + tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp ); + if (!tga_data) return epuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + skip(s, tga_offset ); + // do I need to load a palette? + if ( tga_indexed ) + { + // any data to skip? (offset usually = 0) + skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 ); + if (!tga_palette) { + free(tga_data); + return epuc("outofmem", "Out of memory"); + } + if (!getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) { + free(tga_data); + free(tga_palette); + return epuc("bad palette", "Corrupt TGA"); + } + } + // load the data + trans_data[0] = trans_data[1] = trans_data[2] = trans_data[3] = 0; + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE chunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = get8u(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in 1 byte, then perform the lookup + int pal_idx = get8u(s); + if ( pal_idx >= tga_palette_len ) + { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_bits_per_pixel / 8; + for (j = 0; j*8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else + { + // read in the data raw + for (j = 0; j*8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = get8u(s); + } + } + // convert raw to the intermediate format + switch (tga_bits_per_pixel) + { + case 8: + // Luminous => RGBA + trans_data[0] = raw_data[0]; + trans_data[1] = raw_data[0]; + trans_data[2] = raw_data[0]; + trans_data[3] = 255; + break; + case 16: + // Luminous,Alpha => RGBA + trans_data[0] = raw_data[0]; + trans_data[1] = raw_data[0]; + trans_data[2] = raw_data[0]; + trans_data[3] = raw_data[1]; + break; + case 24: + // BGR => RGBA + trans_data[0] = raw_data[2]; + trans_data[1] = raw_data[1]; + trans_data[2] = raw_data[0]; + trans_data[3] = 255; + break; + case 32: + // BGRA => RGBA + trans_data[0] = raw_data[2]; + trans_data[1] = raw_data[1]; + trans_data[2] = raw_data[0]; + trans_data[3] = raw_data[3]; + break; + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + // convert to final format + switch (req_comp) + { + case 1: + // RGBA => Luminance + tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); + break; + case 2: + // RGBA => Luminance,Alpha + tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); + tga_data[i*req_comp+1] = trans_data[3]; + break; + case 3: + // RGBA => RGB + tga_data[i*req_comp+0] = trans_data[0]; + tga_data[i*req_comp+1] = trans_data[1]; + tga_data[i*req_comp+2] = trans_data[2]; + break; + case 4: + // RGBA => RGBA + tga_data[i*req_comp+0] = trans_data[0]; + tga_data[i*req_comp+1] = trans_data[1]; + tga_data[i*req_comp+2] = trans_data[2]; + tga_data[i*req_comp+3] = trans_data[3]; + break; + } + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * req_comp; + int index2 = (tga_height - 1 - j) * tga_width * req_comp; + for (i = tga_width * req_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + free( tga_palette ); + } + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + // OK, done + return tga_data; +} + +static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + return tga_load(s,x,y,comp,req_comp); +} + + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +static int psd_test(stbi *s) +{ + if (get32(s) != 0x38425053) return 0; // "8BPS" + else return 1; +} + +static int stbi_psd_test(stbi *s) +{ + int r = psd_test(s); + stbi_rewind(s); + return r; +} + +static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + int pixelCount; + int channelCount, compression; + int channel, i, count, len; + int w,h; + uint8 *out; + + // Check identifier + if (get32(s) != 0x38425053) // "8BPS" + return epuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (get16(s) != 1) + return epuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = get16(s); + if (channelCount < 0 || channelCount > 16) + return epuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = get32(s); + w = get32(s); + + // Make sure the depth is 8 bits. + if (get16(s) != 8) + return epuc("unsupported bit depth", "PSD bit depth is not 8 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (get16(s) != 3) + return epuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + skip(s,get32(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + skip(s, get32(s) ); + + // Skip the reserved data. + skip(s, get32(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = get16(s); + if (compression > 1) + return epuc("bad compression", "PSD has an unknown compression format"); + + // Create the destination image. + out = (stbi_uc *) malloc(4 * w*h); + if (!out) return epuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // which we're going to just skip. + skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + uint8 *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; + } else { + // Read the RLE data. + count = 0; + while (count < pixelCount) { + len = get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + count += len; + while (len) { + *p = get8u(s); + p += 4; + len--; + } + } else if (len > 128) { + uint8 val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len ^= 0x0FF; + len += 2; + val = get8u(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + uint8 *p; + + p = out + channel; + if (channel > channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; + } else { + // Read the data. + for (i = 0; i < pixelCount; i++) + *p = get8u(s), p += 4; + } + } + } + + if (req_comp && req_comp != 4) { + out = convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // convert_format frees input on failure + } + + if (comp) *comp = channelCount; + *y = h; + *x = w; + + return out; +} + +static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + return psd_load(s,x,y,comp,req_comp); +} + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +static int pic_is4(stbi *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int pic_test(stbi *s) +{ + int i; + + if (!pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + get8(s); + + if (!pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} pic_packet_t; + +static stbi_uc *pic_readval(stbi *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (at_eof(s)) return epuc("bad file","PIC file too short"); + dest[i]=get8u(s); + } + } + + return dest; +} + +static void pic_copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *pic_load2(stbi *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + pic_packet_t packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + pic_packet_t *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return epuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = get8(s); + packet->size = get8u(s); + packet->type = get8u(s); + packet->channel = get8u(s); + + act_comp |= packet->channel; + + if (at_eof(s)) return epuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return epuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return epuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=get8u(s); + if (at_eof(s)) return epuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (uint8) left; + + if (!pic_readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = get8(s), i; + if (at_eof(s)) return epuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + int i; + + if (count==128) + count = get16(s); + else + count -= 127; + if (count > left) + return epuc("bad file","scanline overrun"); + + if (!pic_readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return epuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static stbi_uc *pic_load(stbi *s,int *px,int *py,int *comp,int req_comp) +{ + stbi_uc *result; + int i, x,y; + + for (i=0; i<92; ++i) + get8(s); + + x = get16(s); + y = get16(s); + if (at_eof(s)) return epuc("bad file","file too short (pic header)"); + if ((1 << 28) / x < y) return epuc("too large", "Image too large to decode"); + + get32(s); //skip `ratio' + get16(s); //skip `fields' + get16(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) malloc(x*y*4); + memset(result, 0xff, x*y*4); + + if (!pic_load2(s,x,y,comp, result)) { + free(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi_pic_test(stbi *s) +{ + int r = pic_test(s); + stbi_rewind(s); + return r; +} + +static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + return pic_load(s,x,y,comp,req_comp); +} + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb +typedef struct stbi_gif_lzw_struct { + int16 prefix; + uint8 first; + uint8 suffix; +} stbi_gif_lzw; + +typedef struct stbi_gif_struct +{ + int w,h; + stbi_uc *out; // output buffer (always 4 components) + int flags, bgindex, ratio, transparent, eflags; + uint8 pal[256][4]; + uint8 lpal[256][4]; + stbi_gif_lzw codes[4096]; + uint8 *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; +} stbi_gif; + +static int gif_test(stbi *s) +{ + int sz; + if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') return 0; + sz = get8(s); + if (sz != '9' && sz != '7') return 0; + if (get8(s) != 'a') return 0; + return 1; +} + +static int stbi_gif_test(stbi *s) +{ + int r = gif_test(s); + stbi_rewind(s); + return r; +} + +static void stbi_gif_parse_colortable(stbi *s, uint8 pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = get8u(s); + pal[i][1] = get8u(s); + pal[i][0] = get8u(s); + pal[i][3] = transp ? 0 : 255; + } +} + +static int stbi_gif_header(stbi *s, stbi_gif *g, int *comp, int is_info) +{ + uint8 version; + if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') + return e("not GIF", "Corrupt GIF"); + + version = get8u(s); + if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF"); + if (get8(s) != 'a') return e("not GIF", "Corrupt GIF"); + + failure_reason = ""; + g->w = get16le(s); + g->h = get16le(s); + g->flags = get8(s); + g->bgindex = get8(s); + g->ratio = get8(s); + g->transparent = -1; + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi_gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi_gif_info_raw(stbi *s, int *x, int *y, int *comp) +{ + stbi_gif g; + if (!stbi_gif_header(s, &g, comp, 1)) { + stbi_rewind( s ); + return 0; + } + if (x) *x = g.w; + if (y) *y = g.h; + return 1; +} + +static void stbi_out_gif_code(stbi_gif *g, uint16 code) +{ + uint8 *p, *c; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi_out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + p = &g->out[g->cur_x + g->cur_y]; + c = &g->color_table[g->codes[code].suffix * 4]; + + if (c[3] >= 128) { + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g) +{ + uint8 lzw_cs; + int32 len, code; + uint32 first; + int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi_gif_lzw *p; + + lzw_cs = get8u(s); + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (code = 0; code < clear; code++) { + g->codes[code].prefix = -1; + g->codes[code].first = (uint8) code; + g->codes[code].suffix = (uint8) code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (int32) get8(s) << valid_bits; + valid_bits += 8; + } else { + int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + skip(s, len); + while ((len = get8(s)) > 0) + skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) return epuc("no clear code", "Corrupt GIF"); + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 4096) return epuc("too many codes", "Corrupt GIF"); + p->prefix = (int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return epuc("illegal code in raster", "Corrupt GIF"); + + stbi_out_gif_code(g, (uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return epuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +static void stbi_fill_gif_background(stbi_gif *g) +{ + int i; + uint8 *c = g->pal[g->bgindex]; + // @OPTIMIZE: write a dword at a time + for (i = 0; i < g->w * g->h * 4; i += 4) { + uint8 *p = &g->out[i]; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +static uint8 *stbi_gif_load_next(stbi *s, stbi_gif *g, int *comp, int req_comp) +{ + int i; + uint8 *old_out = 0; + + if (g->out == 0) { + if (!stbi_gif_header(s, g, comp,0)) return 0; // failure_reason set by stbi_gif_header + g->out = (uint8 *) malloc(4 * g->w * g->h); + if (g->out == 0) return epuc("outofmem", "Out of memory"); + stbi_fill_gif_background(g); + } else { + // animated-gif-only path + if (((g->eflags & 0x1C) >> 2) == 3) { + old_out = g->out; + g->out = (uint8 *) malloc(4 * g->w * g->h); + if (g->out == 0) return epuc("outofmem", "Out of memory"); + memcpy(g->out, old_out, g->w*g->h*4); + } + } + + for (;;) { + switch (get8(s)) { + case 0x2C: /* Image Descriptor */ + { + int32 x, y, w, h; + uint8 *o; + + x = get16le(s); + y = get16le(s); + w = get16le(s); + h = get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return epuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + g->lflags = get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi_gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (uint8 *) g->lpal; + } else if (g->flags & 0x80) { + for (i=0; i < 256; ++i) // @OPTIMIZE: reset only the previous transparent + g->pal[i][3] = 255; + if (g->transparent >= 0 && (g->eflags & 0x01)) + g->pal[g->transparent][3] = 0; + g->color_table = (uint8 *) g->pal; + } else + return epuc("missing color table", "Corrupt GIF"); + + o = stbi_process_gif_raster(s, g); + if (o == NULL) return NULL; + + if (req_comp && req_comp != 4) + o = convert_format(o, 4, req_comp, g->w, g->h); + return o; + } + + case 0x21: // Comment Extension. + { + int len; + if (get8(s) == 0xF9) { // Graphic Control Extension. + len = get8(s); + if (len == 4) { + g->eflags = get8(s); + get16le(s); // delay + g->transparent = get8(s); + } else { + skip(s, len); + break; + } + } + while ((len = get8(s)) != 0) + skip(s, len); + break; + } + + case 0x3B: // gif stream termination code + return (uint8 *) 1; + + default: + return epuc("unknown code", "Corrupt GIF"); + } + } +} + +static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + uint8 *u = 0; + stbi_gif g={0}; + + u = stbi_gif_load_next(s, &g, comp, req_comp); + if (u == (void *) 1) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + } + + return u; +} + +static int stbi_gif_info(stbi *s, int *x, int *y, int *comp) +{ + return stbi_gif_info_raw(s,x,y,comp); +} + + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int hdr_test(stbi *s) +{ + const char *signature = "#?RADIANCE\n"; + int i; + for (i=0; signature[i]; ++i) + if (get8(s) != signature[i]) + return 0; + return 1; +} + +static int stbi_hdr_test(stbi* s) +{ + int r = hdr_test(s); + stbi_rewind(s); + return r; +} + +#define HDR_BUFLEN 1024 +static char *hdr_gettoken(stbi *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) get8(z); + + while (!at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == HDR_BUFLEN-1) { + // flush to end of line + while (!at_eof(z) && get8(z) != '\n') + ; + break; + } + c = (char) get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + char buffer[HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + + + // Check identifier + if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) + return epf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return epf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = strtol(token, NULL, 10); + + *x = width; + *y = height; + + *comp = 3; + if (req_comp == 0) req_comp = 3; + + // Read data + hdr_data = (float *) malloc(height * width * req_comp * sizeof(float)); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + getn(s, rgbe, 4); + hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = get8(s); + c2 = get8(s); + len = get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + uint8 rgbe[4]; + rgbe[0] = (uint8) c1; + rgbe[1] = (uint8) c2; + rgbe[2] = (uint8) len; + rgbe[3] = (uint8) get8u(s); + hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + free(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= get8(s); + if (len != width) { free(hdr_data); free(scanline); return epf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4); + + for (k = 0; k < 4; ++k) { + i = 0; + while (i < width) { + count = get8u(s); + if (count > 128) { + // Run + value = get8u(s); + count -= 128; + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = get8u(s); + } + } + } + for (i=0; i < width; ++i) + hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + free(scanline); + } + + return hdr_data; +} + +static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + return hdr_load(s,x,y,comp,req_comp); +} + +static int stbi_hdr_info(stbi *s, int *x, int *y, int *comp) +{ + char buffer[HDR_BUFLEN]; + char *token; + int valid = 0; + + if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) { + stbi_rewind( s ); + return 0; + } + + for(;;) { + token = hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi_rewind( s ); + return 0; + } + token = hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi_rewind( s ); + return 0; + } + token += 3; + *y = strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi_rewind( s ); + return 0; + } + token += 3; + *x = strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +static int stbi_bmp_info(stbi *s, int *x, int *y, int *comp) +{ + int hsz; + if (get8(s) != 'B' || get8(s) != 'M') { + stbi_rewind( s ); + return 0; + } + skip(s,12); + hsz = get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) { + stbi_rewind( s ); + return 0; + } + if (hsz == 12) { + *x = get16le(s); + *y = get16le(s); + } else { + *x = get32le(s); + *y = get32le(s); + } + if (get16le(s) != 1) { + stbi_rewind( s ); + return 0; + } + *comp = get16le(s) / 8; + return 1; +} + +static int stbi_psd_info(stbi *s, int *x, int *y, int *comp) +{ + int channelCount; + if (get32(s) != 0x38425053) { + stbi_rewind( s ); + return 0; + } + if (get16(s) != 1) { + stbi_rewind( s ); + return 0; + } + skip(s, 6); + channelCount = get16(s); + if (channelCount < 0 || channelCount > 16) { + stbi_rewind( s ); + return 0; + } + *y = get32(s); + *x = get32(s); + if (get16(s) != 8) { + stbi_rewind( s ); + return 0; + } + if (get16(s) != 3) { + stbi_rewind( s ); + return 0; + } + *comp = 4; + return 1; +} + +static int stbi_pic_info(stbi *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained; + pic_packet_t packets[10]; + + skip(s, 92); + + *x = get16(s); + *y = get16(s); + if (at_eof(s)) return 0; + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi_rewind( s ); + return 0; + } + + skip(s, 8); + + do { + pic_packet_t *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = get8(s); + packet->size = get8u(s); + packet->type = get8u(s); + packet->channel = get8u(s); + act_comp |= packet->channel; + + if (at_eof(s)) { + stbi_rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi_rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} + +static int stbi_info_main(stbi *s, int *x, int *y, int *comp) +{ + if (stbi_jpeg_info(s, x, y, comp)) + return 1; + if (stbi_png_info(s, x, y, comp)) + return 1; + if (stbi_gif_info(s, x, y, comp)) + return 1; + if (stbi_bmp_info(s, x, y, comp)) + return 1; + if (stbi_psd_info(s, x, y, comp)) + return 1; + if (stbi_pic_info(s, x, y, comp)) + return 1; + #ifndef STBI_NO_HDR + if (stbi_hdr_info(s, x, y, comp)) + return 1; + #endif + // test tga last because it's a crappy test! + if (stbi_tga_info(s, x, y, comp)) + return 1; + return e("unknown image type", "Image not of any known type, or corrupt"); +} + +#ifndef STBI_NO_STDIO +int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = fopen(filename, "rb"); + int result; + if (!f) return e("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi s; + long pos = ftell(f); + start_file(&s, f); + r = stbi_info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi s; + start_mem(&s,buffer,len); + return stbi_info_main(&s,x,y,comp); +} + +int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi s; + start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi_info_main(&s,x,y,comp); +} + +#endif // STBI_HEADER_FILE_ONLY + +/* + revision history: + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-uint8 to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.e. Janez (U+017D)emva) + 1.21 fix use of 'uint8' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 2008-08-02 + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi_bmp_load() and stbi_tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 first released version +*/ diff --git a/ext/native/ext/stb_image/stb_image.h b/ext/native/ext/stb_image/stb_image.h new file mode 100644 index 0000000000..675bb96285 --- /dev/null +++ b/ext/native/ext/stb_image/stb_image.h @@ -0,0 +1,262 @@ +#pragma once +//// begin header file //////////////////////////////////////////////////// +// +// Limitations: +// - no jpeg progressive support +// - non-HDR formats support 8-bit samples only (jpeg, png) +// - no delayed line count (jpeg) -- IJG doesn't support either +// - no 1-bit BMP +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *comp -- outputs # of image components in image file +// int req_comp -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. +// If req_comp is non-zero, *comp has the number of components that _would_ +// have been output otherwise. E.g. if you set req_comp to 4, you will always +// get RGBA output, but you can check *comp to easily see if it's opaque. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *comp will be unchanged. The function stbi_failure_reason() +// can be queried for an extremely brief, end-user unfriendly explanation +// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid +// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// =========================================================================== +// +// iPhone PNG support: +// +// By default we convert iphone-formatted PNGs back to RGB; nominally they +// would silently load as BGR, except the existing code should have just +// failed on such iPhone PNGs. But you can disable this conversion by +// by calling stbi_convert_iphone_png_to_rgb(0), in which case +// you will always just get the native iphone "format" through. +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image now supports loading HDR images in general, and currently +// the Radiance .HDR file format, although the support is provided +// generically. You can still load any file through the existing interface; +// if you attempt to load an HDR file, it will be automatically remapped to +// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). + + +#ifndef STBI_NO_STDIO + +#if defined(_MSC_VER) && _MSC_VER >= 0x1400 +#define _CRT_SECURE_NO_WARNINGS // suppress bogus warnings about fopen() +#endif + +#include +#endif + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for req_comp + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +typedef unsigned char stbi_uc; + +#ifdef __cplusplus +extern "C" { +#endif + + ////////////////////////////////////////////////////////////////////////////// + // + // PRIMARY API - works on images of any type + // + + // + // load image by filename, open file, or memory buffer + // + + extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_STDIO + extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); + extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + // for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + + typedef struct + { + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,unsigned n); // skip the next 'n' bytes + int (*eof) (void *user); // returns nonzero if we are at end of file/data + } stbi_io_callbacks; + + extern stbi_uc *stbi_load_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_HDR + extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_STDIO + extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); + extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + + extern float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + + extern void stbi_hdr_to_ldr_gamma(float gamma); + extern void stbi_hdr_to_ldr_scale(float scale); + + extern void stbi_ldr_to_hdr_gamma(float gamma); + extern void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_HDR + + // stbi_is_hdr is always defined + extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); + extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO + extern int stbi_is_hdr (char const *filename); + extern int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + + // get a VERY brief reason for failure + // NOT THREADSAFE + extern const char *stbi_failure_reason (void); + + // free the loaded image -- this is just free() + extern void stbi_image_free (void *retval_from_stbi_load); + + // get image dimensions & components without fully decoding + extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); + extern int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO + extern int stbi_info (char const *filename, int *x, int *y, int *comp); + extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); + +#endif + + + + // for image formats that explicitly notate that they have premultiplied alpha, + // we just return the colors as stored in the file. set this flag to force + // unpremultiplication. results are undefined if the unpremultiply overflow. + extern void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + + // indicate whether we should process iphone images back to canonical format, + // or just pass them through "as-is" + extern void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + + + // ZLIB client - used by PNG, available for other purposes + + extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); + extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); + extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); + extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + + // define faster low-level operations (typically SIMD support) +#ifdef STBI_SIMD + typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize); + // compute an integer IDCT on "input" + // input[x] = data[x] * dequantize[x] + // write results to 'out': 64 samples, each run of 8 spaced by 'out_stride' + // CLAMP results to 0..255 + typedef void (*stbi_YCbCr_to_RGB_run)(stbi_uc *output, stbi_uc const *y, stbi_uc const *cb, stbi_uc const *cr, int count, int step); + // compute a conversion from YCbCr to RGB + // 'count' pixels + // write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B + // y: Y input channel + // cb: Cb input channel; scale/biased to be 0..255 + // cr: Cr input channel; scale/biased to be 0..255 + + extern void stbi_install_idct(stbi_idct_8x8 func); + extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func); +#endif // STBI_SIMD + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// diff --git a/ext/native/ext/stb_image_write/stb_image_write.c b/ext/native/ext/stb_image_write/stb_image_write.c new file mode 100644 index 0000000000..cbbabf0d3b --- /dev/null +++ b/ext/native/ext/stb_image_write/stb_image_write.c @@ -0,0 +1,2 @@ +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "ext/stb_image_write/stb_image_writer.h" \ No newline at end of file diff --git a/ext/native/ext/stb_image_write/stb_image_writer.h b/ext/native/ext/stb_image_write/stb_image_writer.h new file mode 100644 index 0000000000..b7c4f490b2 --- /dev/null +++ b/ext/native/ext/stb_image_write/stb_image_writer.h @@ -0,0 +1,511 @@ +/* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h + writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010 + no warranty implied; use at your own risk + + +Before including, + + #define STB_IMAGE_WRITE_IMPLEMENTATION + +in the file that you want to have the implementation. + + +ABOUT: + + This header file is a library for writing images to C stdio. It could be + adapted to write to memory or a general streaming interface; let me know. + + The PNG output is not optimal; it is 20-50% larger than the file + written by a decent optimizing implementation. This library is designed + for source code compactness and simplicitly, not optimal image file size + or run-time performance. + +USAGE: + + There are three functions, one for each image file format: + + int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + + Each function returns 0 on failure and non-0 on success. + + The functions create an image file defined by the parameters. The image + is a rectangle of pixels stored from left-to-right, top-to-bottom. + Each pixel contains 'comp' channels of data stored interleaved with 8-bits + per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is + monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. + The *data pointer points to the first byte of the top-left-most pixel. + For PNG, "stride_in_bytes" is the distance in bytes from the first byte of + a row of pixels to the first byte of the next row of pixels. + + PNG creates output files with the same number of components as the input. + The BMP and TGA formats expand Y to RGB in the file format. BMP does not + output alpha. + + PNG supports writing rectangles of data even when the bytes storing rows of + data are not consecutive in memory (e.g. sub-rectangles of a larger image), + by supplying the stride between the beginning of adjacent rows. The other + formats do not. (Thus you cannot write a native-format BMP through the BMP + writer, both because it is in BGR order and because it may have padding + at the end of the line.) +*/ + +#ifndef INCLUDE_STB_IMAGE_WRITE_H +#define INCLUDE_STB_IMAGE_WRITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); +extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); +extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + +#ifdef __cplusplus +} +#endif + +#endif//INCLUDE_STB_IMAGE_WRITE_H + +#ifdef STB_IMAGE_WRITE_IMPLEMENTATION + +#include +#include +#include +#include +#include + +typedef unsigned int stbiw_uint32; +typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; + +static void writefv(FILE *f, const char *fmt, va_list v) +{ + while (*fmt) { + switch (*fmt++) { + case ' ': break; + case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; } + case '2': { int x = va_arg(v,int); unsigned char b[2]; + b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8); + fwrite(b,2,1,f); break; } + case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4]; + b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8); + b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24); + fwrite(b,4,1,f); break; } + default: + assert(0); + return; + } + } +} + +static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c) +{ + unsigned char arr[3]; + arr[0] = a, arr[1] = b, arr[2] = c; + fwrite(arr, 3, 1, f); +} + +static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad) +{ + unsigned char bg[3] = { 255, 0, 255}, px[3]; + stbiw_uint32 zero = 0; + int i,j,k, j_end; + + if (y <= 0) + return; + + if (vdir < 0) + j_end = -1, j = y-1; + else + j_end = y, j = 0; + + for (; j != j_end; j += vdir) { + for (i=0; i < x; ++i) { + unsigned char *d = (unsigned char *) data + (j*x+i)*comp; + if (write_alpha < 0) + fwrite(&d[comp-1], 1, 1, f); + switch (comp) { + case 1: + case 2: write3(f, d[0],d[0],d[0]); + break; + case 4: + if (!write_alpha) { + // composite against pink background + for (k=0; k < 3; ++k) + px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255; + write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]); + break; + } + /* FALLTHROUGH */ + case 3: + write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]); + break; + } + if (write_alpha > 0) + fwrite(&d[comp-1], 1, 1, f); + } + fwrite(&zero,scanline_pad,1,f); + } +} + +static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...) +{ + FILE *f; + if (y < 0 || x < 0) return 0; + f = fopen(filename, "wb"); + if (f) { + va_list v; + va_start(v, fmt); + writefv(f, fmt, v); + va_end(v); + write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad); + fclose(f); + } + return f != NULL; +} + +int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) +{ + int pad = (-x*3) & 3; + return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad, + "11 4 22 4" "4 44 22 444444", + 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header + 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header +} + +int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) +{ + int has_alpha = !(comp & 1); + return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0, + "111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha); +} + +// stretchy buffer; stbi__sbpush() == vector<>::push_back() -- stbi__sbcount() == vector<>::size() +#define stbi__sbraw(a) ((int *) (a) - 2) +#define stbi__sbm(a) stbi__sbraw(a)[0] +#define stbi__sbn(a) stbi__sbraw(a)[1] + +#define stbi__sbneedgrow(a,n) ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a)) +#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0) +#define stbi__sbgrow(a,n) stbi__sbgrowf((void **) &(a), (n), sizeof(*(a))) + +#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v)) +#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0) +#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)),0 : 0) + +static void *stbi__sbgrowf(void **arr, int increment, int itemsize) +{ + int m = *arr ? 2*stbi__sbm(*arr)+increment : increment+1; + void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2); + assert(p); + if (p) { + if (!*arr) ((int *) p)[1] = 0; + *arr = (void *) ((int *) p + 2); + stbi__sbm(*arr) = m; + } + return *arr; +} + +static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) +{ + while (*bitcount >= 8) { + stbi__sbpush(data, (unsigned char) *bitbuffer); + *bitbuffer >>= 8; + *bitcount -= 8; + } + return data; +} + +static int stbi__zlib_bitrev(int code, int codebits) +{ + int res=0; + while (codebits--) { + res = (res << 1) | (code & 1); + code >>= 1; + } + return res; +} + +static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int limit) +{ + int i; + for (i=0; i < limit && i < 258; ++i) + if (a[i] != b[i]) break; + return i; +} + +static unsigned int stbi__zhash(unsigned char *data) +{ + stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return hash; +} + +#define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount)) +#define stbi__zlib_add(code,codebits) \ + (bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush()) +#define stbi__zlib_huffa(b,c) stbi__zlib_add(stbi__zlib_bitrev(b,c),c) +// default huffman tables +#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8) +#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9) +#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256,7) +#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280,8) +#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n)) +#define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n)) + +#define stbi__ZHASH 16384 + +unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +{ + static unsigned short lengthc[] = { 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, 259 }; + static unsigned char lengtheb[]= { 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 }; + static unsigned short distc[] = { 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, 32768 }; + static unsigned char disteb[] = { 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 }; + unsigned int bitbuf=0; + int i,j, bitcount=0; + unsigned char *out = NULL; + unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack! + if (quality < 5) quality = 5; + + stbi__sbpush(out, 0x78); // DEFLATE 32K window + stbi__sbpush(out, 0x5e); // FLEVEL = 1 + stbi__zlib_add(1,1); // BFINAL = 1 + stbi__zlib_add(1,2); // BTYPE = 1 -- fixed huffman + + for (i=0; i < stbi__ZHASH; ++i) + hash_table[i] = NULL; + + i=0; + while (i < data_len-3) { + // hash next 3 bytes of data to be compressed + int h = stbi__zhash(data+i)&(stbi__ZHASH-1), best=3; + unsigned char *bestloc = 0; + unsigned char **hlist = hash_table[h]; + int n = stbi__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32768) { // if entry lies within window + int d = stbi__zlib_countm(hlist[j], data+i, data_len-i); + if (d >= best) best=d,bestloc=hlist[j]; + } + } + // when hash table entry is too long, delete half the entries + if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) { + memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); + stbi__sbn(hash_table[h]) = quality; + } + stbi__sbpush(hash_table[h],data+i); + + if (bestloc) { + // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal + h = stbi__zhash(data+i+1)&(stbi__ZHASH-1); + hlist = hash_table[h]; + n = stbi__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32767) { + int e = stbi__zlib_countm(hlist[j], data+i+1, data_len-i-1); + if (e > best) { // if next match is better, bail on current match + bestloc = NULL; + break; + } + } + } + } + + if (bestloc) { + int d = data+i - bestloc; // distance back + assert(d <= 32767 && best <= 258); + for (j=0; best > lengthc[j+1]-1; ++j); + stbi__zlib_huff(j+257); + if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]); + for (j=0; d > distc[j+1]-1; ++j); + stbi__zlib_add(stbi__zlib_bitrev(j,5),5); + if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]); + i += best; + } else { + stbi__zlib_huffb(data[i]); + ++i; + } + } + // write out final bytes + for (;i < data_len; ++i) + stbi__zlib_huffb(data[i]); + stbi__zlib_huff(256); // end of block + // pad with 0 bits to byte boundary + while (bitcount) + stbi__zlib_add(0,1); + + for (i=0; i < stbi__ZHASH; ++i) + (void) stbi__sbfree(hash_table[i]); + + { + // compute adler32 on input + unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552; + int j=0; + while (j < data_len) { + for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1; + s1 %= 65521, s2 %= 65521; + j += blocklen; + blocklen = 5552; + } + stbi__sbpush(out, (unsigned char) (s2 >> 8)); + stbi__sbpush(out, (unsigned char) s2); + stbi__sbpush(out, (unsigned char) (s1 >> 8)); + stbi__sbpush(out, (unsigned char) s1); + } + *out_len = stbi__sbn(out); + // make returned pointer freeable + memmove(stbi__sbraw(out), out, *out_len); + return (unsigned char *) stbi__sbraw(out); +} + +unsigned int stbi__crc32(unsigned char *buffer, int len) +{ + static unsigned int crc_table[256]; + unsigned int crc = ~0u; + int i,j; + if (crc_table[1] == 0) + for(i=0; i < 256; i++) + for (crc_table[i]=i, j=0; j < 8; ++j) + crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0); + for (i=0; i < len; ++i) + crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; + return ~crc; +} + +#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4) +#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); +#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3]) + +static void stbi__wpcrc(unsigned char **data, int len) +{ + unsigned int crc = stbi__crc32(*data - len - 4, len+4); + stbi__wp32(*data, crc); +} + +static unsigned char stbi__paeth(int a, int b, int c) +{ + int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); + if (pa <= pb && pa <= pc) return (unsigned char) a; + if (pb <= pc) return (unsigned char) b; + return (unsigned char) c; +} + +unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +{ + int ctype[5] = { -1, 0, 4, 2, 6 }; + unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; + unsigned char *out,*o, *filt, *zlib; + signed char *line_buffer; + int i,j,k,p,zlen; + + if (stride_bytes == 0) + stride_bytes = x * n; + + filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0; + line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; } + for (j=0; j < y; ++j) { + static int mapping[] = { 0,1,2,3,4 }; + static int firstmap[] = { 0,1,0,5,6 }; + int *mymap = j ? mapping : firstmap; + int best = 0, bestval = 0x7fffffff; + for (p=0; p < 2; ++p) { + for (k= p?best:0; k < 5; ++k) { + int type = mymap[k],est=0; + unsigned char *z = pixels + stride_bytes*j; + for (i=0; i < n; ++i) + switch (type) { + case 0: line_buffer[i] = z[i]; break; + case 1: line_buffer[i] = z[i]; break; + case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; + case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break; + case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break; + case 5: line_buffer[i] = z[i]; break; + case 6: line_buffer[i] = z[i]; break; + } + for (i=n; i < x*n; ++i) { + switch (type) { + case 0: line_buffer[i] = z[i]; break; + case 1: line_buffer[i] = z[i] - z[i-n]; break; + case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; + case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break; + case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break; + case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break; + case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break; + } + } + if (p) break; + for (i=0; i < x*n; ++i) + est += abs((signed char) line_buffer[i]); + if (est < bestval) { bestval = est; best = k; } + } + } + // when we get here, best contains the filter type, and line_buffer contains the data + filt[j*(x*n+1)] = (unsigned char) best; + memcpy(filt+j*(x*n+1)+1, line_buffer, x*n); + } + free(line_buffer); + zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory + free(filt); + if (!zlib) return 0; + + // each tag requires 12 bytes of overhead + out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12); + if (!out) return 0; + *out_len = 8 + 12+13 + 12+zlen + 12; + + o=out; + memcpy(o,sig,8); o+= 8; + stbi__wp32(o, 13); // header length + stbi__wptag(o, "IHDR"); + stbi__wp32(o, x); + stbi__wp32(o, y); + *o++ = 8; + *o++ = (unsigned char) ctype[n]; + *o++ = 0; + *o++ = 0; + *o++ = 0; + stbi__wpcrc(&o,13); + + stbi__wp32(o, zlen); + stbi__wptag(o, "IDAT"); + memcpy(o, zlib, zlen); o += zlen; free(zlib); + stbi__wpcrc(&o, zlen); + + stbi__wp32(o,0); + stbi__wptag(o, "IEND"); + stbi__wpcrc(&o,0); + + assert(o == out + *out_len); + + return out; +} + +int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) +{ + FILE *f; + int len; + unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); + if (!png) return 0; + f = fopen(filename, "wb"); + if (!f) { free(png); return 0; } + fwrite(png, 1, len, f); + fclose(f); + free(png); + return 1; +} +#endif // STB_IMAGE_WRITE_IMPLEMENTATION + +/* Revision history + + 0.92 (2010-08-01) + casts to unsigned char to fix warnings + 0.91 (2010-07-17) + first public release + 0.90 first internal release +*/ \ No newline at end of file diff --git a/ext/native/ext/stb_vorbis/CMakeLists.txt b/ext/native/ext/stb_vorbis/CMakeLists.txt new file mode 100644 index 0000000000..27561cc163 --- /dev/null +++ b/ext/native/ext/stb_vorbis/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 2.6) + +#if(UNIX) +add_definitions(-fPIC) +add_definitions(-g) +add_definitions(-O2) +add_definitions(-Wall) +#endif(UNIX) + +add_library(stb_vorbis stb_vorbis.c) diff --git a/ext/native/ext/stb_vorbis/stb_vorbis.c b/ext/native/ext/stb_vorbis/stb_vorbis.c new file mode 100644 index 0000000000..44c64fde8a --- /dev/null +++ b/ext/native/ext/stb_vorbis/stb_vorbis.c @@ -0,0 +1,5024 @@ +// Ogg Vorbis I audio decoder -- version 0.99996 +// +// Written in April 2007 by Sean Barrett, sponsored by RAD Game Tools. +// +// Placed in the public domain April 2007 by the author: no copyright is +// claimed, and you may use it for any purpose you like. +// +// No warranty for any purpose is expressed or implied by the author (nor +// by RAD Game Tools). Report bugs and send enhancements to the author. +// +// Get the latest version and other information at: +// http://nothings.org/stb_vorbis/ + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#pragma warning (disable:4244) +#include +#elif !defined(__SYMBIAN32__) && !defined(__Bitrig__) && !defined(__DragonFly__) && \ + !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) +#include +#endif + +// Todo: +// +// - seeking (note you can seek yourself using the pushdata API) +// +// Limitations: +// +// - floor 0 not supported (used in old ogg vorbis files) +// - lossless sample-truncation at beginning ignored +// - cannot concatenate multiple vorbis streams +// - sample positions are 32-bit, limiting seekable 192Khz +// files to around 6 hours (Ogg supports 64-bit) +// +// All of these limitations may be removed in future versions. + +#include "stb_vorbis.h" + + +#ifndef STB_VORBIS_HEADER_ONLY + +// global configuration settings (e.g. set these in the project/makefile), +// or just set them in this file at the top (although ideally the first few +// should be visible when the header file is compiled too, although it's not +// crucial) + +// STB_VORBIS_NO_PUSHDATA_API +// does not compile the code for the various stb_vorbis_*_pushdata() +// functions +// #define STB_VORBIS_NO_PUSHDATA_API + +// STB_VORBIS_NO_PULLDATA_API +// does not compile the code for the non-pushdata APIs +// #define STB_VORBIS_NO_PULLDATA_API + +// STB_VORBIS_NO_STDIO +// does not compile the code for the APIs that use FILE *s internally +// or externally (implied by STB_VORBIS_NO_PULLDATA_API) +#define STB_VORBIS_NO_STDIO + +// STB_VORBIS_NO_INTEGER_CONVERSION +// does not compile the code for converting audio sample data from +// float to integer (implied by STB_VORBIS_NO_PULLDATA_API) +// #define STB_VORBIS_NO_INTEGER_CONVERSION + +// STB_VORBIS_NO_FAST_SCALED_FLOAT +// does not use a fast float-to-int trick to accelerate float-to-int on +// most platforms which requires endianness be defined correctly. +//#define STB_VORBIS_NO_FAST_SCALED_FLOAT + + +// STB_VORBIS_MAX_CHANNELS [number] +// globally define this to the maximum number of channels you need. +// The spec does not put a restriction on channels except that +// the count is stored in a byte, so 255 is the hard limit. +// Reducing this saves about 16 bytes per value, so using 16 saves +// (255-16)*16 or around 4KB. Plus anything other memory usage +// I forgot to account for. Can probably go as low as 8 (7.1 audio), +// 6 (5.1 audio), or 2 (stereo only). +#ifndef STB_VORBIS_MAX_CHANNELS +#define STB_VORBIS_MAX_CHANNELS 16 // enough for anyone? +#endif + +// STB_VORBIS_PUSHDATA_CRC_COUNT [number] +// after a flush_pushdata(), stb_vorbis begins scanning for the +// next valid page, without backtracking. when it finds something +// that looks like a page, it streams through it and verifies its +// CRC32. Should that validation fail, it keeps scanning. But it's +// possible that _while_ streaming through to check the CRC32 of +// one candidate page, it sees another candidate page. This #define +// determines how many "overlapping" candidate pages it can search +// at once. Note that "real" pages are typically ~4KB to ~8KB, whereas +// garbage pages could be as big as 64KB, but probably average ~16KB. +// So don't hose ourselves by scanning an apparent 64KB page and +// missing a ton of real ones in the interim; so minimum of 2 +#ifndef STB_VORBIS_PUSHDATA_CRC_COUNT +#define STB_VORBIS_PUSHDATA_CRC_COUNT 4 +#endif + +// STB_VORBIS_FAST_HUFFMAN_LENGTH [number] +// sets the log size of the huffman-acceleration table. Maximum +// supported value is 24. with larger numbers, more decodings are O(1), +// but the table size is larger so worse cache missing, so you'll have +// to probe (and try multiple ogg vorbis files) to find the sweet spot. +#ifndef STB_VORBIS_FAST_HUFFMAN_LENGTH +#define STB_VORBIS_FAST_HUFFMAN_LENGTH 10 +#endif + +// STB_VORBIS_FAST_BINARY_LENGTH [number] +// sets the log size of the binary-search acceleration table. this +// is used in similar fashion to the fast-huffman size to set initial +// parameters for the binary search + +// STB_VORBIS_FAST_HUFFMAN_INT +// The fast huffman tables are much more efficient if they can be +// stored as 16-bit results instead of 32-bit results. This restricts +// the codebooks to having only 65535 possible outcomes, though. +// (At least, accelerated by the huffman table.) +#ifndef STB_VORBIS_FAST_HUFFMAN_INT +#define STB_VORBIS_FAST_HUFFMAN_SHORT +#endif + +// STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH +// If the 'fast huffman' search doesn't succeed, then stb_vorbis falls +// back on binary searching for the correct one. This requires storing +// extra tables with the huffman codes in sorted order. Defining this +// symbol trades off space for speed by forcing a linear search in the +// non-fast case, except for "sparse" codebooks. +// #define STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH + +// STB_VORBIS_DIVIDES_IN_RESIDUE +// stb_vorbis precomputes the result of the scalar residue decoding +// that would otherwise require a divide per chunk. you can trade off +// space for time by defining this symbol. +// #define STB_VORBIS_DIVIDES_IN_RESIDUE + +// STB_VORBIS_DIVIDES_IN_CODEBOOK +// vorbis VQ codebooks can be encoded two ways: with every case explicitly +// stored, or with all elements being chosen from a small range of values, +// and all values possible in all elements. By default, stb_vorbis expands +// this latter kind out to look like the former kind for ease of decoding, +// because otherwise an integer divide-per-vector-element is required to +// unpack the index. If you define STB_VORBIS_DIVIDES_IN_CODEBOOK, you can +// trade off storage for speed. +//#define STB_VORBIS_DIVIDES_IN_CODEBOOK + +// STB_VORBIS_CODEBOOK_SHORTS +// The vorbis file format encodes VQ codebook floats as ax+b where a and +// b are floating point per-codebook constants, and x is a 16-bit int. +// Normally, stb_vorbis decodes them to floats rather than leaving them +// as 16-bit ints and computing ax+b while decoding. This is a speed/space +// tradeoff; you can save space by defining this flag. +#ifndef STB_VORBIS_CODEBOOK_SHORTS +#define STB_VORBIS_CODEBOOK_FLOATS +#endif + +// STB_VORBIS_DIVIDE_TABLE +// this replaces small integer divides in the floor decode loop with +// table lookups. made less than 1% difference, so disabled by default. + +// STB_VORBIS_NO_INLINE_DECODE +// disables the inlining of the scalar codebook fast-huffman decode. +// might save a little codespace; useful for debugging +// #define STB_VORBIS_NO_INLINE_DECODE + +// STB_VORBIS_NO_DEFER_FLOOR +// Normally we only decode the floor without synthesizing the actual +// full curve. We can instead synthesize the curve immediately. This +// requires more memory and is very likely slower, so I don't think +// you'd ever want to do it except for debugging. +// #define STB_VORBIS_NO_DEFER_FLOOR + + + + +////////////////////////////////////////////////////////////////////////////// + +#ifdef STB_VORBIS_NO_PULLDATA_API + #define STB_VORBIS_NO_INTEGER_CONVERSION + #define STB_VORBIS_NO_STDIO +#endif + +#if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO) + #define STB_VORBIS_NO_STDIO 1 +#endif + +#ifndef STB_VORBIS_NO_INTEGER_CONVERSION +#ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT + + // only need endianness for fast-float-to-int, which we don't + // use for pushdata + + #ifndef STB_VORBIS_BIG_ENDIAN + #define STB_VORBIS_ENDIAN 0 + #else + #define STB_VORBIS_ENDIAN 1 + #endif + +#endif +#endif + + +#ifndef STB_VORBIS_NO_STDIO +#include +#endif + +#ifndef STB_VORBIS_NO_CRT +#include +#include +#include +#include +#else +#define NULL 0 +#endif + +#ifndef _MSC_VER + #if __GNUC__ + #define __forceinline inline + #else + #define __forceinline + #endif +#endif + +#if STB_VORBIS_MAX_CHANNELS > 256 +#error "Value of STB_VORBIS_MAX_CHANNELS outside of allowed range" +#endif + +#if STB_VORBIS_FAST_HUFFMAN_LENGTH > 24 +#error "Value of STB_VORBIS_FAST_HUFFMAN_LENGTH outside of allowed range" +#endif + + +#define MAX_BLOCKSIZE_LOG 13 // from specification +#define MAX_BLOCKSIZE (1 << MAX_BLOCKSIZE_LOG) + + +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifdef STB_VORBIS_CODEBOOK_FLOATS +typedef float codetype; +#else +typedef uint16 codetype; +#endif + +// @NOTE +// +// Some arrays below are tagged "//varies", which means it's actually +// a variable-sized piece of data, but rather than malloc I assume it's +// small enough it's better to just allocate it all together with the +// main thing +// +// Most of the variables are specified with the smallest size I could pack +// them into. It might give better performance to make them all full-sized +// integers. It should be safe to freely rearrange the structures or change +// the sizes larger--nothing relies on silently truncating etc., nor the +// order of variables. + +#define FAST_HUFFMAN_TABLE_SIZE (1 << STB_VORBIS_FAST_HUFFMAN_LENGTH) +#define FAST_HUFFMAN_TABLE_MASK (FAST_HUFFMAN_TABLE_SIZE - 1) + +typedef struct +{ + int dimensions, entries; + uint8 *codeword_lengths; + float minimum_value; + float delta_value; + uint8 value_bits; + uint8 lookup_type; + uint8 sequence_p; + uint8 sparse; + uint32 lookup_values; + codetype *multiplicands; + uint32 *codewords; + #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT + int16 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; + #else + int32 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; + #endif + uint32 *sorted_codewords; + int *sorted_values; + int sorted_entries; +} Codebook; + +typedef struct +{ + uint8 order; + uint16 rate; + uint16 bark_map_size; + uint8 amplitude_bits; + uint8 amplitude_offset; + uint8 number_of_books; + uint8 book_list[16]; // varies +} Floor0; + +typedef struct +{ + uint8 partitions; + uint8 partition_class_list[32]; // varies + uint8 class_dimensions[16]; // varies + uint8 class_subclasses[16]; // varies + uint8 class_masterbooks[16]; // varies + int16 subclass_books[16][8]; // varies + uint16 Xlist[31*8+2]; // varies + uint8 sorted_order[31*8+2]; + uint8 neighbors[31*8+2][2]; + uint8 floor1_multiplier; + uint8 rangebits; + int values; +} Floor1; + +typedef union +{ + Floor0 floor0; + Floor1 floor1; +} Floor; + +typedef struct +{ + uint32 begin, end; + uint32 part_size; + uint8 classifications; + uint8 classbook; + uint8 **classdata; + int16 (*residue_books)[8]; +} Residue; + +typedef struct +{ + uint8 magnitude; + uint8 angle; + uint8 mux; +} MappingChannel; + +typedef struct +{ + uint16 coupling_steps; + MappingChannel *chan; + uint8 submaps; + uint8 submap_floor[15]; // varies + uint8 submap_residue[15]; // varies +} Mapping; + +typedef struct +{ + uint8 blockflag; + uint8 mapping; + uint16 windowtype; + uint16 transformtype; +} Mode; + +typedef struct +{ + uint32 goal_crc; // expected crc if match + int bytes_left; // bytes left in packet + uint32 crc_so_far; // running crc + int bytes_done; // bytes processed in _current_ chunk + uint32 sample_loc; // granule pos encoded in page +} CRCscan; + +typedef struct +{ + uint32 page_start, page_end; + uint32 after_previous_page_start; + uint32 first_decoded_sample; + uint32 last_decoded_sample; +} ProbedPage; + +struct stb_vorbis +{ + // user-accessible info + unsigned int sample_rate; + int channels; + + unsigned int setup_memory_required; + unsigned int temp_memory_required; + unsigned int setup_temp_memory_required; + + // input config +#ifndef STB_VORBIS_NO_STDIO + FILE *f; + uint32 f_start; + int close_on_free; +#endif + + uint8 *stream; + uint8 *stream_start; + uint8 *stream_end; + + uint32 stream_len; + + uint8 push_mode; + + uint32 first_audio_page_offset; + + ProbedPage p_first, p_last; + + // memory management + stb_vorbis_alloc alloc; + int setup_offset; + int temp_offset; + + // run-time results + int eof; + enum STBVorbisError error; + + // user-useful data + + // header info + int blocksize[2]; + int blocksize_0, blocksize_1; + int codebook_count; + Codebook *codebooks; + int floor_count; + uint16 floor_types[64]; // varies + Floor *floor_config; + int residue_count; + uint16 residue_types[64]; // varies + Residue *residue_config; + int mapping_count; + Mapping *mapping; + int mode_count; + Mode mode_config[64]; // varies + + uint32 total_samples; + + // decode buffer + float *channel_buffers[STB_VORBIS_MAX_CHANNELS]; + float *outputs [STB_VORBIS_MAX_CHANNELS]; + + float *previous_window[STB_VORBIS_MAX_CHANNELS]; + int previous_length; + + #ifndef STB_VORBIS_NO_DEFER_FLOOR + int16 *finalY[STB_VORBIS_MAX_CHANNELS]; + #else + float *floor_buffers[STB_VORBIS_MAX_CHANNELS]; + #endif + + uint32 current_loc; // sample location of next frame to decode + int current_loc_valid; + + // per-blocksize precomputed data + + // twiddle factors + float *A[2],*B[2],*C[2]; + float *window[2]; + uint16 *bit_reverse[2]; + + // current page/packet/segment streaming info + uint32 serial; // stream serial number for verification + int last_page; + int segment_count; + uint8 segments[255]; + uint8 page_flag; + uint8 bytes_in_seg; + uint8 first_decode; + int next_seg; + int last_seg; // flag that we're on the last segment + int last_seg_which; // what was the segment number of the last seg? + uint32 acc; + int valid_bits; + int packet_bytes; + int end_seg_with_known_loc; + uint32 known_loc_for_packet; + int discard_samples_deferred; + uint32 samples_output; + + // push mode scanning + int page_crc_tests; // only in push_mode: number of tests active; -1 if not searching +#ifndef STB_VORBIS_NO_PUSHDATA_API + CRCscan scan[STB_VORBIS_PUSHDATA_CRC_COUNT]; +#endif + + // sample-access + int channel_buffer_start; + int channel_buffer_end; +}; + +extern int my_prof(int slot); +//#define stb_prof my_prof + +#ifndef stb_prof +#define stb_prof(x) {} +#endif + +#if defined(STB_VORBIS_NO_PUSHDATA_API) + #define IS_PUSH_MODE(f) FALSE +#elif defined(STB_VORBIS_NO_PULLDATA_API) + #define IS_PUSH_MODE(f) TRUE +#else + #define IS_PUSH_MODE(f) ((f)->push_mode) +#endif + +typedef struct stb_vorbis vorb; + +static int error(vorb *f, enum STBVorbisError e) +{ + f->error = e; + if (!f->eof && e != VORBIS_need_more_data) { + f->error=e; // breakpoint for debugging + } + return 0; +} + + +// these functions are used for allocating temporary memory +// while decoding. if you can afford the stack space, use +// alloca(); otherwise, provide a temp buffer and it will +// allocate out of those. + +#define array_size_required(count,size) (count*(sizeof(void *)+(size))) + +#define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : alloca(size)) +#ifdef dealloca +#define temp_free(f,p) (f->alloc.alloc_buffer ? 0 : dealloca(size)) +#else +#define temp_free(f,p) 0 +#endif +#define temp_alloc_save(f) ((f)->temp_offset) +#define temp_alloc_restore(f,p) ((f)->temp_offset = (p)) + +#define temp_block_array(f,count,size) make_block_array(temp_alloc(f,array_size_required(count,size)), count, size) + +// given a sufficiently large block of memory, make an array of pointers to subblocks of it +static void *make_block_array(void *mem, int count, int size) +{ + int i; + void ** p = (void **) mem; + char *q = (char *) (p + count); + for (i=0; i < count; ++i) { + p[i] = q; + q += size; + } + return p; +} + +static void *setup_malloc(vorb *f, int sz) +{ + sz = (sz+3) & ~3; + f->setup_memory_required += sz; + if (f->alloc.alloc_buffer) { + void *p = (char *) f->alloc.alloc_buffer + f->setup_offset; + if (f->setup_offset + sz > f->temp_offset) return NULL; + f->setup_offset += sz; + return p; + } + return sz ? malloc(sz) : NULL; +} + +static void setup_free(vorb *f, void *p) +{ + if (f->alloc.alloc_buffer) return; // do nothing; setup mem is not a stack + free(p); +} + +static void *setup_temp_malloc(vorb *f, int sz) +{ + sz = (sz+3) & ~3; + if (f->alloc.alloc_buffer) { + if (f->temp_offset - sz < f->setup_offset) return NULL; + f->temp_offset -= sz; + return (char *) f->alloc.alloc_buffer + f->temp_offset; + } + return malloc(sz); +} + +static void setup_temp_free(vorb *f, void *p, size_t sz) +{ + if (f->alloc.alloc_buffer) { + f->temp_offset += (sz+3)&~3; + return; + } + free(p); +} + +#define CRC32_POLY 0x04c11db7 // from spec + +static uint32 crc_table[256]; +static void crc32_init(void) +{ + int i,j; + uint32 s; + for(i=0; i < 256; i++) { + for (s=i<<24, j=0; j < 8; ++j) + s = (s << 1) ^ (s >= (1<<31) ? CRC32_POLY : 0); + crc_table[i] = s; + } +} + +static __forceinline uint32 crc32_update(uint32 crc, uint8 byte) +{ + return (crc << 8) ^ crc_table[byte ^ (crc >> 24)]; +} + + +// used in setup, and for huffman that doesn't go fast path +static unsigned int bit_reverse(unsigned int n) +{ + n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1); + n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2); + n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4); + n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8); + return (n >> 16) | (n << 16); +} + +static float square(float x) +{ + return x*x; +} + +// this is a weird definition of log2() for which log2(1) = 1, log2(2) = 2, log2(4) = 3 +// as required by the specification. fast(?) implementation from stb.h +// @OPTIMIZE: called multiple times per-packet with "constants"; move to setup +static int ilog(int32 n) +{ + static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 }; + + // 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29) + if (n < (1U << 14)) + if (n < (1U << 4)) return 0 + log2_4[n ]; + else if (n < (1U << 9)) return 5 + log2_4[n >> 5]; + else return 10 + log2_4[n >> 10]; + else if (n < (1U << 24)) + if (n < (1U << 19)) return 15 + log2_4[n >> 15]; + else return 20 + log2_4[n >> 20]; + else if (n < (1U << 29)) return 25 + log2_4[n >> 25]; + else if (n < (1U << 31)) return 30 + log2_4[n >> 30]; + else return 0; // signed n returns 0 +} + +#ifndef M_PI + #define M_PI 3.14159265358979323846264f // from CRC +#endif + +// code length assigned to a value with no huffman encoding +#define NO_CODE 255 + +/////////////////////// LEAF SETUP FUNCTIONS ////////////////////////// +// +// these functions are only called at setup, and only a few times +// per file + +static float float32_unpack(uint32 x) +{ + // from the specification + uint32 mantissa = x & 0x1fffff; + uint32 sign = x & 0x80000000; + uint32 exp = (x & 0x7fe00000) >> 21; + double res = sign ? -(double)mantissa : (double)mantissa; + return (float) ldexp((float)res, exp-788); +} + + +// zlib & jpeg huffman tables assume that the output symbols +// can either be arbitrarily arranged, or have monotonically +// increasing frequencies--they rely on the lengths being sorted; +// this makes for a very simple generation algorithm. +// vorbis allows a huffman table with non-sorted lengths. This +// requires a more sophisticated construction, since symbols in +// order do not map to huffman codes "in order". +static void add_entry(Codebook *c, uint32 huff_code, int symbol, int count, int len, uint32 *values) +{ + if (!c->sparse) { + c->codewords [symbol] = huff_code; + } else { + c->codewords [count] = huff_code; + c->codeword_lengths[count] = len; + values [count] = symbol; + } +} + +static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) +{ + int i,k,m=0; + uint32 available[32]; + + memset(available, 0, sizeof(available)); + // find the first entry + for (k=0; k < n; ++k) if (len[k] < NO_CODE) break; + if (k == n) { assert(c->sorted_entries == 0); return TRUE; } + // add to the list + add_entry(c, 0, k, m++, len[k], values); + // add all available leaves + for (i=1; i <= len[k]; ++i) + available[i] = 1 << (32-i); + // note that the above code treats the first case specially, + // but it's really the same as the following code, so they + // could probably be combined (except the initial code is 0, + // and I use 0 in available[] to mean 'empty') + for (i=k+1; i < n; ++i) { + uint32 res; + int z = len[i], y; + if (z == NO_CODE) continue; + // find lowest available leaf (should always be earliest, + // which is what the specification calls for) + // note that this property, and the fact we can never have + // more than one free leaf at a given level, isn't totally + // trivial to prove, but it seems true and the assert never + // fires, so! + while (z > 0 && !available[z]) --z; + if (z == 0) { assert(0); return FALSE; } + res = available[z]; + available[z] = 0; + add_entry(c, bit_reverse(res), i, m++, len[i], values); + // propogate availability up the tree + if (z != len[i]) { + for (y=len[i]; y > z; --y) { + assert(available[y] == 0); + available[y] = res + (1 << (32-y)); + } + } + } + return TRUE; +} + +// accelerated huffman table allows fast O(1) match of all symbols +// of length <= STB_VORBIS_FAST_HUFFMAN_LENGTH +static void compute_accelerated_huffman(Codebook *c) +{ + int i, len; + for (i=0; i < FAST_HUFFMAN_TABLE_SIZE; ++i) + c->fast_huffman[i] = -1; + + len = c->sparse ? c->sorted_entries : c->entries; + #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT + if (len > 32767) len = 32767; // largest possible value we can encode! + #endif + for (i=0; i < len; ++i) { + if (c->codeword_lengths[i] <= STB_VORBIS_FAST_HUFFMAN_LENGTH) { + uint32 z = c->sparse ? bit_reverse(c->sorted_codewords[i]) : c->codewords[i]; + // set table entries for all bit combinations in the higher bits + while (z < FAST_HUFFMAN_TABLE_SIZE) { + c->fast_huffman[z] = i; + z += 1 << c->codeword_lengths[i]; + } + } + } +} + +static int uint32_compare(const void *p, const void *q) +{ + uint32 x = * (uint32 *) p; + uint32 y = * (uint32 *) q; + return x < y ? -1 : x > y; +} + +static int include_in_sort(Codebook *c, uint8 len) +{ + if (c->sparse) { assert(len != NO_CODE); return TRUE; } + if (len == NO_CODE) return FALSE; + if (len > STB_VORBIS_FAST_HUFFMAN_LENGTH) return TRUE; + return FALSE; +} + +// if the fast table above doesn't work, we want to binary +// search them... need to reverse the bits +static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values) +{ + int i, len; + // build a list of all the entries + // OPTIMIZATION: don't include the short ones, since they'll be caught by FAST_HUFFMAN. + // this is kind of a frivolous optimization--I don't see any performance improvement, + // but it's like 4 extra lines of code, so. + if (!c->sparse) { + int k = 0; + for (i=0; i < c->entries; ++i) + if (include_in_sort(c, lengths[i])) + c->sorted_codewords[k++] = bit_reverse(c->codewords[i]); + assert(k == c->sorted_entries); + } else { + for (i=0; i < c->sorted_entries; ++i) + c->sorted_codewords[i] = bit_reverse(c->codewords[i]); + } + + qsort(c->sorted_codewords, c->sorted_entries, sizeof(c->sorted_codewords[0]), uint32_compare); + c->sorted_codewords[c->sorted_entries] = 0xffffffff; + + len = c->sparse ? c->sorted_entries : c->entries; + // now we need to indicate how they correspond; we could either + // #1: sort a different data structure that says who they correspond to + // #2: for each sorted entry, search the original list to find who corresponds + // #3: for each original entry, find the sorted entry + // #1 requires extra storage, #2 is slow, #3 can use binary search! + for (i=0; i < len; ++i) { + int huff_len = c->sparse ? lengths[values[i]] : lengths[i]; + if (include_in_sort(c,huff_len)) { + uint32 code = bit_reverse(c->codewords[i]); + int x=0, n=c->sorted_entries; + while (n > 1) { + // invariant: sc[x] <= code < sc[x+n] + int m = x + (n >> 1); + if (c->sorted_codewords[m] <= code) { + x = m; + n -= (n>>1); + } else { + n >>= 1; + } + } + assert(c->sorted_codewords[x] == code); + if (c->sparse) { + c->sorted_values[x] = values[i]; + c->codeword_lengths[x] = huff_len; + } else { + c->sorted_values[x] = i; + } + } + } +} + +// only run while parsing the header (3 times) +static int vorbis_validate(uint8 *data) +{ + static uint8 vorbis[6] = { 'v', 'o', 'r', 'b', 'i', 's' }; + return memcmp(data, vorbis, 6) == 0; +} + +// called from setup only, once per code book +// (formula implied by specification) +static int lookup1_values(int entries, int dim) +{ + int r = (int) floor(exp((float) log((float) entries) / dim)); + if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning; + ++r; // floor() to avoid _ftol() when non-CRT + assert(pow((float) r+1, dim) > entries); + assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above + return r; +} + +// called twice per file +static void compute_twiddle_factors(int n, float *A, float *B, float *C) +{ + int n4 = n >> 2, n8 = n >> 3; + int k,k2; + + for (k=k2=0; k < n4; ++k,k2+=2) { + A[k2 ] = (float) cos(4*k*M_PI/n); + A[k2+1] = (float) -sin(4*k*M_PI/n); + B[k2 ] = (float) cos((k2+1)*M_PI/n/2) * 0.5f; + B[k2+1] = (float) sin((k2+1)*M_PI/n/2) * 0.5f; + } + for (k=k2=0; k < n8; ++k,k2+=2) { + C[k2 ] = (float) cos(2*(k2+1)*M_PI/n); + C[k2+1] = (float) -sin(2*(k2+1)*M_PI/n); + } +} + +static void compute_window(int n, float *window) +{ + int n2 = n >> 1, i; + for (i=0; i < n2; ++i) + window[i] = (float) sin(0.5 * M_PI * square((float) sin((i - 0 + 0.5) / n2 * 0.5 * M_PI))); +} + +static void compute_bitreverse(int n, uint16 *rev) +{ + int ld = ilog(n) - 1; // ilog is off-by-one from normal definitions + int i, n8 = n >> 3; + for (i=0; i < n8; ++i) + rev[i] = (bit_reverse(i) >> (32-ld+3)) << 2; +} + +static int init_blocksize(vorb *f, int b, int n) +{ + int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3; + f->A[b] = (float *) setup_malloc(f, sizeof(float) * n2); + f->B[b] = (float *) setup_malloc(f, sizeof(float) * n2); + f->C[b] = (float *) setup_malloc(f, sizeof(float) * n4); + if (!f->A[b] || !f->B[b] || !f->C[b]) return error(f, VORBIS_outofmem); + compute_twiddle_factors(n, f->A[b], f->B[b], f->C[b]); + f->window[b] = (float *) setup_malloc(f, sizeof(float) * n2); + if (!f->window[b]) return error(f, VORBIS_outofmem); + compute_window(n, f->window[b]); + f->bit_reverse[b] = (uint16 *) setup_malloc(f, sizeof(uint16) * n8); + if (!f->bit_reverse[b]) return error(f, VORBIS_outofmem); + compute_bitreverse(n, f->bit_reverse[b]); + return TRUE; +} + +static void neighbors(uint16 *x, int n, int *plow, int *phigh) +{ + int low = -1; + int high = 65536; + int i; + for (i=0; i < n; ++i) { + if (x[i] > low && x[i] < x[n]) { *plow = i; low = x[i]; } + if (x[i] < high && x[i] > x[n]) { *phigh = i; high = x[i]; } + } +} + +// this has been repurposed so y is now the original index instead of y +typedef struct +{ + uint16 x,y; +} Point; + +int point_compare(const void *p, const void *q) +{ + Point *a = (Point *) p; + Point *b = (Point *) q; + return a->x < b->x ? -1 : a->x > b->x; +} + +// +/////////////////////// END LEAF SETUP FUNCTIONS ////////////////////////// + + +#if defined(STB_VORBIS_NO_STDIO) + #define USE_MEMORY(z) TRUE +#else + #define USE_MEMORY(z) ((z)->stream) +#endif + +static uint8 get8(vorb *z) +{ + if (USE_MEMORY(z)) { + if (z->stream >= z->stream_end) { z->eof = TRUE; return 0; } + return *z->stream++; + } + + #ifndef STB_VORBIS_NO_STDIO + { + int c = fgetc(z->f); + if (c == EOF) { z->eof = TRUE; return 0; } + return c; + } + #endif +} + +static uint32 get32(vorb *f) +{ + uint32 x; + x = get8(f); + x += get8(f) << 8; + x += get8(f) << 16; + x += get8(f) << 24; + return x; +} + +static int getn(vorb *z, uint8 *data, int n) +{ + if (USE_MEMORY(z)) { + if (z->stream+n > z->stream_end) { z->eof = 1; return 0; } + memcpy(data, z->stream, n); + z->stream += n; + return 1; + } + + #ifndef STB_VORBIS_NO_STDIO + if (fread(data, n, 1, z->f) == 1) + return 1; + else { + z->eof = 1; + return 0; + } + #endif +} + +static void skip(vorb *z, int n) +{ + if (USE_MEMORY(z)) { + z->stream += n; + if (z->stream >= z->stream_end) z->eof = 1; + return; + } + #ifndef STB_VORBIS_NO_STDIO + { + long x = ftell(z->f); + fseek(z->f, x+n, SEEK_SET); + } + #endif +} + +static int set_file_offset(stb_vorbis *f, unsigned int loc) +{ + #ifndef STB_VORBIS_NO_PUSHDATA_API + if (f->push_mode) return 0; + #endif + f->eof = 0; + if (USE_MEMORY(f)) { + if (f->stream_start + loc >= f->stream_end || f->stream_start + loc < f->stream_start) { + f->stream = f->stream_end; + f->eof = 1; + return 0; + } else { + f->stream = f->stream_start + loc; + return 1; + } + } + #ifndef STB_VORBIS_NO_STDIO + if (loc + f->f_start < loc || loc >= 0x80000000) { + loc = 0x7fffffff; + f->eof = 1; + } else { + loc += f->f_start; + } + if (!fseek(f->f, loc, SEEK_SET)) + return 1; + f->eof = 1; + fseek(f->f, f->f_start, SEEK_END); + return 0; + #endif +} + + +static uint8 ogg_page_header[4] = { 0x4f, 0x67, 0x67, 0x53 }; + +static int capture_pattern(vorb *f) +{ + if (0x4f != get8(f)) return FALSE; + if (0x67 != get8(f)) return FALSE; + if (0x67 != get8(f)) return FALSE; + if (0x53 != get8(f)) return FALSE; + return TRUE; +} + +#define PAGEFLAG_continued_packet 1 +#define PAGEFLAG_first_page 2 +#define PAGEFLAG_last_page 4 + +static int start_page_no_capturepattern(vorb *f) +{ + uint32 loc0,loc1,n; + // stream structure version + if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version); + // header flag + f->page_flag = get8(f); + // absolute granule position + loc0 = get32(f); + loc1 = get32(f); + // @TODO: validate loc0,loc1 as valid positions? + // stream serial number -- vorbis doesn't interleave, so discard + get32(f); + //if (f->serial != get32(f)) return error(f, VORBIS_incorrect_stream_serial_number); + // page sequence number + n = get32(f); + f->last_page = n; + // CRC32 + get32(f); + // page_segments + f->segment_count = get8(f); + if (!getn(f, f->segments, f->segment_count)) + return error(f, VORBIS_unexpected_eof); + // assume we _don't_ know any the sample position of any segments + f->end_seg_with_known_loc = -2; + if (loc0 != ~0 || loc1 != ~0) { + int i; + // determine which packet is the last one that will complete + for (i=f->segment_count-1; i >= 0; --i) + if (f->segments[i] < 255) + break; + // 'i' is now the index of the _last_ segment of a packet that ends + if (i >= 0) { + f->end_seg_with_known_loc = i; + f->known_loc_for_packet = loc0; + } + } + if (f->first_decode) { + int i,len; + ProbedPage p; + len = 0; + for (i=0; i < f->segment_count; ++i) + len += f->segments[i]; + len += 27 + f->segment_count; + p.page_start = f->first_audio_page_offset; + p.page_end = p.page_start + len; + p.after_previous_page_start = p.page_start; + p.first_decoded_sample = 0; + p.last_decoded_sample = loc0; + f->p_first = p; + } + f->next_seg = 0; + return TRUE; +} + +static int start_page(vorb *f) +{ + if (!capture_pattern(f)) return error(f, VORBIS_missing_capture_pattern); + return start_page_no_capturepattern(f); +} + +static int start_packet(vorb *f) +{ + while (f->next_seg == -1) { + if (!start_page(f)) return FALSE; + if (f->page_flag & PAGEFLAG_continued_packet) + return error(f, VORBIS_continued_packet_flag_invalid); + } + f->last_seg = FALSE; + f->valid_bits = 0; + f->packet_bytes = 0; + f->bytes_in_seg = 0; + // f->next_seg is now valid + return TRUE; +} + +static int maybe_start_packet(vorb *f) +{ + if (f->next_seg == -1) { + int x = get8(f); + if (f->eof) return FALSE; // EOF at page boundary is not an error! + if (0x4f != x ) return error(f, VORBIS_missing_capture_pattern); + if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (0x53 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (!start_page_no_capturepattern(f)) return FALSE; + if (f->page_flag & PAGEFLAG_continued_packet) { + // set up enough state that we can read this packet if we want, + // e.g. during recovery + f->last_seg = FALSE; + f->bytes_in_seg = 0; + return error(f, VORBIS_continued_packet_flag_invalid); + } + } + return start_packet(f); +} + +static int next_segment(vorb *f) +{ + int len; + if (f->last_seg) return 0; + if (f->next_seg == -1) { + f->last_seg_which = f->segment_count-1; // in case start_page fails + if (!start_page(f)) { f->last_seg = 1; return 0; } + if (!(f->page_flag & PAGEFLAG_continued_packet)) return error(f, VORBIS_continued_packet_flag_invalid); + } + len = f->segments[f->next_seg++]; + if (len < 255) { + f->last_seg = TRUE; + f->last_seg_which = f->next_seg-1; + } + if (f->next_seg >= f->segment_count) + f->next_seg = -1; + assert(f->bytes_in_seg == 0); + f->bytes_in_seg = len; + return len; +} + +#define EOP (-1) +#define INVALID_BITS (-1) + +static int get8_packet_raw(vorb *f) +{ + if (!f->bytes_in_seg){ + if (f->last_seg) return EOP; + else if (!next_segment(f)) return EOP; + } + assert(f->bytes_in_seg > 0); + --f->bytes_in_seg; + ++f->packet_bytes; + return get8(f); +} + +static int get8_packet(vorb *f) +{ + int x = get8_packet_raw(f); + f->valid_bits = 0; + return x; +} + +static void flush_packet(vorb *f) +{ + while (get8_packet_raw(f) != EOP); +} + +// @OPTIMIZE: this is the secondary bit decoder, so it's probably not as important +// as the huffman decoder? +static uint32 get_bits(vorb *f, int n) +{ + uint32 z; + + if (f->valid_bits < 0) return 0; + if (f->valid_bits < n) { + if (n > 24) { + // the accumulator technique below would not work correctly in this case + z = get_bits(f, 24); + z += get_bits(f, n-24) << 24; + return z; + } + if (f->valid_bits == 0) f->acc = 0; + while (f->valid_bits < n) { + int z = get8_packet_raw(f); + if (z == EOP) { + f->valid_bits = INVALID_BITS; + return 0; + } + f->acc += z << f->valid_bits; + f->valid_bits += 8; + } + } + if (f->valid_bits < 0) return 0; + z = f->acc & ((1 << n)-1); + f->acc >>= n; + f->valid_bits -= n; + return z; +} + +// @OPTIMIZE: primary accumulator for huffman +// expand the buffer to as many bits as possible without reading off end of packet +// it might be nice to allow f->valid_bits and f->acc to be stored in registers, +// e.g. cache them locally and decode locally +static __forceinline void prep_huffman(vorb *f) +{ + if (f->valid_bits <= 24) { + if (f->valid_bits == 0) f->acc = 0; + do { + int z; + if (f->last_seg && !f->bytes_in_seg) return; + z = get8_packet_raw(f); + if (z == EOP) return; + f->acc += z << f->valid_bits; + f->valid_bits += 8; + } while (f->valid_bits <= 24); + } +} + +enum +{ + VORBIS_packet_id = 1, + VORBIS_packet_comment = 3, + VORBIS_packet_setup = 5, +}; + +static int codebook_decode_scalar_raw(vorb *f, Codebook *c) +{ + int i; + prep_huffman(f); + + assert(c->sorted_codewords || c->codewords); + // cases to use binary search: sorted_codewords && !c->codewords + // sorted_codewords && c->entries > 8 + if (c->entries > 8 ? c->sorted_codewords!=NULL : !c->codewords) { + // binary search + uint32 code = bit_reverse(f->acc); + int x=0, n=c->sorted_entries, len; + + while (n > 1) { + // invariant: sc[x] <= code < sc[x+n] + int m = x + (n >> 1); + if (c->sorted_codewords[m] <= code) { + x = m; + n -= (n>>1); + } else { + n >>= 1; + } + } + // x is now the sorted index + if (!c->sparse) x = c->sorted_values[x]; + // x is now sorted index if sparse, or symbol otherwise + len = c->codeword_lengths[x]; + if (f->valid_bits >= len) { + f->acc >>= len; + f->valid_bits -= len; + return x; + } + + f->valid_bits = 0; + return -1; + } + + // if small, linear search + assert(!c->sparse); + for (i=0; i < c->entries; ++i) { + if (c->codeword_lengths[i] == NO_CODE) continue; + if (c->codewords[i] == (f->acc & ((1 << c->codeword_lengths[i])-1))) { + if (f->valid_bits >= c->codeword_lengths[i]) { + f->acc >>= c->codeword_lengths[i]; + f->valid_bits -= c->codeword_lengths[i]; + return i; + } + f->valid_bits = 0; + return -1; + } + } + + error(f, VORBIS_invalid_stream); + f->valid_bits = 0; + return -1; +} + +#ifndef STB_VORBIS_NO_INLINE_DECODE + +#define DECODE_RAW(var, f,c) \ + if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) \ + prep_huffman(f); \ + var = f->acc & FAST_HUFFMAN_TABLE_MASK; \ + var = c->fast_huffman[var]; \ + if (var >= 0) { \ + int n = c->codeword_lengths[var]; \ + f->acc >>= n; \ + f->valid_bits -= n; \ + if (f->valid_bits < 0) { f->valid_bits = 0; var = -1; } \ + } else { \ + var = codebook_decode_scalar_raw(f,c); \ + } + +#else + +#define DECODE_RAW(var,f,c) var = codebook_decode_scalar(f,c); + +#endif + +#define DECODE(var,f,c) \ + DECODE_RAW(var,f,c) \ + if (c->sparse) var = c->sorted_values[var]; + +#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK + #define DECODE_VQ(var,f,c) DECODE_RAW(var,f,c) +#else + #define DECODE_VQ(var,f,c) DECODE(var,f,c) +#endif + + + + + + +// CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case +// where we avoid one addition +#ifndef STB_VORBIS_CODEBOOK_FLOATS + #define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off] * c->delta_value + c->minimum_value) + #define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off] * c->delta_value) + #define CODEBOOK_ELEMENT_BASE(c) (c->minimum_value) +#else + #define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off]) + #define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off]) + #define CODEBOOK_ELEMENT_BASE(c) (0) +#endif + +static int codebook_decode_start(vorb *f, Codebook *c, int len) +{ + int z = -1; + + // type 0 is only legal in a scalar context + if (c->lookup_type == 0) + error(f, VORBIS_invalid_stream); + else { + DECODE_VQ(z,f,c); + if (c->sparse) assert(z < c->sorted_entries); + if (z < 0) { // check for EOP + if (!f->bytes_in_seg) + if (f->last_seg) + return z; + error(f, VORBIS_invalid_stream); + } + } + return z; +} + +static int codebook_decode(vorb *f, Codebook *c, float *output, int len) +{ + int i,z = codebook_decode_start(f,c,len); + if (z < 0) return FALSE; + if (len > c->dimensions) len = c->dimensions; + +#ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK + if (c->lookup_type == 1) { + float last = CODEBOOK_ELEMENT_BASE(c); + int div = 1; + for (i=0; i < len; ++i) { + int off = (z / div) % c->lookup_values; + float val = CODEBOOK_ELEMENT_FAST(c,off) + last; + output[i] += val; + if (c->sequence_p) last = val + c->minimum_value; + div *= c->lookup_values; + } + return TRUE; + } +#endif + + z *= c->dimensions; + if (c->sequence_p) { + float last = CODEBOOK_ELEMENT_BASE(c); + for (i=0; i < len; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; + output[i] += val; + last = val + c->minimum_value; + } + } else { + float last = CODEBOOK_ELEMENT_BASE(c); + for (i=0; i < len; ++i) { + output[i] += CODEBOOK_ELEMENT_FAST(c,z+i) + last; + } + } + + return TRUE; +} + +static int codebook_decode_step(vorb *f, Codebook *c, float *output, int len, int step) +{ + int i,z = codebook_decode_start(f,c,len); + float last = CODEBOOK_ELEMENT_BASE(c); + if (z < 0) return FALSE; + if (len > c->dimensions) len = c->dimensions; + +#ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK + if (c->lookup_type == 1) { + int div = 1; + for (i=0; i < len; ++i) { + int off = (z / div) % c->lookup_values; + float val = CODEBOOK_ELEMENT_FAST(c,off) + last; + output[i*step] += val; + if (c->sequence_p) last = val; + div *= c->lookup_values; + } + return TRUE; + } +#endif + + z *= c->dimensions; + for (i=0; i < len; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; + output[i*step] += val; + if (c->sequence_p) last = val; + } + + return TRUE; +} + +static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **outputs, int ch, int *c_inter_p, int *p_inter_p, int len, int total_decode) +{ + int c_inter = *c_inter_p; + int p_inter = *p_inter_p; + int i,z, effective = c->dimensions; + + // type 0 is only legal in a scalar context + if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream); + + while (total_decode > 0) { + float last = CODEBOOK_ELEMENT_BASE(c); + DECODE_VQ(z,f,c); + #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK + assert(!c->sparse || z < c->sorted_entries); + #endif + if (z < 0) { + if (!f->bytes_in_seg) + if (f->last_seg) return FALSE; + return error(f, VORBIS_invalid_stream); + } + + // if this will take us off the end of the buffers, stop short! + // we check by computing the length of the virtual interleaved + // buffer (len*ch), our current offset within it (p_inter*ch)+(c_inter), + // and the length we'll be using (effective) + if (c_inter + p_inter*ch + effective > len * ch) { + effective = len*ch - (p_inter*ch - c_inter); + } + + #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK + if (c->lookup_type == 1) { + int div = 1; + for (i=0; i < effective; ++i) { + int off = (z / div) % c->lookup_values; + float val = CODEBOOK_ELEMENT_FAST(c,off) + last; + outputs[c_inter][p_inter] += val; + if (++c_inter == ch) { c_inter = 0; ++p_inter; } + if (c->sequence_p) last = val; + div *= c->lookup_values; + } + } else + #endif + { + z *= c->dimensions; + if (c->sequence_p) { + for (i=0; i < effective; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; + outputs[c_inter][p_inter] += val; + if (++c_inter == ch) { c_inter = 0; ++p_inter; } + last = val; + } + } else { + for (i=0; i < effective; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; + outputs[c_inter][p_inter] += val; + if (++c_inter == ch) { c_inter = 0; ++p_inter; } + } + } + } + + total_decode -= effective; + } + *c_inter_p = c_inter; + *p_inter_p = p_inter; + return TRUE; +} + +#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK +static int codebook_decode_deinterleave_repeat_2(vorb *f, Codebook *c, float **outputs, int *c_inter_p, int *p_inter_p, int len, int total_decode) +{ + int c_inter = *c_inter_p; + int p_inter = *p_inter_p; + int i,z, effective = c->dimensions; + + // type 0 is only legal in a scalar context + if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream); + + while (total_decode > 0) { + float last = CODEBOOK_ELEMENT_BASE(c); + DECODE_VQ(z,f,c); + + if (z < 0) { + if (!f->bytes_in_seg) + if (f->last_seg) return FALSE; + return error(f, VORBIS_invalid_stream); + } + + // if this will take us off the end of the buffers, stop short! + // we check by computing the length of the virtual interleaved + // buffer (len*ch), our current offset within it (p_inter*ch)+(c_inter), + // and the length we'll be using (effective) + if (c_inter + p_inter*2 + effective > len * 2) { + effective = len*2 - (p_inter*2 - c_inter); + } + + { + z *= c->dimensions; + stb_prof(11); + if (c->sequence_p) { + // haven't optimized this case because I don't have any examples + for (i=0; i < effective; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; + outputs[c_inter][p_inter] += val; + if (++c_inter == 2) { c_inter = 0; ++p_inter; } + last = val; + } + } else { + i=0; + if (c_inter == 1) { + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; + outputs[c_inter][p_inter] += val; + c_inter = 0; ++p_inter; + ++i; + } + { + float *z0 = outputs[0]; + float *z1 = outputs[1]; + for (; i+1 < effective;) { + z0[p_inter] += CODEBOOK_ELEMENT_FAST(c,z+i) + last; + z1[p_inter] += CODEBOOK_ELEMENT_FAST(c,z+i+1) + last; + ++p_inter; + i += 2; + } + } + if (i < effective) { + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; + outputs[c_inter][p_inter] += val; + if (++c_inter == 2) { c_inter = 0; ++p_inter; } + } + } + } + + total_decode -= effective; + } + *c_inter_p = c_inter; + *p_inter_p = p_inter; + return TRUE; +} +#endif + +static int predict_point(int x, int x0, int x1, int y0, int y1) +{ + int dy = y1 - y0; + int adx = x1 - x0; + // @OPTIMIZE: force int division to round in the right direction... is this necessary on x86? + int err = abs(dy) * (x - x0); + int off = err / adx; + return dy < 0 ? y0 - off : y0 + off; +} + +// the following table is block-copied from the specification +static float inverse_db_table[256] = +{ + 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, + 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, + 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, + 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, + 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, + 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, + 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, + 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, + 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, + 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, + 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, + 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, + 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, + 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, + 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, + 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, + 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, + 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, + 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, + 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, + 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, + 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, + 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, + 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, + 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, + 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, + 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, + 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, + 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, + 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, + 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, + 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, + 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, + 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, + 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, + 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, + 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, + 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, + 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, + 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, + 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, + 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, + 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, + 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, + 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, + 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, + 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, + 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, + 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, + 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, + 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, + 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, + 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, + 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, + 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, + 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, + 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, + 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, + 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, + 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, + 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, + 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, + 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, + 0.82788260f, 0.88168307f, 0.9389798f, 1.0f +}; + + +// @OPTIMIZE: if you want to replace this bresenham line-drawing routine, +// note that you must produce bit-identical output to decode correctly; +// this specific sequence of operations is specified in the spec (it's +// drawing integer-quantized frequency-space lines that the encoder +// expects to be exactly the same) +// ... also, isn't the whole point of Bresenham's algorithm to NOT +// have to divide in the setup? sigh. +#ifndef STB_VORBIS_NO_DEFER_FLOOR +#define LINE_OP(a,b) a *= b +#else +#define LINE_OP(a,b) a = b +#endif + +#ifdef STB_VORBIS_DIVIDE_TABLE +#define DIVTAB_NUMER 32 +#define DIVTAB_DENOM 64 +int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]; // 2KB +#endif + +static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y1, int n) +{ + int dy = y1 - y0; + int adx = x1 - x0; + int ady = abs(dy); + int base; + int x=x0,y=y0; + int err = 0; + int sy; + +#ifdef STB_VORBIS_DIVIDE_TABLE + if (adx < DIVTAB_DENOM && ady < DIVTAB_NUMER) { + if (dy < 0) { + base = -integer_divide_table[ady][adx]; + sy = base-1; + } else { + base = integer_divide_table[ady][adx]; + sy = base+1; + } + } else { + base = dy / adx; + if (dy < 0) + sy = base - 1; + else + sy = base+1; + } +#else + base = dy / adx; + if (dy < 0) + sy = base - 1; + else + sy = base+1; +#endif + ady -= abs(base) * adx; + if (x1 > n) x1 = n; + LINE_OP(output[x], inverse_db_table[y]); + for (++x; x < x1; ++x) { + err += ady; + if (err >= adx) { + err -= adx; + y += sy; + } else + y += base; + LINE_OP(output[x], inverse_db_table[y]); + } +} + +static int residue_decode(vorb *f, Codebook *book, float *target, int offset, int n, int rtype) +{ + int k; + if (rtype == 0) { + int step = n / book->dimensions; + for (k=0; k < step; ++k) + if (!codebook_decode_step(f, book, target+offset+k, n-offset-k, step)) + return FALSE; + } else { + for (k=0; k < n; ) { + if (!codebook_decode(f, book, target+offset, n-k)) + return FALSE; + k += book->dimensions; + offset += book->dimensions; + } + } + return TRUE; +} + +static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode) +{ + int i,j,pass; + Residue *r = f->residue_config + rn; + int rtype = f->residue_types[rn]; + int c = r->classbook; + int classwords = f->codebooks[c].dimensions; + int n_read = r->end - r->begin; + int part_read = n_read / r->part_size; + int temp_alloc_point = temp_alloc_save(f); + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + uint8 ***part_classdata = (uint8 ***) temp_block_array(f,f->channels, part_read * sizeof(**part_classdata)); + #else + int **classifications = (int **) temp_block_array(f,f->channels, part_read * sizeof(**classifications)); + #endif + + stb_prof(2); + for (i=0; i < ch; ++i) + if (!do_not_decode[i]) + memset(residue_buffers[i], 0, sizeof(float) * n); + + if (rtype == 2 && ch != 1) { + // int len = ch * n; + for (j=0; j < ch; ++j) + if (!do_not_decode[j]) + break; + if (j == ch) + goto done; + + stb_prof(3); + for (pass=0; pass < 8; ++pass) { + int pcount = 0, class_set = 0; + if (ch == 2) { + stb_prof(13); + while (pcount < part_read) { + int z = r->begin + pcount*r->part_size; + int c_inter = (z & 1), p_inter = z>>1; + if (pass == 0) { + Codebook *c = f->codebooks+r->classbook; + int q; + DECODE(q,f,c); + if (q == EOP) goto done; + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + part_classdata[0][class_set] = r->classdata[q]; + #else + for (i=classwords-1; i >= 0; --i) { + classifications[0][i+pcount] = q % r->classifications; + q /= r->classifications; + } + #endif + } + stb_prof(5); + for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { + int z = r->begin + pcount*r->part_size; + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + int c = part_classdata[0][class_set][i]; + #else + int c = classifications[0][pcount]; + #endif + int b = r->residue_books[c][pass]; + if (b >= 0) { + Codebook *book = f->codebooks + b; + stb_prof(20); // accounts for X time + #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK + if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) + goto done; + #else + // saves 1% + if (!codebook_decode_deinterleave_repeat_2(f, book, residue_buffers, &c_inter, &p_inter, n, r->part_size)) + goto done; + #endif + stb_prof(7); + } else { + z += r->part_size; + c_inter = z & 1; + p_inter = z >> 1; + } + } + stb_prof(8); + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + ++class_set; + #endif + } + } else if (ch == 1) { + while (pcount < part_read) { + int z = r->begin + pcount*r->part_size; + int c_inter = 0, p_inter = z; + if (pass == 0) { + Codebook *c = f->codebooks+r->classbook; + int q; + DECODE(q,f,c); + if (q == EOP) goto done; + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + part_classdata[0][class_set] = r->classdata[q]; + #else + for (i=classwords-1; i >= 0; --i) { + classifications[0][i+pcount] = q % r->classifications; + q /= r->classifications; + } + #endif + } + for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { + int z = r->begin + pcount*r->part_size; + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + int c = part_classdata[0][class_set][i]; + #else + int c = classifications[0][pcount]; + #endif + int b = r->residue_books[c][pass]; + if (b >= 0) { + Codebook *book = f->codebooks + b; + stb_prof(22); + if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) + goto done; + stb_prof(3); + } else { + z += r->part_size; + c_inter = 0; + p_inter = z; + } + } + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + ++class_set; + #endif + } + } else { + while (pcount < part_read) { + int z = r->begin + pcount*r->part_size; + int c_inter = z % ch, p_inter = z/ch; + if (pass == 0) { + Codebook *c = f->codebooks+r->classbook; + int q; + DECODE(q,f,c); + if (q == EOP) goto done; + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + part_classdata[0][class_set] = r->classdata[q]; + #else + for (i=classwords-1; i >= 0; --i) { + classifications[0][i+pcount] = q % r->classifications; + q /= r->classifications; + } + #endif + } + for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { + int z = r->begin + pcount*r->part_size; + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + int c = part_classdata[0][class_set][i]; + #else + int c = classifications[0][pcount]; + #endif + int b = r->residue_books[c][pass]; + if (b >= 0) { + Codebook *book = f->codebooks + b; + stb_prof(22); + if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) + goto done; + stb_prof(3); + } else { + z += r->part_size; + c_inter = z % ch; + p_inter = z / ch; + } + } + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + ++class_set; + #endif + } + } + } + goto done; + } + stb_prof(9); + + for (pass=0; pass < 8; ++pass) { + int pcount = 0, class_set=0; + while (pcount < part_read) { + if (pass == 0) { + for (j=0; j < ch; ++j) { + if (!do_not_decode[j]) { + Codebook *c = f->codebooks+r->classbook; + int temp; + DECODE(temp,f,c); + if (temp == EOP) goto done; + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + part_classdata[j][class_set] = r->classdata[temp]; + #else + for (i=classwords-1; i >= 0; --i) { + classifications[j][i+pcount] = temp % r->classifications; + temp /= r->classifications; + } + #endif + } + } + } + for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { + for (j=0; j < ch; ++j) { + if (!do_not_decode[j]) { + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + int c = part_classdata[j][class_set][i]; + #else + int c = classifications[j][pcount]; + #endif + int b = r->residue_books[c][pass]; + if (b >= 0) { + float *target = residue_buffers[j]; + int offset = r->begin + pcount * r->part_size; + int n = r->part_size; + Codebook *book = f->codebooks + b; + if (!residue_decode(f, book, target, offset, n, rtype)) + goto done; + } + } + } + } + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + ++class_set; + #endif + } + } + done: + stb_prof(0); + temp_alloc_restore(f,temp_alloc_point); +} + + +#if 0 +// slow way for debugging +void inverse_mdct_slow(float *buffer, int n) +{ + int i,j; + int n2 = n >> 1; + float *x = (float *) malloc(sizeof(*x) * n2); + memcpy(x, buffer, sizeof(*x) * n2); + for (i=0; i < n; ++i) { + float acc = 0; + for (j=0; j < n2; ++j) + // formula from paper: + //acc += n/4.0f * x[j] * (float) cos(M_PI / 2 / n * (2 * i + 1 + n/2.0)*(2*j+1)); + // formula from wikipedia + //acc += 2.0f / n2 * x[j] * (float) cos(M_PI/n2 * (i + 0.5 + n2/2)*(j + 0.5)); + // these are equivalent, except the formula from the paper inverts the multiplier! + // however, what actually works is NO MULTIPLIER!?! + //acc += 64 * 2.0f / n2 * x[j] * (float) cos(M_PI/n2 * (i + 0.5 + n2/2)*(j + 0.5)); + acc += x[j] * (float) cos(M_PI / 2 / n * (2 * i + 1 + n/2.0)*(2*j+1)); + buffer[i] = acc; + } + free(x); +} +#elif 0 +// same as above, but just barely able to run in real time on modern machines +void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) +{ + float mcos[16384]; + int i,j; + int n2 = n >> 1, nmask = (n << 2) -1; + float *x = (float *) malloc(sizeof(*x) * n2); + memcpy(x, buffer, sizeof(*x) * n2); + for (i=0; i < 4*n; ++i) + mcos[i] = (float) cos(M_PI / 2 * i / n); + + for (i=0; i < n; ++i) { + float acc = 0; + for (j=0; j < n2; ++j) + acc += x[j] * mcos[(2 * i + 1 + n2)*(2*j+1) & nmask]; + buffer[i] = acc; + } + free(x); +} +#else +// transform to use a slow dct-iv; this is STILL basically trivial, +// but only requires half as many ops +void dct_iv_slow(float *buffer, int n) +{ + float mcos[16384]; + float x[2048]; + int i,j; + int nmask = (n << 3) - 1; + memcpy(x, buffer, sizeof(*x) * n); + for (i=0; i < 8*n; ++i) + mcos[i] = (float) cos(M_PI / 4 * i / n); + for (i=0; i < n; ++i) { + float acc = 0; + for (j=0; j < n; ++j) + acc += x[j] * mcos[((2 * i + 1)*(2*j+1)) & nmask]; + //acc += x[j] * cos(M_PI / n * (i + 0.5) * (j + 0.5)); + buffer[i] = acc; + } +} + +void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) +{ + int i, n4 = n >> 2, n2 = n >> 1, n3_4 = n - n4; + float temp[4096]; + + memcpy(temp, buffer, n2 * sizeof(float)); + dct_iv_slow(temp, n2); // returns -c'-d, a-b' + + for (i=0; i < n4 ; ++i) buffer[i] = temp[i+n4]; // a-b' + for ( ; i < n3_4; ++i) buffer[i] = -temp[n3_4 - i - 1]; // b-a', c+d' + for ( ; i < n ; ++i) buffer[i] = -temp[i - n3_4]; // c'+d +} +#endif + +#ifndef LIBVORBIS_MDCT +#define LIBVORBIS_MDCT 0 +#endif + +#if LIBVORBIS_MDCT +// directly call the vorbis MDCT using an interface documented +// by Jeff Roberts... useful for performance comparison +typedef struct +{ + int n; + int log2n; + + float *trig; + int *bitrev; + + float scale; +} mdct_lookup; + +extern void mdct_init(mdct_lookup *lookup, int n); +extern void mdct_clear(mdct_lookup *l); +extern void mdct_backward(mdct_lookup *init, float *in, float *out); + +mdct_lookup M1,M2; + +void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) +{ + mdct_lookup *M; + if (M1.n == n) M = &M1; + else if (M2.n == n) M = &M2; + else if (M1.n == 0) { mdct_init(&M1, n); M = &M1; } + else { + if (M2.n) __asm int 3; + mdct_init(&M2, n); + M = &M2; + } + + mdct_backward(M, buffer, buffer); +} +#endif + + +// the following were split out into separate functions while optimizing; +// they could be pushed back up but eh. __forceinline showed no change; +// they're probably already being inlined. +static void imdct_step3_iter0_loop(int n, float *e, int i_off, int k_off, float *A) +{ + float *ee0 = e + i_off; + float *ee2 = ee0 + k_off; + int i; + + assert((n & 3) == 0); + for (i=(n>>2); i > 0; --i) { + float k00_20, k01_21; + k00_20 = ee0[ 0] - ee2[ 0]; + k01_21 = ee0[-1] - ee2[-1]; + ee0[ 0] += ee2[ 0];//ee0[ 0] = ee0[ 0] + ee2[ 0]; + ee0[-1] += ee2[-1];//ee0[-1] = ee0[-1] + ee2[-1]; + ee2[ 0] = k00_20 * A[0] - k01_21 * A[1]; + ee2[-1] = k01_21 * A[0] + k00_20 * A[1]; + A += 8; + + k00_20 = ee0[-2] - ee2[-2]; + k01_21 = ee0[-3] - ee2[-3]; + ee0[-2] += ee2[-2];//ee0[-2] = ee0[-2] + ee2[-2]; + ee0[-3] += ee2[-3];//ee0[-3] = ee0[-3] + ee2[-3]; + ee2[-2] = k00_20 * A[0] - k01_21 * A[1]; + ee2[-3] = k01_21 * A[0] + k00_20 * A[1]; + A += 8; + + k00_20 = ee0[-4] - ee2[-4]; + k01_21 = ee0[-5] - ee2[-5]; + ee0[-4] += ee2[-4];//ee0[-4] = ee0[-4] + ee2[-4]; + ee0[-5] += ee2[-5];//ee0[-5] = ee0[-5] + ee2[-5]; + ee2[-4] = k00_20 * A[0] - k01_21 * A[1]; + ee2[-5] = k01_21 * A[0] + k00_20 * A[1]; + A += 8; + + k00_20 = ee0[-6] - ee2[-6]; + k01_21 = ee0[-7] - ee2[-7]; + ee0[-6] += ee2[-6];//ee0[-6] = ee0[-6] + ee2[-6]; + ee0[-7] += ee2[-7];//ee0[-7] = ee0[-7] + ee2[-7]; + ee2[-6] = k00_20 * A[0] - k01_21 * A[1]; + ee2[-7] = k01_21 * A[0] + k00_20 * A[1]; + A += 8; + ee0 -= 8; + ee2 -= 8; + } +} + +static void imdct_step3_inner_r_loop(int lim, float *e, int d0, int k_off, float *A, int k1) +{ + int i; + float k00_20, k01_21; + + float *e0 = e + d0; + float *e2 = e0 + k_off; + + for (i=lim >> 2; i > 0; --i) { + k00_20 = e0[-0] - e2[-0]; + k01_21 = e0[-1] - e2[-1]; + e0[-0] += e2[-0];//e0[-0] = e0[-0] + e2[-0]; + e0[-1] += e2[-1];//e0[-1] = e0[-1] + e2[-1]; + e2[-0] = (k00_20)*A[0] - (k01_21) * A[1]; + e2[-1] = (k01_21)*A[0] + (k00_20) * A[1]; + + A += k1; + + k00_20 = e0[-2] - e2[-2]; + k01_21 = e0[-3] - e2[-3]; + e0[-2] += e2[-2];//e0[-2] = e0[-2] + e2[-2]; + e0[-3] += e2[-3];//e0[-3] = e0[-3] + e2[-3]; + e2[-2] = (k00_20)*A[0] - (k01_21) * A[1]; + e2[-3] = (k01_21)*A[0] + (k00_20) * A[1]; + + A += k1; + + k00_20 = e0[-4] - e2[-4]; + k01_21 = e0[-5] - e2[-5]; + e0[-4] += e2[-4];//e0[-4] = e0[-4] + e2[-4]; + e0[-5] += e2[-5];//e0[-5] = e0[-5] + e2[-5]; + e2[-4] = (k00_20)*A[0] - (k01_21) * A[1]; + e2[-5] = (k01_21)*A[0] + (k00_20) * A[1]; + + A += k1; + + k00_20 = e0[-6] - e2[-6]; + k01_21 = e0[-7] - e2[-7]; + e0[-6] += e2[-6];//e0[-6] = e0[-6] + e2[-6]; + e0[-7] += e2[-7];//e0[-7] = e0[-7] + e2[-7]; + e2[-6] = (k00_20)*A[0] - (k01_21) * A[1]; + e2[-7] = (k01_21)*A[0] + (k00_20) * A[1]; + + e0 -= 8; + e2 -= 8; + + A += k1; + } +} + +static void imdct_step3_inner_s_loop(int n, float *e, int i_off, int k_off, float *A, int a_off, int k0) +{ + int i; + float A0 = A[0]; + float A1 = A[0+1]; + float A2 = A[0+a_off]; + float A3 = A[0+a_off+1]; + float A4 = A[0+a_off*2+0]; + float A5 = A[0+a_off*2+1]; + float A6 = A[0+a_off*3+0]; + float A7 = A[0+a_off*3+1]; + + float k00,k11; + + float *ee0 = e +i_off; + float *ee2 = ee0+k_off; + + for (i=n; i > 0; --i) { + k00 = ee0[ 0] - ee2[ 0]; + k11 = ee0[-1] - ee2[-1]; + ee0[ 0] = ee0[ 0] + ee2[ 0]; + ee0[-1] = ee0[-1] + ee2[-1]; + ee2[ 0] = (k00) * A0 - (k11) * A1; + ee2[-1] = (k11) * A0 + (k00) * A1; + + k00 = ee0[-2] - ee2[-2]; + k11 = ee0[-3] - ee2[-3]; + ee0[-2] = ee0[-2] + ee2[-2]; + ee0[-3] = ee0[-3] + ee2[-3]; + ee2[-2] = (k00) * A2 - (k11) * A3; + ee2[-3] = (k11) * A2 + (k00) * A3; + + k00 = ee0[-4] - ee2[-4]; + k11 = ee0[-5] - ee2[-5]; + ee0[-4] = ee0[-4] + ee2[-4]; + ee0[-5] = ee0[-5] + ee2[-5]; + ee2[-4] = (k00) * A4 - (k11) * A5; + ee2[-5] = (k11) * A4 + (k00) * A5; + + k00 = ee0[-6] - ee2[-6]; + k11 = ee0[-7] - ee2[-7]; + ee0[-6] = ee0[-6] + ee2[-6]; + ee0[-7] = ee0[-7] + ee2[-7]; + ee2[-6] = (k00) * A6 - (k11) * A7; + ee2[-7] = (k11) * A6 + (k00) * A7; + + ee0 -= k0; + ee2 -= k0; + } +} + +static __forceinline void iter_54(float *z) +{ + float k00,k11,k22,k33; + float y0,y1,y2,y3; + + k00 = z[ 0] - z[-4]; + y0 = z[ 0] + z[-4]; + y2 = z[-2] + z[-6]; + k22 = z[-2] - z[-6]; + + z[-0] = y0 + y2; // z0 + z4 + z2 + z6 + z[-2] = y0 - y2; // z0 + z4 - z2 - z6 + + // done with y0,y2 + + k33 = z[-3] - z[-7]; + + z[-4] = k00 + k33; // z0 - z4 + z3 - z7 + z[-6] = k00 - k33; // z0 - z4 - z3 + z7 + + // done with k33 + + k11 = z[-1] - z[-5]; + y1 = z[-1] + z[-5]; + y3 = z[-3] + z[-7]; + + z[-1] = y1 + y3; // z1 + z5 + z3 + z7 + z[-3] = y1 - y3; // z1 + z5 - z3 - z7 + z[-5] = k11 - k22; // z1 - z5 + z2 - z6 + z[-7] = k11 + k22; // z1 - z5 - z2 + z6 +} + +static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A, int base_n) +{ + int a_off = base_n >> 3; + float A2 = A[0+a_off]; + float *z = e + i_off; + float *base = z - 16 * n; + + while (z > base) { + float k00,k11; + + k00 = z[-0] - z[-8]; + k11 = z[-1] - z[-9]; + z[-0] = z[-0] + z[-8]; + z[-1] = z[-1] + z[-9]; + z[-8] = k00; + z[-9] = k11 ; + + k00 = z[ -2] - z[-10]; + k11 = z[ -3] - z[-11]; + z[ -2] = z[ -2] + z[-10]; + z[ -3] = z[ -3] + z[-11]; + z[-10] = (k00+k11) * A2; + z[-11] = (k11-k00) * A2; + + k00 = z[-12] - z[ -4]; // reverse to avoid a unary negation + k11 = z[ -5] - z[-13]; + z[ -4] = z[ -4] + z[-12]; + z[ -5] = z[ -5] + z[-13]; + z[-12] = k11; + z[-13] = k00; + + k00 = z[-14] - z[ -6]; // reverse to avoid a unary negation + k11 = z[ -7] - z[-15]; + z[ -6] = z[ -6] + z[-14]; + z[ -7] = z[ -7] + z[-15]; + z[-14] = (k00+k11) * A2; + z[-15] = (k00-k11) * A2; + + iter_54(z); + iter_54(z-8); + z -= 16; + } +} + +static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) +{ + int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l; + int n3_4 = n - n4, ld; + // @OPTIMIZE: reduce register pressure by using fewer variables? + int save_point = temp_alloc_save(f); + float *buf2 = (float *) temp_alloc(f, n2 * sizeof(*buf2)); + float *u=NULL,*v=NULL; + // twiddle factors + float *A = f->A[blocktype]; + + // IMDCT algorithm from "The use of multirate filter banks for coding of high quality digital audio" + // See notes about bugs in that paper in less-optimal implementation 'inverse_mdct_old' after this function. + + // kernel from paper + + + // merged: + // copy and reflect spectral data + // step 0 + + // note that it turns out that the items added together during + // this step are, in fact, being added to themselves (as reflected + // by step 0). inexplicable inefficiency! this became obvious + // once I combined the passes. + + // so there's a missing 'times 2' here (for adding X to itself). + // this propogates through linearly to the end, where the numbers + // are 1/2 too small, and need to be compensated for. + + { + float *d,*e, *AA, *e_stop; + d = &buf2[n2-2]; + AA = A; + e = &buffer[0]; + e_stop = &buffer[n2]; + while (e != e_stop) { + d[1] = (e[0] * AA[0] - e[2]*AA[1]); + d[0] = (e[0] * AA[1] + e[2]*AA[0]); + d -= 2; + AA += 2; + e += 4; + } + + e = &buffer[n2-3]; + while (d >= buf2) { + d[1] = (-e[2] * AA[0] - -e[0]*AA[1]); + d[0] = (-e[2] * AA[1] + -e[0]*AA[0]); + d -= 2; + AA += 2; + e -= 4; + } + } + + // now we use symbolic names for these, so that we can + // possibly swap their meaning as we change which operations + // are in place + + u = buffer; + v = buf2; + + // step 2 (paper output is w, now u) + // this could be in place, but the data ends up in the wrong + // place... _somebody_'s got to swap it, so this is nominated + { + float *AA = &A[n2-8]; + float *d0,*d1, *e0, *e1; + + e0 = &v[n4]; + e1 = &v[0]; + + d0 = &u[n4]; + d1 = &u[0]; + + while (AA >= A) { + float v40_20, v41_21; + + v41_21 = e0[1] - e1[1]; + v40_20 = e0[0] - e1[0]; + d0[1] = e0[1] + e1[1]; + d0[0] = e0[0] + e1[0]; + d1[1] = v41_21*AA[4] - v40_20*AA[5]; + d1[0] = v40_20*AA[4] + v41_21*AA[5]; + + v41_21 = e0[3] - e1[3]; + v40_20 = e0[2] - e1[2]; + d0[3] = e0[3] + e1[3]; + d0[2] = e0[2] + e1[2]; + d1[3] = v41_21*AA[0] - v40_20*AA[1]; + d1[2] = v40_20*AA[0] + v41_21*AA[1]; + + AA -= 8; + + d0 += 4; + d1 += 4; + e0 += 4; + e1 += 4; + } + } + + // step 3 + ld = ilog(n) - 1; // ilog is off-by-one from normal definitions + + // optimized step 3: + + // the original step3 loop can be nested r inside s or s inside r; + // it's written originally as s inside r, but this is dumb when r + // iterates many times, and s few. So I have two copies of it and + // switch between them halfway. + + // this is iteration 0 of step 3 + imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*0, -(n >> 3), A); + imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*1, -(n >> 3), A); + + // this is iteration 1 of step 3 + imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*0, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*1, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*2, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*3, -(n >> 4), A, 16); + + l=2; + for (; l < (ld-3)>>1; ++l) { + int k0 = n >> (l+2), k0_2 = k0>>1; + int lim = 1 << (l+1); + int i; + for (i=0; i < lim; ++i) + imdct_step3_inner_r_loop(n >> (l+4), u, n2-1 - k0*i, -k0_2, A, 1 << (l+3)); + } + + for (; l < ld-6; ++l) { + int k0 = n >> (l+2), k1 = 1 << (l+3), k0_2 = k0>>1; + int rlim = n >> (l+6), r; + int lim = 1 << (l+1); + int i_off; + float *A0 = A; + i_off = n2-1; + for (r=rlim; r > 0; --r) { + imdct_step3_inner_s_loop(lim, u, i_off, -k0_2, A0, k1, k0); + A0 += k1*4; + i_off -= 8; + } + } + + // iterations with count: + // ld-6,-5,-4 all interleaved together + // the big win comes from getting rid of needless flops + // due to the constants on pass 5 & 4 being all 1 and 0; + // combining them to be simultaneous to improve cache made little difference + imdct_step3_inner_s_loop_ld654(n >> 5, u, n2-1, A, n); + + // output is u + + // step 4, 5, and 6 + // cannot be in-place because of step 5 + { + uint16 *bitrev = f->bit_reverse[blocktype]; + // weirdly, I'd have thought reading sequentially and writing + // erratically would have been better than vice-versa, but in + // fact that's not what my testing showed. (That is, with + // j = bitreverse(i), do you read i and write j, or read j and write i.) + + float *d0 = &v[n4-4]; + float *d1 = &v[n2-4]; + while (d0 >= v) { + int k4; + + k4 = bitrev[0]; + d1[3] = u[k4+0]; + d1[2] = u[k4+1]; + d0[3] = u[k4+2]; + d0[2] = u[k4+3]; + + k4 = bitrev[1]; + d1[1] = u[k4+0]; + d1[0] = u[k4+1]; + d0[1] = u[k4+2]; + d0[0] = u[k4+3]; + + d0 -= 4; + d1 -= 4; + bitrev += 2; + } + } + // (paper output is u, now v) + + + // data must be in buf2 + assert(v == buf2); + + // step 7 (paper output is v, now v) + // this is now in place + { + float *C = f->C[blocktype]; + float *d, *e; + + d = v; + e = v + n2 - 4; + + while (d < e) { + float a02,a11,b0,b1,b2,b3; + + a02 = d[0] - e[2]; + a11 = d[1] + e[3]; + + b0 = C[1]*a02 + C[0]*a11; + b1 = C[1]*a11 - C[0]*a02; + + b2 = d[0] + e[ 2]; + b3 = d[1] - e[ 3]; + + d[0] = b2 + b0; + d[1] = b3 + b1; + e[2] = b2 - b0; + e[3] = b1 - b3; + + a02 = d[2] - e[0]; + a11 = d[3] + e[1]; + + b0 = C[3]*a02 + C[2]*a11; + b1 = C[3]*a11 - C[2]*a02; + + b2 = d[2] + e[ 0]; + b3 = d[3] - e[ 1]; + + d[2] = b2 + b0; + d[3] = b3 + b1; + e[0] = b2 - b0; + e[1] = b1 - b3; + + C += 4; + d += 4; + e -= 4; + } + } + + // data must be in buf2 + + + // step 8+decode (paper output is X, now buffer) + // this generates pairs of data a la 8 and pushes them directly through + // the decode kernel (pushing rather than pulling) to avoid having + // to make another pass later + + // this cannot POSSIBLY be in place, so we refer to the buffers directly + + { + float *d0,*d1,*d2,*d3; + + float *B = f->B[blocktype] + n2 - 8; + float *e = buf2 + n2 - 8; + d0 = &buffer[0]; + d1 = &buffer[n2-4]; + d2 = &buffer[n2]; + d3 = &buffer[n-4]; + while (e >= v) { + float p0,p1,p2,p3; + + p3 = e[6]*B[7] - e[7]*B[6]; + p2 = -e[6]*B[6] - e[7]*B[7]; + + d0[0] = p3; + d1[3] = - p3; + d2[0] = p2; + d3[3] = p2; + + p1 = e[4]*B[5] - e[5]*B[4]; + p0 = -e[4]*B[4] - e[5]*B[5]; + + d0[1] = p1; + d1[2] = - p1; + d2[1] = p0; + d3[2] = p0; + + p3 = e[2]*B[3] - e[3]*B[2]; + p2 = -e[2]*B[2] - e[3]*B[3]; + + d0[2] = p3; + d1[1] = - p3; + d2[2] = p2; + d3[1] = p2; + + p1 = e[0]*B[1] - e[1]*B[0]; + p0 = -e[0]*B[0] - e[1]*B[1]; + + d0[3] = p1; + d1[0] = - p1; + d2[3] = p0; + d3[0] = p0; + + B -= 8; + e -= 8; + d0 += 4; + d2 += 4; + d1 -= 4; + d3 -= 4; + } + } + + temp_alloc_restore(f,save_point); +} + +#if 0 +// this is the original version of the above code, if you want to optimize it from scratch +void inverse_mdct_naive(float *buffer, int n) +{ + float s; + float A[1 << 12], B[1 << 12], C[1 << 11]; + int i,k,k2,k4, n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l; + int n3_4 = n - n4, ld; + // how can they claim this only uses N words?! + // oh, because they're only used sparsely, whoops + float u[1 << 13], X[1 << 13], v[1 << 13], w[1 << 13]; + // set up twiddle factors + + for (k=k2=0; k < n4; ++k,k2+=2) { + A[k2 ] = (float) cos(4*k*M_PI/n); + A[k2+1] = (float) -sin(4*k*M_PI/n); + B[k2 ] = (float) cos((k2+1)*M_PI/n/2); + B[k2+1] = (float) sin((k2+1)*M_PI/n/2); + } + for (k=k2=0; k < n8; ++k,k2+=2) { + C[k2 ] = (float) cos(2*(k2+1)*M_PI/n); + C[k2+1] = (float) -sin(2*(k2+1)*M_PI/n); + } + + // IMDCT algorithm from "The use of multirate filter banks for coding of high quality digital audio" + // Note there are bugs in that pseudocode, presumably due to them attempting + // to rename the arrays nicely rather than representing the way their actual + // implementation bounces buffers back and forth. As a result, even in the + // "some formulars corrected" version, a direct implementation fails. These + // are noted below as "paper bug". + + // copy and reflect spectral data + for (k=0; k < n2; ++k) u[k] = buffer[k]; + for ( ; k < n ; ++k) u[k] = -buffer[n - k - 1]; + // kernel from paper + // step 1 + for (k=k2=k4=0; k < n4; k+=1, k2+=2, k4+=4) { + v[n-k4-1] = (u[k4] - u[n-k4-1]) * A[k2] - (u[k4+2] - u[n-k4-3])*A[k2+1]; + v[n-k4-3] = (u[k4] - u[n-k4-1]) * A[k2+1] + (u[k4+2] - u[n-k4-3])*A[k2]; + } + // step 2 + for (k=k4=0; k < n8; k+=1, k4+=4) { + w[n2+3+k4] = v[n2+3+k4] + v[k4+3]; + w[n2+1+k4] = v[n2+1+k4] + v[k4+1]; + w[k4+3] = (v[n2+3+k4] - v[k4+3])*A[n2-4-k4] - (v[n2+1+k4]-v[k4+1])*A[n2-3-k4]; + w[k4+1] = (v[n2+1+k4] - v[k4+1])*A[n2-4-k4] + (v[n2+3+k4]-v[k4+3])*A[n2-3-k4]; + } + // step 3 + ld = ilog(n) - 1; // ilog is off-by-one from normal definitions + for (l=0; l < ld-3; ++l) { + int k0 = n >> (l+2), k1 = 1 << (l+3); + int rlim = n >> (l+4), r4, r; + int s2lim = 1 << (l+2), s2; + for (r=r4=0; r < rlim; r4+=4,++r) { + for (s2=0; s2 < s2lim; s2+=2) { + u[n-1-k0*s2-r4] = w[n-1-k0*s2-r4] + w[n-1-k0*(s2+1)-r4]; + u[n-3-k0*s2-r4] = w[n-3-k0*s2-r4] + w[n-3-k0*(s2+1)-r4]; + u[n-1-k0*(s2+1)-r4] = (w[n-1-k0*s2-r4] - w[n-1-k0*(s2+1)-r4]) * A[r*k1] + - (w[n-3-k0*s2-r4] - w[n-3-k0*(s2+1)-r4]) * A[r*k1+1]; + u[n-3-k0*(s2+1)-r4] = (w[n-3-k0*s2-r4] - w[n-3-k0*(s2+1)-r4]) * A[r*k1] + + (w[n-1-k0*s2-r4] - w[n-1-k0*(s2+1)-r4]) * A[r*k1+1]; + } + } + if (l+1 < ld-3) { + // paper bug: ping-ponging of u&w here is omitted + memcpy(w, u, sizeof(u)); + } + } + + // step 4 + for (i=0; i < n8; ++i) { + int j = bit_reverse(i) >> (32-ld+3); + assert(j < n8); + if (i == j) { + // paper bug: original code probably swapped in place; if copying, + // need to directly copy in this case + int i8 = i << 3; + v[i8+1] = u[i8+1]; + v[i8+3] = u[i8+3]; + v[i8+5] = u[i8+5]; + v[i8+7] = u[i8+7]; + } else if (i < j) { + int i8 = i << 3, j8 = j << 3; + v[j8+1] = u[i8+1], v[i8+1] = u[j8 + 1]; + v[j8+3] = u[i8+3], v[i8+3] = u[j8 + 3]; + v[j8+5] = u[i8+5], v[i8+5] = u[j8 + 5]; + v[j8+7] = u[i8+7], v[i8+7] = u[j8 + 7]; + } + } + // step 5 + for (k=0; k < n2; ++k) { + w[k] = v[k*2+1]; + } + // step 6 + for (k=k2=k4=0; k < n8; ++k, k2 += 2, k4 += 4) { + u[n-1-k2] = w[k4]; + u[n-2-k2] = w[k4+1]; + u[n3_4 - 1 - k2] = w[k4+2]; + u[n3_4 - 2 - k2] = w[k4+3]; + } + // step 7 + for (k=k2=0; k < n8; ++k, k2 += 2) { + v[n2 + k2 ] = ( u[n2 + k2] + u[n-2-k2] + C[k2+1]*(u[n2+k2]-u[n-2-k2]) + C[k2]*(u[n2+k2+1]+u[n-2-k2+1]))/2; + v[n-2 - k2] = ( u[n2 + k2] + u[n-2-k2] - C[k2+1]*(u[n2+k2]-u[n-2-k2]) - C[k2]*(u[n2+k2+1]+u[n-2-k2+1]))/2; + v[n2+1+ k2] = ( u[n2+1+k2] - u[n-1-k2] + C[k2+1]*(u[n2+1+k2]+u[n-1-k2]) - C[k2]*(u[n2+k2]-u[n-2-k2]))/2; + v[n-1 - k2] = (-u[n2+1+k2] + u[n-1-k2] + C[k2+1]*(u[n2+1+k2]+u[n-1-k2]) - C[k2]*(u[n2+k2]-u[n-2-k2]))/2; + } + // step 8 + for (k=k2=0; k < n4; ++k,k2 += 2) { + X[k] = v[k2+n2]*B[k2 ] + v[k2+1+n2]*B[k2+1]; + X[n2-1-k] = v[k2+n2]*B[k2+1] - v[k2+1+n2]*B[k2 ]; + } + + // decode kernel to output + // determined the following value experimentally + // (by first figuring out what made inverse_mdct_slow work); then matching that here + // (probably vorbis encoder premultiplies by n or n/2, to save it on the decoder?) + s = 0.5; // theoretically would be n4 + + // [[[ note! the s value of 0.5 is compensated for by the B[] in the current code, + // so it needs to use the "old" B values to behave correctly, or else + // set s to 1.0 ]]] + for (i=0; i < n4 ; ++i) buffer[i] = s * X[i+n4]; + for ( ; i < n3_4; ++i) buffer[i] = -s * X[n3_4 - i - 1]; + for ( ; i < n ; ++i) buffer[i] = -s * X[i - n3_4]; +} +#endif + +static float *get_window(vorb *f, int len) +{ + len <<= 1; + if (len == f->blocksize_0) return f->window[0]; + if (len == f->blocksize_1) return f->window[1]; + assert(0); + return NULL; +} + +#ifndef STB_VORBIS_NO_DEFER_FLOOR +typedef int16 YTYPE; +#else +typedef int YTYPE; +#endif +static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *finalY, uint8 *step2_flag) +{ + int n2 = n >> 1; + int s = map->chan[i].mux, floor; + floor = map->submap_floor[s]; + if (f->floor_types[floor] == 0) { + return error(f, VORBIS_invalid_stream); + } else { + Floor1 *g = &f->floor_config[floor].floor1; + int j,q; + int lx = 0, ly = finalY[0] * g->floor1_multiplier; + for (q=1; q < g->values; ++q) { + j = g->sorted_order[q]; + #ifndef STB_VORBIS_NO_DEFER_FLOOR + if (finalY[j] >= 0) + #else + if (step2_flag[j]) + #endif + { + int hy = finalY[j] * g->floor1_multiplier; + int hx = g->Xlist[j]; + draw_line(target, lx,ly, hx,hy, n2); + lx = hx, ly = hy; + } + } + if (lx < n2) + // optimization of: draw_line(target, lx,ly, n,ly, n2); + for (j=lx; j < n2; ++j) + LINE_OP(target[j], inverse_db_table[ly]); + } + return TRUE; +} + +static int vorbis_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) +{ + Mode *m; + int i, n, prev, next, window_center; + f->channel_buffer_start = f->channel_buffer_end = 0; + + retry: + if (f->eof) return FALSE; + if (!maybe_start_packet(f)) + return FALSE; + // check packet type + if (get_bits(f,1) != 0) { + if (IS_PUSH_MODE(f)) + return error(f,VORBIS_bad_packet_type); + while (EOP != get8_packet(f)); + goto retry; + } + + if (f->alloc.alloc_buffer) + assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); + + i = get_bits(f, ilog(f->mode_count-1)); + if (i == EOP) return FALSE; + if (i >= f->mode_count) return FALSE; + *mode = i; + m = f->mode_config + i; + if (m->blockflag) { + n = f->blocksize_1; + prev = get_bits(f,1); + next = get_bits(f,1); + } else { + prev = next = 0; + n = f->blocksize_0; + } + +// WINDOWING + + window_center = n >> 1; + if (m->blockflag && !prev) { + *p_left_start = (n - f->blocksize_0) >> 2; + *p_left_end = (n + f->blocksize_0) >> 2; + } else { + *p_left_start = 0; + *p_left_end = window_center; + } + if (m->blockflag && !next) { + *p_right_start = (n*3 - f->blocksize_0) >> 2; + *p_right_end = (n*3 + f->blocksize_0) >> 2; + } else { + *p_right_start = window_center; + *p_right_end = n; + } + return TRUE; +} + +static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, int left_end, int right_start, int right_end, int *p_left) +{ + Mapping *map; + int i,j,k,n,n2; + int zero_channel[256]; + int really_zero_channel[256]; + int window_center; + +// WINDOWING + + n = f->blocksize[m->blockflag]; + window_center = n >> 1; + + map = &f->mapping[m->mapping]; + +// FLOORS + n2 = n >> 1; + + stb_prof(1); + for (i=0; i < f->channels; ++i) { + int s = map->chan[i].mux, floor; + zero_channel[i] = FALSE; + floor = map->submap_floor[s]; + if (f->floor_types[floor] == 0) { + return error(f, VORBIS_invalid_stream); + } else { + Floor1 *g = &f->floor_config[floor].floor1; + if (get_bits(f, 1)) { + short *finalY; + uint8 step2_flag[256]; + static int range_list[4] = { 256, 128, 86, 64 }; + int range = range_list[g->floor1_multiplier-1]; + int offset = 2; + finalY = f->finalY[i]; + finalY[0] = get_bits(f, ilog(range)-1); + finalY[1] = get_bits(f, ilog(range)-1); + for (j=0; j < g->partitions; ++j) { + int pclass = g->partition_class_list[j]; + int cdim = g->class_dimensions[pclass]; + int cbits = g->class_subclasses[pclass]; + int csub = (1 << cbits)-1; + int cval = 0; + if (cbits) { + Codebook *c = f->codebooks + g->class_masterbooks[pclass]; + DECODE(cval,f,c); + } + for (k=0; k < cdim; ++k) { + int book = g->subclass_books[pclass][cval & csub]; + cval = cval >> cbits; + if (book >= 0) { + int temp; + Codebook *c = f->codebooks + book; + DECODE(temp,f,c); + finalY[offset++] = temp; + } else + finalY[offset++] = 0; + } + } + if (f->valid_bits == INVALID_BITS) goto error; // behavior according to spec + step2_flag[0] = step2_flag[1] = 1; + for (j=2; j < g->values; ++j) { + int low, high, pred, highroom, lowroom, room, val; + low = g->neighbors[j][0]; + high = g->neighbors[j][1]; + //neighbors(g->Xlist, j, &low, &high); + pred = predict_point(g->Xlist[j], g->Xlist[low], g->Xlist[high], finalY[low], finalY[high]); + val = finalY[j]; + highroom = range - pred; + lowroom = pred; + if (highroom < lowroom) + room = highroom * 2; + else + room = lowroom * 2; + if (val) { + step2_flag[low] = step2_flag[high] = 1; + step2_flag[j] = 1; + if (val >= room) + if (highroom > lowroom) + finalY[j] = val - lowroom + pred; + else + finalY[j] = pred - val + highroom - 1; + else + if (val & 1) + finalY[j] = pred - ((val+1)>>1); + else + finalY[j] = pred + (val>>1); + } else { + step2_flag[j] = 0; + finalY[j] = pred; + } + } + +#ifdef STB_VORBIS_NO_DEFER_FLOOR + do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag); +#else + // defer final floor computation until _after_ residue + for (j=0; j < g->values; ++j) { + if (!step2_flag[j]) + finalY[j] = -1; + } +#endif + } else { + error: + zero_channel[i] = TRUE; + } + // So we just defer everything else to later + + // at this point we've decoded the floor into buffer + } + } + stb_prof(0); + // at this point we've decoded all floors + + if (f->alloc.alloc_buffer) + assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); + + // re-enable coupled channels if necessary + memcpy(really_zero_channel, zero_channel, sizeof(really_zero_channel[0]) * f->channels); + for (i=0; i < map->coupling_steps; ++i) + if (!zero_channel[map->chan[i].magnitude] || !zero_channel[map->chan[i].angle]) { + zero_channel[map->chan[i].magnitude] = zero_channel[map->chan[i].angle] = FALSE; + } + +// RESIDUE DECODE + for (i=0; i < map->submaps; ++i) { + float *residue_buffers[STB_VORBIS_MAX_CHANNELS]; + int r,t; + uint8 do_not_decode[256]; + int ch = 0; + for (j=0; j < f->channels; ++j) { + if (map->chan[j].mux == i) { + if (zero_channel[j]) { + do_not_decode[ch] = TRUE; + residue_buffers[ch] = NULL; + } else { + do_not_decode[ch] = FALSE; + residue_buffers[ch] = f->channel_buffers[j]; + } + ++ch; + } + } + r = map->submap_residue[i]; + t = f->residue_types[r]; + decode_residue(f, residue_buffers, ch, n2, r, do_not_decode); + } + + if (f->alloc.alloc_buffer) + assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); + +// INVERSE COUPLING + stb_prof(14); + for (i = map->coupling_steps-1; i >= 0; --i) { + int n2 = n >> 1; + float *m = f->channel_buffers[map->chan[i].magnitude]; + float *a = f->channel_buffers[map->chan[i].angle ]; + for (j=0; j < n2; ++j) { + float a2,m2; + if (m[j] > 0) + if (a[j] > 0) + m2 = m[j], a2 = m[j] - a[j]; + else + a2 = m[j], m2 = m[j] + a[j]; + else + if (a[j] > 0) + m2 = m[j], a2 = m[j] + a[j]; + else + a2 = m[j], m2 = m[j] - a[j]; + m[j] = m2; + a[j] = a2; + } + } + + // finish decoding the floors +#ifndef STB_VORBIS_NO_DEFER_FLOOR + stb_prof(15); + for (i=0; i < f->channels; ++i) { + if (really_zero_channel[i]) { + memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2); + } else { + do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], NULL); + } + } +#else + for (i=0; i < f->channels; ++i) { + if (really_zero_channel[i]) { + memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2); + } else { + for (j=0; j < n2; ++j) + f->channel_buffers[i][j] *= f->floor_buffers[i][j]; + } + } +#endif + +// INVERSE MDCT + stb_prof(16); + for (i=0; i < f->channels; ++i) + inverse_mdct(f->channel_buffers[i], n, f, m->blockflag); + stb_prof(0); + + // this shouldn't be necessary, unless we exited on an error + // and want to flush to get to the next packet + flush_packet(f); + + if (f->first_decode) { + // assume we start so first non-discarded sample is sample 0 + // this isn't to spec, but spec would require us to read ahead + // and decode the size of all current frames--could be done, + // but presumably it's not a commonly used feature + f->current_loc = -n2; // start of first frame is positioned for discard + // we might have to discard samples "from" the next frame too, + // if we're lapping a large block then a small at the start? + f->discard_samples_deferred = n - right_end; + f->current_loc_valid = TRUE; + f->first_decode = FALSE; + } else if (f->discard_samples_deferred) { + left_start += f->discard_samples_deferred; + *p_left = left_start; + f->discard_samples_deferred = 0; + } else if (f->previous_length == 0 && f->current_loc_valid) { + // we're recovering from a seek... that means we're going to discard + // the samples from this packet even though we know our position from + // the last page header, so we need to update the position based on + // the discarded samples here + // but wait, the code below is going to add this in itself even + // on a discard, so we don't need to do it here... + } + + // check if we have ogg information about the sample # for this packet + if (f->last_seg_which == f->end_seg_with_known_loc) { + // if we have a valid current loc, and this is final: + if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) { + uint32 current_end = f->known_loc_for_packet - (n-right_end); + // then let's infer the size of the (probably) short final frame + if (current_end < f->current_loc + right_end) { + if (current_end < f->current_loc) { + // negative truncation, that's impossible! + *len = 0; + } else { + *len = current_end - f->current_loc; + } + *len += left_start; + f->current_loc += *len; + return TRUE; + } + } + // otherwise, just set our sample loc + // guess that the ogg granule pos refers to the _middle_ of the + // last frame? + // set f->current_loc to the position of left_start + f->current_loc = f->known_loc_for_packet - (n2-left_start); + f->current_loc_valid = TRUE; + } + if (f->current_loc_valid) + f->current_loc += (right_start - left_start); + + if (f->alloc.alloc_buffer) + assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); + *len = right_end; // ignore samples after the window goes to 0 + return TRUE; +} + +static int vorbis_decode_packet(vorb *f, int *len, int *p_left, int *p_right) +{ + int mode, left_end, right_end; + if (!vorbis_decode_initial(f, p_left, &left_end, p_right, &right_end, &mode)) return 0; + return vorbis_decode_packet_rest(f, len, f->mode_config + mode, *p_left, left_end, *p_right, right_end, p_left); +} + +static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) +{ + int prev,i,j; + // we use right&left (the start of the right- and left-window sin()-regions) + // to determine how much to return, rather than inferring from the rules + // (same result, clearer code); 'left' indicates where our sin() window + // starts, therefore where the previous window's right edge starts, and + // therefore where to start mixing from the previous buffer. 'right' + // indicates where our sin() ending-window starts, therefore that's where + // we start saving, and where our returned-data ends. + + // mixin from previous window + if (f->previous_length) { + int i,j, n = f->previous_length; + float *w = get_window(f, n); + for (i=0; i < f->channels; ++i) { + for (j=0; j < n; ++j) + f->channel_buffers[i][left+j] = + f->channel_buffers[i][left+j]*w[ j] + + f->previous_window[i][ j]*w[n-1-j]; + } + } + + prev = f->previous_length; + + // last half of this data becomes previous window + f->previous_length = len - right; + + // @OPTIMIZE: could avoid this copy by double-buffering the + // output (flipping previous_window with channel_buffers), but + // then previous_window would have to be 2x as large, and + // channel_buffers couldn't be temp mem (although they're NOT + // currently temp mem, they could be (unless we want to level + // performance by spreading out the computation)) + for (i=0; i < f->channels; ++i) + for (j=0; right+j < len; ++j) + f->previous_window[i][j] = f->channel_buffers[i][right+j]; + + if (!prev) + // there was no previous packet, so this data isn't valid... + // this isn't entirely true, only the would-have-overlapped data + // isn't valid, but this seems to be what the spec requires + return 0; + + // truncate a short frame + if (len < right) right = len; + + f->samples_output += right-left; + + return right - left; +} + +static void vorbis_pump_first_frame(stb_vorbis *f) +{ + int len, right, left; + if (vorbis_decode_packet(f, &len, &left, &right)) + vorbis_finish_frame(f, len, left, right); +} + +#ifndef STB_VORBIS_NO_PUSHDATA_API +static int is_whole_packet_present(stb_vorbis *f, int end_page) +{ + // make sure that we have the packet available before continuing... + // this requires a full ogg parse, but we know we can fetch from f->stream + + // instead of coding this out explicitly, we could save the current read state, + // read the next packet with get8() until end-of-packet, check f->eof, then + // reset the state? but that would be slower, esp. since we'd have over 256 bytes + // of state to restore (primarily the page segment table) + + int s = f->next_seg, first = TRUE; + uint8 *p = f->stream; + + if (s != -1) { // if we're not starting the packet with a 'continue on next page' flag + for (; s < f->segment_count; ++s) { + p += f->segments[s]; + if (f->segments[s] < 255) // stop at first short segment + break; + } + // either this continues, or it ends it... + if (end_page) + if (s < f->segment_count-1) return error(f, VORBIS_invalid_stream); + if (s == f->segment_count) + s = -1; // set 'crosses page' flag + if (p > f->stream_end) return error(f, VORBIS_need_more_data); + first = FALSE; + } + for (; s == -1;) { + uint8 *q; + int n; + + // check that we have the page header ready + if (p + 26 >= f->stream_end) return error(f, VORBIS_need_more_data); + // validate the page + if (memcmp(p, ogg_page_header, 4)) return error(f, VORBIS_invalid_stream); + if (p[4] != 0) return error(f, VORBIS_invalid_stream); + if (first) { // the first segment must NOT have 'continued_packet', later ones MUST + if (f->previous_length) + if ((p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream); + // if no previous length, we're resynching, so we can come in on a continued-packet, + // which we'll just drop + } else { + if (!(p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream); + } + n = p[26]; // segment counts + q = p+27; // q points to segment table + p = q + n; // advance past header + // make sure we've read the segment table + if (p > f->stream_end) return error(f, VORBIS_need_more_data); + for (s=0; s < n; ++s) { + p += q[s]; + if (q[s] < 255) + break; + } + if (end_page) + if (s < n-1) return error(f, VORBIS_invalid_stream); + if (s == f->segment_count) + s = -1; // set 'crosses page' flag + if (p > f->stream_end) return error(f, VORBIS_need_more_data); + first = FALSE; + } + return TRUE; +} +#endif // !STB_VORBIS_NO_PUSHDATA_API + +static int start_decoder(vorb *f) +{ + uint8 header[6], x,y; + int len,i,j,k, max_submaps = 0; + int longest_floorlist=0; + + // first page, first packet + + if (!start_page(f)) return FALSE; + // validate page flag + if (!(f->page_flag & PAGEFLAG_first_page)) return error(f, VORBIS_invalid_first_page); + if (f->page_flag & PAGEFLAG_last_page) return error(f, VORBIS_invalid_first_page); + if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page); + // check for expected packet length + if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page); + if (f->segments[0] != 30) return error(f, VORBIS_invalid_first_page); + // read packet + // check packet header + if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page); + if (!getn(f, header, 6)) return error(f, VORBIS_unexpected_eof); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_first_page); + // vorbis_version + if (get32(f) != 0) return error(f, VORBIS_invalid_first_page); + f->channels = get8(f); if (!f->channels) return error(f, VORBIS_invalid_first_page); + if (f->channels > STB_VORBIS_MAX_CHANNELS) return error(f, VORBIS_too_many_channels); + f->sample_rate = get32(f); if (!f->sample_rate) return error(f, VORBIS_invalid_first_page); + get32(f); // bitrate_maximum + get32(f); // bitrate_nominal + get32(f); // bitrate_minimum + x = get8(f); + { int log0,log1; + log0 = x & 15; + log1 = x >> 4; + f->blocksize_0 = 1 << log0; + f->blocksize_1 = 1 << log1; + if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup); + if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup); + if (log0 > log1) return error(f, VORBIS_invalid_setup); + } + + // framing_flag + x = get8(f); + if (!(x & 1)) return error(f, VORBIS_invalid_first_page); + + // second packet! + if (!start_page(f)) return FALSE; + + if (!start_packet(f)) return FALSE; + do { + len = next_segment(f); + skip(f, len); + f->bytes_in_seg = 0; + } while (len); + + // third packet! + if (!start_packet(f)) return FALSE; + + #ifndef STB_VORBIS_NO_PUSHDATA_API + if (IS_PUSH_MODE(f)) { + if (!is_whole_packet_present(f, TRUE)) { + // convert error in ogg header to write type + if (f->error == VORBIS_invalid_stream) + f->error = VORBIS_invalid_setup; + return FALSE; + } + } + #endif + + crc32_init(); // always init it, to avoid multithread race conditions + + if (get8_packet(f) != VORBIS_packet_setup) return error(f, VORBIS_invalid_setup); + for (i=0; i < 6; ++i) header[i] = get8_packet(f); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); + + // codebooks + + f->codebook_count = get_bits(f,8) + 1; + f->codebooks = (Codebook *) setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count); + if (f->codebooks == NULL) return error(f, VORBIS_outofmem); + memset(f->codebooks, 0, sizeof(*f->codebooks) * f->codebook_count); + for (i=0; i < f->codebook_count; ++i) { + uint32 *values; + int ordered, sorted_count; + int total=0; + uint8 *lengths; + Codebook *c = f->codebooks+i; + x = get_bits(f, 8); if (x != 0x42) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); if (x != 0x43) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); if (x != 0x56) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); + c->dimensions = (get_bits(f, 8)<<8) + x; + x = get_bits(f, 8); + y = get_bits(f, 8); + c->entries = (get_bits(f, 8)<<16) + (y<<8) + x; + ordered = get_bits(f,1); + c->sparse = ordered ? 0 : get_bits(f,1); + + if (c->sparse) + lengths = (uint8 *) setup_temp_malloc(f, c->entries); + else + lengths = c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries); + + if (!lengths) return error(f, VORBIS_outofmem); + + if (ordered) { + int current_entry = 0; + int current_length = get_bits(f,5) + 1; + while (current_entry < c->entries) { + int limit = c->entries - current_entry; + int n = get_bits(f, ilog(limit)); + if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); } + memset(lengths + current_entry, current_length, n); + current_entry += n; + ++current_length; + } + } else { + for (j=0; j < c->entries; ++j) { + int present = c->sparse ? get_bits(f,1) : 1; + if (present) { + lengths[j] = get_bits(f, 5) + 1; + ++total; + } else { + lengths[j] = NO_CODE; + } + } + } + + if (c->sparse && total >= c->entries >> 2) { + // convert sparse items to non-sparse! + if (c->entries > (int) f->setup_temp_memory_required) + f->setup_temp_memory_required = c->entries; + + c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries); + memcpy(c->codeword_lengths, lengths, c->entries); + setup_temp_free(f, lengths, c->entries); // note this is only safe if there have been no intervening temp mallocs! + lengths = c->codeword_lengths; + c->sparse = 0; + } + + // compute the size of the sorted tables + if (c->sparse) { + sorted_count = total; + //assert(total != 0); + } else { + sorted_count = 0; + #ifndef STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH + for (j=0; j < c->entries; ++j) + if (lengths[j] > STB_VORBIS_FAST_HUFFMAN_LENGTH && lengths[j] != NO_CODE) + ++sorted_count; + #endif + } + + c->sorted_entries = sorted_count; + values = NULL; + + if (!c->sparse) { + c->codewords = (uint32 *) setup_malloc(f, sizeof(c->codewords[0]) * c->entries); + if (!c->codewords) return error(f, VORBIS_outofmem); + } else { + unsigned int size; + if (c->sorted_entries) { + c->codeword_lengths = (uint8 *) setup_malloc(f, c->sorted_entries); + if (!c->codeword_lengths) return error(f, VORBIS_outofmem); + c->codewords = (uint32 *) setup_temp_malloc(f, sizeof(*c->codewords) * c->sorted_entries); + if (!c->codewords) return error(f, VORBIS_outofmem); + values = (uint32 *) setup_temp_malloc(f, sizeof(*values) * c->sorted_entries); + if (!values) return error(f, VORBIS_outofmem); + } + size = c->entries + (sizeof(*c->codewords) + sizeof(*values)) * c->sorted_entries; + if (size > f->setup_temp_memory_required) + f->setup_temp_memory_required = size; + } + + if (!compute_codewords(c, lengths, c->entries, values)) { + if (c->sparse) setup_temp_free(f, values, 0); + return error(f, VORBIS_invalid_setup); + } + + if (c->sorted_entries) { + // allocate an extra slot for sentinels + c->sorted_codewords = (uint32 *) setup_malloc(f, sizeof(*c->sorted_codewords) * (c->sorted_entries+1)); + // allocate an extra slot at the front so that c->sorted_values[-1] is defined + // so that we can catch that case without an extra if + c->sorted_values = ( int *) setup_malloc(f, sizeof(*c->sorted_values ) * (c->sorted_entries+1)); + if (c->sorted_values) { ++c->sorted_values; c->sorted_values[-1] = -1; } + compute_sorted_huffman(c, lengths, values); + } + + if (c->sparse) { + setup_temp_free(f, values, sizeof(*values)*c->sorted_entries); + setup_temp_free(f, c->codewords, sizeof(*c->codewords)*c->sorted_entries); + setup_temp_free(f, lengths, c->entries); + c->codewords = NULL; + } + + compute_accelerated_huffman(c); + + c->lookup_type = get_bits(f, 4); + if (c->lookup_type > 2) return error(f, VORBIS_invalid_setup); + if (c->lookup_type > 0) { + uint16 *mults; + c->minimum_value = float32_unpack(get_bits(f, 32)); + c->delta_value = float32_unpack(get_bits(f, 32)); + c->value_bits = get_bits(f, 4)+1; + c->sequence_p = get_bits(f,1); + if (c->lookup_type == 1) { + c->lookup_values = lookup1_values(c->entries, c->dimensions); + } else { + c->lookup_values = c->entries * c->dimensions; + } + mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values); + if (mults == NULL) return error(f, VORBIS_outofmem); + for (j=0; j < (int) c->lookup_values; ++j) { + int q = get_bits(f, c->value_bits); + if (q == EOP) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_invalid_setup); } + mults[j] = q; + } + +#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK + if (c->lookup_type == 1) { + int len, sparse = c->sparse; + // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop + if (sparse) { + if (c->sorted_entries == 0) goto skip; + c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions); + } else + c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries * c->dimensions); + if (c->multiplicands == NULL) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } + len = sparse ? c->sorted_entries : c->entries; + for (j=0; j < len; ++j) { + int z = sparse ? c->sorted_values[j] : j, div=1; + for (k=0; k < c->dimensions; ++k) { + int off = (z / div) % c->lookup_values; + c->multiplicands[j*c->dimensions + k] = + #ifndef STB_VORBIS_CODEBOOK_FLOATS + mults[off]; + #else + mults[off]*c->delta_value + c->minimum_value; + // in this case (and this case only) we could pre-expand c->sequence_p, + // and throw away the decode logic for it; have to ALSO do + // it in the case below, but it can only be done if + // STB_VORBIS_CODEBOOK_FLOATS + // !STB_VORBIS_DIVIDES_IN_CODEBOOK + #endif + div *= c->lookup_values; + } + } + setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); + c->lookup_type = 2; + } + else +#endif + { + c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values); + #ifndef STB_VORBIS_CODEBOOK_FLOATS + memcpy(c->multiplicands, mults, sizeof(c->multiplicands[0]) * c->lookup_values); + #else + for (j=0; j < (int) c->lookup_values; ++j) + c->multiplicands[j] = mults[j] * c->delta_value + c->minimum_value; + setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); + #endif + } + skip:; + + #ifdef STB_VORBIS_CODEBOOK_FLOATS + if (c->lookup_type == 2 && c->sequence_p) { + for (j=1; j < (int) c->lookup_values; ++j) + c->multiplicands[j] = c->multiplicands[j-1]; + c->sequence_p = 0; + } + #endif + } + } + + // time domain transfers (notused) + + x = get_bits(f, 6) + 1; + for (i=0; i < x; ++i) { + uint32 z = get_bits(f, 16); + if (z != 0) return error(f, VORBIS_invalid_setup); + } + + // Floors + f->floor_count = get_bits(f, 6)+1; + f->floor_config = (Floor *) setup_malloc(f, f->floor_count * sizeof(*f->floor_config)); + for (i=0; i < f->floor_count; ++i) { + f->floor_types[i] = get_bits(f, 16); + if (f->floor_types[i] > 1) return error(f, VORBIS_invalid_setup); + if (f->floor_types[i] == 0) { + Floor0 *g = &f->floor_config[i].floor0; + g->order = get_bits(f,8); + g->rate = get_bits(f,16); + g->bark_map_size = get_bits(f,16); + g->amplitude_bits = get_bits(f,6); + g->amplitude_offset = get_bits(f,8); + g->number_of_books = get_bits(f,4) + 1; + for (j=0; j < g->number_of_books; ++j) + g->book_list[j] = get_bits(f,8); + return error(f, VORBIS_feature_not_supported); + } else { + Point p[31*8+2]; + Floor1 *g = &f->floor_config[i].floor1; + int max_class = -1; + g->partitions = get_bits(f, 5); + for (j=0; j < g->partitions; ++j) { + g->partition_class_list[j] = get_bits(f, 4); + if (g->partition_class_list[j] > max_class) + max_class = g->partition_class_list[j]; + } + for (j=0; j <= max_class; ++j) { + g->class_dimensions[j] = get_bits(f, 3)+1; + g->class_subclasses[j] = get_bits(f, 2); + if (g->class_subclasses[j]) { + g->class_masterbooks[j] = get_bits(f, 8); + if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup); + } + for (k=0; k < 1 << g->class_subclasses[j]; ++k) { + g->subclass_books[j][k] = get_bits(f,8)-1; + if (g->subclass_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); + } + } + g->floor1_multiplier = get_bits(f,2)+1; + g->rangebits = get_bits(f,4); + g->Xlist[0] = 0; + g->Xlist[1] = 1 << g->rangebits; + g->values = 2; + for (j=0; j < g->partitions; ++j) { + int c = g->partition_class_list[j]; + for (k=0; k < g->class_dimensions[c]; ++k) { + g->Xlist[g->values] = get_bits(f, g->rangebits); + ++g->values; + } + } + // precompute the sorting + for (j=0; j < g->values; ++j) { + p[j].x = g->Xlist[j]; + p[j].y = j; + } + qsort(p, g->values, sizeof(p[0]), point_compare); + for (j=0; j < g->values; ++j) + g->sorted_order[j] = (uint8) p[j].y; + // precompute the neighbors + for (j=2; j < g->values; ++j) { + int low,hi; + neighbors(g->Xlist, j, &low,&hi); + g->neighbors[j][0] = low; + g->neighbors[j][1] = hi; + } + + if (g->values > longest_floorlist) + longest_floorlist = g->values; + } + } + + // Residue + f->residue_count = get_bits(f, 6)+1; + f->residue_config = (Residue *) setup_malloc(f, f->residue_count * sizeof(*f->residue_config)); + for (i=0; i < f->residue_count; ++i) { + uint8 residue_cascade[64]; + Residue *r = f->residue_config+i; + f->residue_types[i] = get_bits(f, 16); + if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup); + r->begin = get_bits(f, 24); + r->end = get_bits(f, 24); + r->part_size = get_bits(f,24)+1; + r->classifications = get_bits(f,6)+1; + r->classbook = get_bits(f,8); + for (j=0; j < r->classifications; ++j) { + uint8 high_bits=0; + uint8 low_bits=get_bits(f,3); + if (get_bits(f,1)) + high_bits = get_bits(f,5); + residue_cascade[j] = high_bits*8 + low_bits; + } + r->residue_books = (short (*)[8]) setup_malloc(f, sizeof(r->residue_books[0]) * r->classifications); + for (j=0; j < r->classifications; ++j) { + for (k=0; k < 8; ++k) { + if (residue_cascade[j] & (1 << k)) { + r->residue_books[j][k] = get_bits(f, 8); + if (r->residue_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); + } else { + r->residue_books[j][k] = -1; + } + } + } + // precompute the classifications[] array to avoid inner-loop mod/divide + // call it 'classdata' since we already have r->classifications + r->classdata = (uint8 **) setup_malloc(f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); + if (!r->classdata) return error(f, VORBIS_outofmem); + memset(r->classdata, 0, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); + for (j=0; j < f->codebooks[r->classbook].entries; ++j) { + int classwords = f->codebooks[r->classbook].dimensions; + int temp = j; + r->classdata[j] = (uint8 *) setup_malloc(f, sizeof(r->classdata[j][0]) * classwords); + for (k=classwords-1; k >= 0; --k) { + r->classdata[j][k] = temp % r->classifications; + temp /= r->classifications; + } + } + } + + f->mapping_count = get_bits(f,6)+1; + f->mapping = (Mapping *) setup_malloc(f, f->mapping_count * sizeof(*f->mapping)); + for (i=0; i < f->mapping_count; ++i) { + Mapping *m = f->mapping + i; + int mapping_type = get_bits(f,16); + if (mapping_type != 0) return error(f, VORBIS_invalid_setup); + m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan)); + if (get_bits(f,1)) + m->submaps = get_bits(f,4); + else + m->submaps = 1; + if (m->submaps > max_submaps) + max_submaps = m->submaps; + if (get_bits(f,1)) { + m->coupling_steps = get_bits(f,8)+1; + for (k=0; k < m->coupling_steps; ++k) { + m->chan[k].magnitude = get_bits(f, ilog(f->channels)-1); + m->chan[k].angle = get_bits(f, ilog(f->channels)-1); + if (m->chan[k].magnitude >= f->channels) return error(f, VORBIS_invalid_setup); + if (m->chan[k].angle >= f->channels) return error(f, VORBIS_invalid_setup); + if (m->chan[k].magnitude == m->chan[k].angle) return error(f, VORBIS_invalid_setup); + } + } else + m->coupling_steps = 0; + + // reserved field + if (get_bits(f,2)) return error(f, VORBIS_invalid_setup); + if (m->submaps > 1) { + for (j=0; j < f->channels; ++j) { + m->chan[j].mux = get_bits(f, 4); + if (m->chan[j].mux >= m->submaps) return error(f, VORBIS_invalid_setup); + } + } else + // @SPECIFICATION: this case is missing from the spec + for (j=0; j < f->channels; ++j) + m->chan[j].mux = 0; + + for (j=0; j < m->submaps; ++j) { + get_bits(f,8); // discard + m->submap_floor[j] = get_bits(f,8); + m->submap_residue[j] = get_bits(f,8); + if (m->submap_floor[j] >= f->floor_count) return error(f, VORBIS_invalid_setup); + if (m->submap_residue[j] >= f->residue_count) return error(f, VORBIS_invalid_setup); + } + } + + // Modes + f->mode_count = get_bits(f, 6)+1; + for (i=0; i < f->mode_count; ++i) { + Mode *m = f->mode_config+i; + m->blockflag = get_bits(f,1); + m->windowtype = get_bits(f,16); + m->transformtype = get_bits(f,16); + m->mapping = get_bits(f,8); + if (m->windowtype != 0) return error(f, VORBIS_invalid_setup); + if (m->transformtype != 0) return error(f, VORBIS_invalid_setup); + if (m->mapping >= f->mapping_count) return error(f, VORBIS_invalid_setup); + } + + flush_packet(f); + + f->previous_length = 0; + + for (i=0; i < f->channels; ++i) { + f->channel_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1); + f->previous_window[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); + f->finalY[i] = (int16 *) setup_malloc(f, sizeof(int16) * longest_floorlist); + #ifdef STB_VORBIS_NO_DEFER_FLOOR + f->floor_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); + #endif + } + + if (!init_blocksize(f, 0, f->blocksize_0)) return FALSE; + if (!init_blocksize(f, 1, f->blocksize_1)) return FALSE; + f->blocksize[0] = f->blocksize_0; + f->blocksize[1] = f->blocksize_1; + +#ifdef STB_VORBIS_DIVIDE_TABLE + if (integer_divide_table[1][1]==0) + for (i=0; i < DIVTAB_NUMER; ++i) + for (j=1; j < DIVTAB_DENOM; ++j) + integer_divide_table[i][j] = i / j; +#endif + + // compute how much temporary memory is needed + + // 1. + { + uint32 imdct_mem = (f->blocksize_1 * sizeof(float) >> 1); + uint32 classify_mem; + int i,max_part_read=0; + for (i=0; i < f->residue_count; ++i) { + Residue *r = f->residue_config + i; + int n_read = r->end - r->begin; + int part_read = n_read / r->part_size; + if (part_read > max_part_read) + max_part_read = part_read; + } + #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(uint8 *)); + #else + classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *)); + #endif + + f->temp_memory_required = classify_mem; + if (imdct_mem > f->temp_memory_required) + f->temp_memory_required = imdct_mem; + } + + f->first_decode = TRUE; + + if (f->alloc.alloc_buffer) { + assert(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes); + // check if there's enough temp memory so we don't error later + if (f->setup_offset + sizeof(*f) + f->temp_memory_required > (unsigned) f->temp_offset) + return error(f, VORBIS_outofmem); + } + + f->first_audio_page_offset = stb_vorbis_get_file_offset(f); + + return TRUE; +} + +static void vorbis_deinit(stb_vorbis *p) +{ + int i,j; + for (i=0; i < p->residue_count; ++i) { + Residue *r = p->residue_config+i; + if (r->classdata) { + for (j=0; j < p->codebooks[r->classbook].entries; ++j) + setup_free(p, r->classdata[j]); + setup_free(p, r->classdata); + } + setup_free(p, r->residue_books); + } + + if (p->codebooks) { + for (i=0; i < p->codebook_count; ++i) { + Codebook *c = p->codebooks + i; + setup_free(p, c->codeword_lengths); + setup_free(p, c->multiplicands); + setup_free(p, c->codewords); + setup_free(p, c->sorted_codewords); + // c->sorted_values[-1] is the first entry in the array + setup_free(p, c->sorted_values ? c->sorted_values-1 : NULL); + } + setup_free(p, p->codebooks); + } + setup_free(p, p->floor_config); + setup_free(p, p->residue_config); + for (i=0; i < p->mapping_count; ++i) + setup_free(p, p->mapping[i].chan); + setup_free(p, p->mapping); + for (i=0; i < p->channels; ++i) { + setup_free(p, p->channel_buffers[i]); + setup_free(p, p->previous_window[i]); + #ifdef STB_VORBIS_NO_DEFER_FLOOR + setup_free(p, p->floor_buffers[i]); + #endif + setup_free(p, p->finalY[i]); + } + for (i=0; i < 2; ++i) { + setup_free(p, p->A[i]); + setup_free(p, p->B[i]); + setup_free(p, p->C[i]); + setup_free(p, p->window[i]); + } + #ifndef STB_VORBIS_NO_STDIO + if (p->close_on_free) fclose(p->f); + #endif +} + +void stb_vorbis_close(stb_vorbis *p) +{ + if (p == NULL) return; + vorbis_deinit(p); + setup_free(p,p); +} + +static void vorbis_init(stb_vorbis *p, stb_vorbis_alloc *z) +{ + memset(p, 0, sizeof(*p)); // NULL out all malloc'd pointers to start + if (z) { + p->alloc = *z; + p->alloc.alloc_buffer_length_in_bytes = (p->alloc.alloc_buffer_length_in_bytes+3) & ~3; + p->temp_offset = p->alloc.alloc_buffer_length_in_bytes; + } + p->eof = 0; + p->error = VORBIS__no_error; + p->stream = NULL; + p->codebooks = NULL; + p->page_crc_tests = -1; + #ifndef STB_VORBIS_NO_STDIO + p->close_on_free = FALSE; + p->f = NULL; + #endif +} + +int stb_vorbis_get_sample_offset(stb_vorbis *f) +{ + if (f->current_loc_valid) + return f->current_loc; + else + return -1; +} + +stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f) +{ + stb_vorbis_info d; + d.channels = f->channels; + d.sample_rate = f->sample_rate; + d.setup_memory_required = f->setup_memory_required; + d.setup_temp_memory_required = f->setup_temp_memory_required; + d.temp_memory_required = f->temp_memory_required; + d.max_frame_size = f->blocksize_1 >> 1; + return d; +} + +int stb_vorbis_get_error(stb_vorbis *f) +{ + int e = f->error; + f->error = VORBIS__no_error; + return e; +} + +static stb_vorbis * vorbis_alloc(stb_vorbis *f) +{ + stb_vorbis *p = (stb_vorbis *) setup_malloc(f, sizeof(*p)); + return p; +} + +#ifndef STB_VORBIS_NO_PUSHDATA_API + +void stb_vorbis_flush_pushdata(stb_vorbis *f) +{ + f->previous_length = 0; + f->page_crc_tests = 0; + f->discard_samples_deferred = 0; + f->current_loc_valid = FALSE; + f->first_decode = FALSE; + f->samples_output = 0; + f->channel_buffer_start = 0; + f->channel_buffer_end = 0; +} + +static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len) +{ + int i,n; + for (i=0; i < f->page_crc_tests; ++i) + f->scan[i].bytes_done = 0; + + // if we have room for more scans, search for them first, because + // they may cause us to stop early if their header is incomplete + if (f->page_crc_tests < STB_VORBIS_PUSHDATA_CRC_COUNT) { + if (data_len < 4) return 0; + data_len -= 3; // need to look for 4-byte sequence, so don't miss + // one that straddles a boundary + for (i=0; i < data_len; ++i) { + if (data[i] == 0x4f) { + if (0==memcmp(data+i, ogg_page_header, 4)) { + int j,len; + uint32 crc; + // make sure we have the whole page header + if (i+26 >= data_len || i+27+data[i+26] >= data_len) { + // only read up to this page start, so hopefully we'll + // have the whole page header start next time + data_len = i; + break; + } + // ok, we have it all; compute the length of the page + len = 27 + data[i+26]; + for (j=0; j < data[i+26]; ++j) + len += data[i+27+j]; + // scan everything up to the embedded crc (which we must 0) + crc = 0; + for (j=0; j < 22; ++j) + crc = crc32_update(crc, data[i+j]); + // now process 4 0-bytes + for ( ; j < 26; ++j) + crc = crc32_update(crc, 0); + // len is the total number of bytes we need to scan + n = f->page_crc_tests++; + f->scan[n].bytes_left = len-j; + f->scan[n].crc_so_far = crc; + f->scan[n].goal_crc = data[i+22] + (data[i+23] << 8) + (data[i+24]<<16) + (data[i+25]<<24); + // if the last frame on a page is continued to the next, then + // we can't recover the sample_loc immediately + if (data[i+27+data[i+26]-1] == 255) + f->scan[n].sample_loc = ~0; + else + f->scan[n].sample_loc = data[i+6] + (data[i+7] << 8) + (data[i+ 8]<<16) + (data[i+ 9]<<24); + f->scan[n].bytes_done = i+j; + if (f->page_crc_tests == STB_VORBIS_PUSHDATA_CRC_COUNT) + break; + // keep going if we still have room for more + } + } + } + } + + for (i=0; i < f->page_crc_tests;) { + uint32 crc; + int j; + int n = f->scan[i].bytes_done; + int m = f->scan[i].bytes_left; + if (m > data_len - n) m = data_len - n; + // m is the bytes to scan in the current chunk + crc = f->scan[i].crc_so_far; + for (j=0; j < m; ++j) + crc = crc32_update(crc, data[n+j]); + f->scan[i].bytes_left -= m; + f->scan[i].crc_so_far = crc; + if (f->scan[i].bytes_left == 0) { + // does it match? + if (f->scan[i].crc_so_far == f->scan[i].goal_crc) { + // Houston, we have page + data_len = n+m; // consumption amount is wherever that scan ended + f->page_crc_tests = -1; // drop out of page scan mode + f->previous_length = 0; // decode-but-don't-output one frame + f->next_seg = -1; // start a new page + f->current_loc = f->scan[i].sample_loc; // set the current sample location + // to the amount we'd have decoded had we decoded this page + f->current_loc_valid = f->current_loc != ~0; + return data_len; + } + // delete entry + f->scan[i] = f->scan[--f->page_crc_tests]; + } else { + ++i; + } + } + + return data_len; +} + +// return value: number of bytes we used +int stb_vorbis_decode_frame_pushdata( + stb_vorbis *f, // the file we're decoding + uint8 *data, int data_len, // the memory available for decoding + int *channels, // place to write number of float * buffers + float ***output, // place to write float ** array of float * buffers + int *samples // place to write number of output samples + ) +{ + int i; + int len,right,left; + + if (!IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); + + if (f->page_crc_tests >= 0) { + *samples = 0; + return vorbis_search_for_page_pushdata(f, data, data_len); + } + + f->stream = data; + f->stream_end = data + data_len; + f->error = VORBIS__no_error; + + // check that we have the entire packet in memory + if (!is_whole_packet_present(f, FALSE)) { + *samples = 0; + return 0; + } + + if (!vorbis_decode_packet(f, &len, &left, &right)) { + // save the actual error we encountered + enum STBVorbisError error = f->error; + if (error == VORBIS_bad_packet_type) { + // flush and resynch + f->error = VORBIS__no_error; + while (get8_packet(f) != EOP) + if (f->eof) break; + *samples = 0; + return f->stream - data; + } + if (error == VORBIS_continued_packet_flag_invalid) { + if (f->previous_length == 0) { + // we may be resynching, in which case it's ok to hit one + // of these; just discard the packet + f->error = VORBIS__no_error; + while (get8_packet(f) != EOP) + if (f->eof) break; + *samples = 0; + return f->stream - data; + } + } + // if we get an error while parsing, what to do? + // well, it DEFINITELY won't work to continue from where we are! + stb_vorbis_flush_pushdata(f); + // restore the error that actually made us bail + f->error = error; + *samples = 0; + return 1; + } + + // success! + len = vorbis_finish_frame(f, len, left, right); + for (i=0; i < f->channels; ++i) + f->outputs[i] = f->channel_buffers[i] + left; + + if (channels) *channels = f->channels; + *samples = len; + *output = f->outputs; + return f->stream - data; +} + +stb_vorbis *stb_vorbis_open_pushdata( + unsigned char *data, int data_len, // the memory available for decoding + int *data_used, // only defined if result is not NULL + int *error, stb_vorbis_alloc *alloc) +{ + stb_vorbis *f, p; + vorbis_init(&p, alloc); + p.stream = data; + p.stream_end = data + data_len; + p.push_mode = TRUE; + if (!start_decoder(&p)) { + if (p.eof) + *error = VORBIS_need_more_data; + else + *error = p.error; + return NULL; + } + f = vorbis_alloc(&p); + if (f) { + *f = p; + *data_used = f->stream - data; + *error = 0; + return f; + } else { + vorbis_deinit(&p); + return NULL; + } +} +#endif // STB_VORBIS_NO_PUSHDATA_API + +unsigned int stb_vorbis_get_file_offset(stb_vorbis *f) +{ + #ifndef STB_VORBIS_NO_PUSHDATA_API + if (f->push_mode) return 0; + #endif + if (USE_MEMORY(f)) return f->stream - f->stream_start; + #ifndef STB_VORBIS_NO_STDIO + return ftell(f->f) - f->f_start; + #endif +} + +#ifndef STB_VORBIS_NO_PULLDATA_API +// +// DATA-PULLING API +// + +static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last) +{ + for(;;) { + int n; + if (f->eof) return 0; + n = get8(f); + if (n == 0x4f) { // page header + unsigned int retry_loc = stb_vorbis_get_file_offset(f); + int i; + // check if we're off the end of a file_section stream + if (retry_loc - 25 > f->stream_len) + return 0; + // check the rest of the header + for (i=1; i < 4; ++i) + if (get8(f) != ogg_page_header[i]) + break; + if (f->eof) return 0; + if (i == 4) { + uint8 header[27]; + uint32 i, crc, goal, len; + for (i=0; i < 4; ++i) + header[i] = ogg_page_header[i]; + for (; i < 27; ++i) + header[i] = get8(f); + if (f->eof) return 0; + if (header[4] != 0) goto invalid; + goal = header[22] + (header[23] << 8) + (header[24]<<16) + (header[25]<<24); + for (i=22; i < 26; ++i) + header[i] = 0; + crc = 0; + for (i=0; i < 27; ++i) + crc = crc32_update(crc, header[i]); + len = 0; + for (i=0; i < header[26]; ++i) { + int s = get8(f); + crc = crc32_update(crc, s); + len += s; + } + if (len && f->eof) return 0; + for (i=0; i < len; ++i) + crc = crc32_update(crc, get8(f)); + // finished parsing probable page + if (crc == goal) { + // we could now check that it's either got the last + // page flag set, OR it's followed by the capture + // pattern, but I guess TECHNICALLY you could have + // a file with garbage between each ogg page and recover + // from it automatically? So even though that paranoia + // might decrease the chance of an invalid decode by + // another 2^32, not worth it since it would hose those + // invalid-but-useful files? + if (end) + *end = stb_vorbis_get_file_offset(f); + if (last) + { + if (header[5] & 0x04) + *last = 1; + else + *last = 0; + } + set_file_offset(f, retry_loc-1); + return 1; + } + } + invalid: + // not a valid page, so rewind and look for next one + set_file_offset(f, retry_loc); + } + } +} + +// seek is implemented with 'interpolation search'--this is like +// binary search, but we use the data values to estimate the likely +// location of the data item (plus a bit of a bias so when the +// estimation is wrong we don't waste overly much time) + +#define SAMPLE_unknown 0xffffffff + + +// ogg vorbis, in its insane infinite wisdom, only provides +// information about the sample at the END of the page. +// therefore we COULD have the data we need in the current +// page, and not know it. we could just use the end location +// as our only knowledge for bounds, seek back, and eventually +// the binary search finds it. or we can try to be smart and +// not waste time trying to locate more pages. we try to be +// smart, since this data is already in memory anyway, so +// doing needless I/O would be crazy! +static int vorbis_analyze_page(stb_vorbis *f, ProbedPage *z) +{ + uint8 header[27], lacing[255]; + uint8 packet_type[255]; + int num_packet, packet_start, previous =0; + int i,len; + uint32 samples; + + // record where the page starts + z->page_start = stb_vorbis_get_file_offset(f); + + // parse the header + getn(f, header, 27); + assert(header[0] == 'O' && header[1] == 'g' && header[2] == 'g' && header[3] == 'S'); + getn(f, lacing, header[26]); + + // determine the length of the payload + len = 0; + for (i=0; i < header[26]; ++i) + len += lacing[i]; + + // this implies where the page ends + z->page_end = z->page_start + 27 + header[26] + len; + + // read the last-decoded sample out of the data + z->last_decoded_sample = header[6] + (header[7] << 8) + (header[8] << 16) + (header[9] << 16); + + if (header[5] & 4) { + // if this is the last page, it's not possible to work + // backwards to figure out the first sample! whoops! fuck. + z->first_decoded_sample = SAMPLE_unknown; + set_file_offset(f, z->page_start); + return 1; + } + + // scan through the frames to determine the sample-count of each one... + // our goal is the sample # of the first fully-decoded sample on the + // page, which is the first decoded sample of the 2nd page + + num_packet=0; + + packet_start = ((header[5] & 1) == 0); + + for (i=0; i < header[26]; ++i) { + if (packet_start) { + uint8 n,b,m; + if (lacing[i] == 0) goto bail; // trying to read from zero-length packet + n = get8(f); + // if bottom bit is non-zero, we've got corruption + if (n & 1) goto bail; + n >>= 1; + b = ilog(f->mode_count-1); + m = n >> b; + n &= (1 << b)-1; + if (n >= f->mode_count) goto bail; + if (num_packet == 0 && f->mode_config[n].blockflag) + previous = (m & 1); + packet_type[num_packet++] = f->mode_config[n].blockflag; + skip(f, lacing[i]-1); + } else + skip(f, lacing[i]); + packet_start = (lacing[i] < 255); + } + + // now that we know the sizes of all the pages, we can start determining + // how much sample data there is. + + samples = 0; + + // for the last packet, we step by its whole length, because the definition + // is that we encoded the end sample loc of the 'last packet completed', + // where 'completed' refers to packets being split, and we are left to guess + // what 'end sample loc' means. we assume it means ignoring the fact that + // the last half of the data is useless without windowing against the next + // packet... (so it's not REALLY complete in that sense) + if (num_packet > 1) + samples += f->blocksize[packet_type[num_packet-1]]; + + for (i=num_packet-2; i >= 1; --i) { + // now, for this packet, how many samples do we have that + // do not overlap the following packet? + if (packet_type[i] == 1) + if (packet_type[i+1] == 1) + samples += f->blocksize_1 >> 1; + else + samples += ((f->blocksize_1 - f->blocksize_0) >> 2) + (f->blocksize_0 >> 1); + else + samples += f->blocksize_0 >> 1; + } + // now, at this point, we've rewound to the very beginning of the + // _second_ packet. if we entirely discard the first packet after + // a seek, this will be exactly the right sample number. HOWEVER! + // we can't as easily compute this number for the LAST page. The + // only way to get the sample offset of the LAST page is to use + // the end loc from the previous page. But what that returns us + // is _exactly_ the place where we get our first non-overlapped + // sample. (I think. Stupid spec for being ambiguous.) So for + // consistency it's better to do that here, too. However, that + // will then require us to NOT discard all of the first frame we + // decode, in some cases, which means an even weirder frame size + // and extra code. what a fucking pain. + + // we're going to discard the first packet if we + // start the seek here, so we don't care about it. (we could actually + // do better; if the first packet is long, and the previous packet + // is short, there's actually data in the first half of the first + // packet that doesn't need discarding... but not worth paying the + // effort of tracking that of that here and in the seeking logic) + // except crap, if we infer it from the _previous_ packet's end + // location, we DO need to use that definition... and we HAVE to + // infer the start loc of the LAST packet from the previous packet's + // end location. fuck you, ogg vorbis. + + z->first_decoded_sample = z->last_decoded_sample - samples; + + // restore file state to where we were + set_file_offset(f, z->page_start); + return 1; + + // restore file state to where we were + bail: + set_file_offset(f, z->page_start); + return 0; +} + +static int vorbis_seek_frame_from_page(stb_vorbis *f, uint32 page_start, uint32 first_sample, uint32 target_sample, int fine) +{ + int left_start, left_end, right_start, right_end, mode,i; + int frame=0; + uint32 frame_start; + int frames_to_skip, data_to_skip; + + // first_sample is the sample # of the first sample that doesn't + // overlap the previous page... note that this requires us to + // _partially_ discard the first packet! bleh. + set_file_offset(f, page_start); + + f->next_seg = -1; // force page resync + + frame_start = first_sample; + // frame start is where the previous packet's last decoded sample + // was, which corresponds to left_end... EXCEPT if the previous + // packet was long and this packet is short? Probably a bug here. + + + // now, we can start decoding frames... we'll only FAKE decode them, + // until we find the frame that contains our sample; then we'll rewind, + // and try again + for (;;) { + int start; + + if (!vorbis_decode_initial(f, &left_start, &left_end, &right_start, &right_end, &mode)) + return error(f, VORBIS_seek_failed); + + if (frame == 0) + start = left_end; + else + start = left_start; + + // the window starts at left_start; the last valid sample we generate + // before the next frame's window start is right_start-1 + if (target_sample < frame_start + right_start-start) + break; + + flush_packet(f); + if (f->eof) + return error(f, VORBIS_seek_failed); + + frame_start += right_start - start; + + ++frame; + } + + // ok, at this point, the sample we want is contained in frame #'frame' + + // to decode frame #'frame' normally, we have to decode the + // previous frame first... but if it's the FIRST frame of the page + // we can't. if it's the first frame, it means it falls in the part + // of the first frame that doesn't overlap either of the other frames. + // so, if we have to handle that case for the first frame, we might + // as well handle it for all of them, so: + if (target_sample > frame_start + (left_end - left_start)) { + // so what we want to do is go ahead and just immediately decode + // this frame, but then make it so the next get_frame_float() uses + // this already-decoded data? or do we want to go ahead and rewind, + // and leave a flag saying to skip the first N data? let's do that + frames_to_skip = frame; // if this is frame #1, skip 1 frame (#0) + data_to_skip = left_end - left_start; + } else { + // otherwise, we want to skip frames 0, 1, 2, ... frame-2 + // (which means frame-2+1 total frames) then decode frame-1, + // then leave frame pending + frames_to_skip = frame - 1; + assert(frames_to_skip >= 0); + data_to_skip = -1; + } + + set_file_offset(f, page_start); + f->next_seg = - 1; // force page resync + + for (i=0; i < frames_to_skip; ++i) { + maybe_start_packet(f); + flush_packet(f); + } + + if (data_to_skip >= 0) { + int i,j,n = f->blocksize_0 >> 1; + f->discard_samples_deferred = data_to_skip; + for (i=0; i < f->channels; ++i) + for (j=0; j < n; ++j) + f->previous_window[i][j] = 0; + f->previous_length = n; + frame_start += data_to_skip; + } else { + f->previous_length = 0; + vorbis_pump_first_frame(f); + } + + // at this point, the NEXT decoded frame will generate the desired sample + if (fine) { + // so if we're doing sample accurate streaming, we want to go ahead and decode it! + if (target_sample != frame_start) { + int n; + stb_vorbis_get_frame_float(f, &n, NULL); + assert(target_sample > frame_start); + assert(f->channel_buffer_start + (int) (target_sample-frame_start) < f->channel_buffer_end); + f->channel_buffer_start += (target_sample - frame_start); + } + } + + return 0; +} + +static int vorbis_seek_base(stb_vorbis *f, unsigned int sample_number, int fine) +{ + ProbedPage p[2],q; + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); + + // do we know the location of the last page? + if (f->p_last.page_start == 0) { + uint32 z = stb_vorbis_stream_length_in_samples(f); + if (z == 0) return error(f, VORBIS_cant_find_last_page); + } + + p[0] = f->p_first; + p[1] = f->p_last; + + if (sample_number >= f->p_last.last_decoded_sample) + sample_number = f->p_last.last_decoded_sample-1; + + if (sample_number < f->p_first.last_decoded_sample) { + vorbis_seek_frame_from_page(f, p[0].page_start, 0, sample_number, fine); + return 0; + } else { + int attempts=0; + while (p[0].page_end < p[1].page_start) { + uint32 probe; + uint32 start_offset, end_offset; + uint32 start_sample, end_sample; + + // copy these into local variables so we can tweak them + // if any are unknown + start_offset = p[0].page_end; + end_offset = p[1].after_previous_page_start; // an address known to seek to page p[1] + start_sample = p[0].last_decoded_sample; + end_sample = p[1].last_decoded_sample; + + // currently there is no such tweaking logic needed/possible? + if (start_sample == SAMPLE_unknown || end_sample == SAMPLE_unknown) + return error(f, VORBIS_seek_failed); + + // now we want to lerp between these for the target samples... + + // step 1: we need to bias towards the page start... + if (start_offset + 4000 < end_offset) + end_offset -= 4000; + + // now compute an interpolated search loc + probe = start_offset + (int) floor((float) (end_offset - start_offset) / (end_sample - start_sample) * (sample_number - start_sample)); + + // next we need to bias towards binary search... + // code is a little wonky to allow for full 32-bit unsigned values + if (attempts >= 4) { + uint32 probe2 = start_offset + ((end_offset - start_offset) >> 1); + if (attempts >= 8) + probe = probe2; + else if (probe < probe2) + probe = probe + ((probe2 - probe) >> 1); + else + probe = probe2 + ((probe - probe2) >> 1); + } + ++attempts; + + set_file_offset(f, probe); + if (!vorbis_find_page(f, NULL, NULL)) return error(f, VORBIS_seek_failed); + if (!vorbis_analyze_page(f, &q)) return error(f, VORBIS_seek_failed); + q.after_previous_page_start = probe; + + // it's possible we've just found the last page again + if (q.page_start == p[1].page_start) { + p[1] = q; + continue; + } + + if (sample_number < q.last_decoded_sample) + p[1] = q; + else + p[0] = q; + } + + if (p[0].last_decoded_sample <= sample_number && sample_number < p[1].last_decoded_sample) { + vorbis_seek_frame_from_page(f, p[1].page_start, p[0].last_decoded_sample, sample_number, fine); + return 0; + } + return error(f, VORBIS_seek_failed); + } +} + +int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number) +{ + return vorbis_seek_base(f, sample_number, FALSE); +} + +int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number) +{ + return vorbis_seek_base(f, sample_number, TRUE); +} + +void stb_vorbis_seek_start(stb_vorbis *f) +{ + if (IS_PUSH_MODE(f)) { error(f, VORBIS_invalid_api_mixing); return; } + set_file_offset(f, f->first_audio_page_offset); + f->previous_length = 0; + f->first_decode = TRUE; + f->next_seg = -1; + vorbis_pump_first_frame(f); +} + +unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) +{ + unsigned int restore_offset, previous_safe; + unsigned int end, last_page_loc; + + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); + if (!f->total_samples) { + int last; + uint32 lo,hi; + char header[6]; + + // first, store the current decode position so we can restore it + restore_offset = stb_vorbis_get_file_offset(f); + + // now we want to seek back 64K from the end (the last page must + // be at most a little less than 64K, but let's allow a little slop) + if (f->stream_len >= 65536 && f->stream_len-65536 >= f->first_audio_page_offset) + previous_safe = f->stream_len - 65536; + else + previous_safe = f->first_audio_page_offset; + + set_file_offset(f, previous_safe); + // previous_safe is now our candidate 'earliest known place that seeking + // to will lead to the final page' + + if (!vorbis_find_page(f, &end, (int unsigned *)&last)) { + // if we can't find a page, we're hosed! + f->error = VORBIS_cant_find_last_page; + f->total_samples = 0xffffffff; + goto done; + } + + // check if there are more pages + last_page_loc = stb_vorbis_get_file_offset(f); + + // stop when the last_page flag is set, not when we reach eof; + // this allows us to stop short of a 'file_section' end without + // explicitly checking the length of the section + while (!last) { + set_file_offset(f, end); + if (!vorbis_find_page(f, &end, (int unsigned *)&last)) { + // the last page we found didn't have the 'last page' flag + // set. whoops! + break; + } + previous_safe = last_page_loc+1; + last_page_loc = stb_vorbis_get_file_offset(f); + } + + set_file_offset(f, last_page_loc); + + // parse the header + getn(f, (unsigned char *)header, 6); + // extract the absolute granule position + lo = get32(f); + hi = get32(f); + if (lo == 0xffffffff && hi == 0xffffffff) { + f->error = VORBIS_cant_find_last_page; + f->total_samples = SAMPLE_unknown; + goto done; + } + if (hi) + lo = 0xfffffffe; // saturate + f->total_samples = lo; + + f->p_last.page_start = last_page_loc; + f->p_last.page_end = end; + f->p_last.last_decoded_sample = lo; + f->p_last.first_decoded_sample = SAMPLE_unknown; + f->p_last.after_previous_page_start = previous_safe; + + done: + set_file_offset(f, restore_offset); + } + return f->total_samples == SAMPLE_unknown ? 0 : f->total_samples; +} + +float stb_vorbis_stream_length_in_seconds(stb_vorbis *f) +{ + return stb_vorbis_stream_length_in_samples(f) / (float) f->sample_rate; +} + + + +int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output) +{ + int len, right,left,i; + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); + + if (!vorbis_decode_packet(f, &len, &left, &right)) { + f->channel_buffer_start = f->channel_buffer_end = 0; + return 0; + } + + len = vorbis_finish_frame(f, len, left, right); + for (i=0; i < f->channels; ++i) + f->outputs[i] = f->channel_buffers[i] + left; + + f->channel_buffer_start = left; + f->channel_buffer_end = left+len; + + if (channels) *channels = f->channels; + if (output) *output = f->outputs; + return len; +} + +#ifndef STB_VORBIS_NO_STDIO + +stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *error, stb_vorbis_alloc *alloc, unsigned int length) +{ + stb_vorbis *f, p; + vorbis_init(&p, alloc); + p.f = file; + p.f_start = ftell(file); + p.stream_len = length; + p.close_on_free = close_on_free; + if (start_decoder(&p)) { + f = vorbis_alloc(&p); + if (f) { + *f = p; + vorbis_pump_first_frame(f); + return f; + } + } + if (error) *error = p.error; + vorbis_deinit(&p); + return NULL; +} + +stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, stb_vorbis_alloc *alloc) +{ + unsigned int len, start; + start = ftell(file); + fseek(file, 0, SEEK_END); + len = ftell(file) - start; + fseek(file, start, SEEK_SET); + return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len); +} + +stb_vorbis * stb_vorbis_open_filename(char *filename, int *error, stb_vorbis_alloc *alloc) +{ + FILE *f = fopen(filename, "rb"); + if (f) + return stb_vorbis_open_file(f, TRUE, error, alloc); + if (error) *error = VORBIS_file_open_failure; + return NULL; +} +#endif // STB_VORBIS_NO_STDIO + +stb_vorbis * stb_vorbis_open_memory(unsigned char *data, int len, int *error, stb_vorbis_alloc *alloc) +{ + stb_vorbis *f, p; + if (data == NULL) return NULL; + vorbis_init(&p, alloc); + p.stream = data; + p.stream_end = data + len; + p.stream_start = p.stream; + p.stream_len = len; + p.push_mode = FALSE; + if (start_decoder(&p)) { + f = vorbis_alloc(&p); + if (f) { + *f = p; + vorbis_pump_first_frame(f); + return f; + } + } + if (error) *error = p.error; + vorbis_deinit(&p); + return NULL; +} + +#ifndef STB_VORBIS_NO_INTEGER_CONVERSION +#define PLAYBACK_MONO 1 +#define PLAYBACK_LEFT 2 +#define PLAYBACK_RIGHT 4 + +#define L (PLAYBACK_LEFT | PLAYBACK_MONO) +#define C (PLAYBACK_LEFT | PLAYBACK_RIGHT | PLAYBACK_MONO) +#define R (PLAYBACK_RIGHT | PLAYBACK_MONO) + +static int8 channel_position[7][6] = +{ + { 0 }, + { C }, + { L, R }, + { L, C, R }, + { L, R, L, R }, + { L, C, R, L, R }, + { L, C, R, L, R, C }, +}; + + +#ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT + typedef union { + float f; + int i; + } float_conv; + typedef char stb_vorbis_float_size_test[sizeof(float)==4 && sizeof(int) == 4]; + #define FASTDEF(x) float_conv x + // add (1<<23) to convert to int, then divide by 2^SHIFT, then add 0.5/2^SHIFT to round + #define MAGIC(SHIFT) (1.5f * (1 << (23-SHIFT)) + 0.5f/(1 << SHIFT)) + #define ADDEND(SHIFT) (((150-SHIFT) << 23) + (1 << 22)) + #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) (temp.f = (x) + MAGIC(s), temp.i - ADDEND(s)) + #define check_endianness() +#else + #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) ((int) ((x) * (1 << (s)))) + #define check_endianness() + #define FASTDEF(x) +#endif + +static void copy_samples(short *dest, float *src, int len) +{ + int i; + check_endianness(); + for (i=0; i < len; ++i) { + FASTDEF(temp); + int v = FAST_SCALED_FLOAT_TO_INT(temp, src[i],15); + if ((unsigned int) (v + 32768) > 65535) + v = v < 0 ? -32768 : 32767; + dest[i] = v; + } +} + +static void compute_samples(int mask, short *output, int num_c, float **data, int d_offset, int len) +{ + #define BUFFER_SIZE 32 + float buffer[BUFFER_SIZE]; + int i,j,o,n = BUFFER_SIZE; + check_endianness(); + for (o = 0; o < len; o += BUFFER_SIZE) { + memset(buffer, 0, sizeof(buffer)); + if (o + n > len) n = len - o; + for (j=0; j < num_c; ++j) { + if (channel_position[num_c][j] & mask) { + for (i=0; i < n; ++i) + buffer[i] += data[j][d_offset+o+i]; + } + } + for (i=0; i < n; ++i) { + FASTDEF(temp); + int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); + if ((unsigned int) (v + 32768) > 65535) + v = v < 0 ? -32768 : 32767; + output[o+i] = v; + } + } +} + +static void compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len) +{ + #define BUFFER_SIZE 32 + float buffer[BUFFER_SIZE]; + int i,j,o,n = BUFFER_SIZE >> 1; + // o is the offset in the source data + check_endianness(); + for (o = 0; o < len; o += BUFFER_SIZE >> 1) { + // o2 is the offset in the output data + int o2 = o << 1; + memset(buffer, 0, sizeof(buffer)); + if (o + n > len) n = len - o; + for (j=0; j < num_c; ++j) { + int m = channel_position[num_c][j] & (PLAYBACK_LEFT | PLAYBACK_RIGHT); + if (m == (PLAYBACK_LEFT | PLAYBACK_RIGHT)) { + for (i=0; i < n; ++i) { + buffer[i*2+0] += data[j][d_offset+o+i]; + buffer[i*2+1] += data[j][d_offset+o+i]; + } + } else if (m == PLAYBACK_LEFT) { + for (i=0; i < n; ++i) { + buffer[i*2+0] += data[j][d_offset+o+i]; + } + } else if (m == PLAYBACK_RIGHT) { + for (i=0; i < n; ++i) { + buffer[i*2+1] += data[j][d_offset+o+i]; + } + } + } + for (i=0; i < (n<<1); ++i) { + FASTDEF(temp); + int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); + if ((unsigned int) (v + 32768) > 65535) + v = v < 0 ? -32768 : 32767; + output[o2+i] = v; + } + } +} + +static void convert_samples_short(int buf_c, short **buffer, int b_offset, int data_c, float **data, int d_offset, int samples) +{ + int i; + if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { + static int channel_selector[3][2] = { {0}, {PLAYBACK_MONO}, {PLAYBACK_LEFT, PLAYBACK_RIGHT} }; + for (i=0; i < buf_c; ++i) + compute_samples(channel_selector[buf_c][i], buffer[i]+b_offset, data_c, data, d_offset, samples); + } else { + int limit = buf_c < data_c ? buf_c : data_c; + for (i=0; i < limit; ++i) + copy_samples(buffer[i]+b_offset, data[i], samples); + for ( ; i < buf_c; ++i) + memset(buffer[i]+b_offset, 0, sizeof(short) * samples); + } +} + +int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num_samples) +{ + float **output; + int len = stb_vorbis_get_frame_float(f, NULL, &output); + if (len > num_samples) len = num_samples; + if (len) + convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len); + return len; +} + +static void convert_channels_short_interleaved(int buf_c, short *buffer, int data_c, float **data, int d_offset, int len) +{ + int i; + check_endianness(); + if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { + assert(buf_c == 2); + for (i=0; i < buf_c; ++i) + compute_stereo_samples(buffer, data_c, data, d_offset, len); + } else { + int limit = buf_c < data_c ? buf_c : data_c; + int j; + for (j=0; j < len; ++j) { + for (i=0; i < limit; ++i) { + FASTDEF(temp); + float f = data[i][d_offset+j]; + int v = FAST_SCALED_FLOAT_TO_INT(temp, f,15);//data[i][d_offset+j],15); + if ((unsigned int) (v + 32768) > 65535) + v = v < 0 ? -32768 : 32767; + *buffer++ = v; + } + for ( ; i < buf_c; ++i) + *buffer++ = 0; + } + } +} + +int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts) +{ + float **output; + int len; + if (num_c == 1) return stb_vorbis_get_frame_short(f,num_c,&buffer, num_shorts); + len = stb_vorbis_get_frame_float(f, NULL, &output); + if (len) { + if (len*num_c > num_shorts) len = num_shorts / num_c; + convert_channels_short_interleaved(num_c, buffer, f->channels, output, 0, len); + } + return len; +} + +int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts) +{ + float **outputs; + int len = num_shorts / channels; + int n=0; + int z = f->channels; + if (z > channels) z = channels; + while (n < len) { + int k = f->channel_buffer_end - f->channel_buffer_start; + if (n+k >= len) k = len - n; + if (k) + convert_channels_short_interleaved(channels, buffer, f->channels, f->channel_buffers, f->channel_buffer_start, k); + buffer += k*channels; + n += k; + f->channel_buffer_start += k; + if (n == len) break; + if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; + } + return n; +} + +int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int len) +{ + float **outputs; + int n=0; + int z = f->channels; + if (z > channels) z = channels; + while (n < len) { + int k = f->channel_buffer_end - f->channel_buffer_start; + if (n+k >= len) k = len - n; + if (k) + convert_samples_short(channels, buffer, n, f->channels, f->channel_buffers, f->channel_buffer_start, k); + n += k; + f->channel_buffer_start += k; + if (n == len) break; + if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; + } + return n; +} + +#ifndef STB_VORBIS_NO_STDIO +int stb_vorbis_decode_filename(char *filename, int *channels, short **output) +{ + int data_len, offset, total, limit, error; + short *data; + stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL); + if (v == NULL) return -1; + limit = v->channels * 4096; + *channels = v->channels; + offset = data_len = 0; + total = limit; + data = (short *) malloc(total * sizeof(*data)); + if (data == NULL) { + stb_vorbis_close(v); + return -2; + } + for (;;) { + int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset); + if (n == 0) break; + data_len += n; + offset += n * v->channels; + if (offset + limit > total) { + short *data2; + total *= 2; + data2 = (short *) realloc(data, total * sizeof(*data)); + if (data2 == NULL) { + free(data); + stb_vorbis_close(v); + return -2; + } + data = data2; + } + } + *output = data; + return data_len; +} +#endif // NO_STDIO + +int stb_vorbis_decode_memory(uint8 *mem, int len, int *channels, short **output) +{ + int data_len, offset, total, limit, error; + short *data; + stb_vorbis *v = stb_vorbis_open_memory(mem, len, &error, NULL); + if (v == NULL) return -1; + limit = v->channels * 4096; + *channels = v->channels; + offset = data_len = 0; + total = limit; + data = (short *) malloc(total * sizeof(*data)); + if (data == NULL) { + stb_vorbis_close(v); + return -2; + } + for (;;) { + int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset); + if (n == 0) break; + data_len += n; + offset += n * v->channels; + if (offset + limit > total) { + short *data2; + total *= 2; + data2 = (short *) realloc(data, total * sizeof(*data)); + if (data2 == NULL) { + free(data); + stb_vorbis_close(v); + return -2; + } + data = data2; + } + } + *output = data; + return data_len; +} +#endif + +int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats) +{ + float **outputs; + int len = num_floats / channels; + int n=0; + int z = f->channels; + if (z > channels) z = channels; + while (n < len) { + int i,j; + int k = f->channel_buffer_end - f->channel_buffer_start; + if (n+k >= len) k = len - n; + for (j=0; j < k; ++j) { + for (i=0; i < z; ++i) + *buffer++ = f->channel_buffers[i][f->channel_buffer_start+j]; + for ( ; i < channels; ++i) + *buffer++ = 0; + } + n += k; + f->channel_buffer_start += k; + if (n == len) break; + if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; + } + return n; +} + +int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples) +{ + float **outputs; + int n=0; + int z = f->channels; + if (z > channels) z = channels; + while (n < num_samples) { + int i; + int k = f->channel_buffer_end - f->channel_buffer_start; + if (n+k >= num_samples) k = num_samples - n; + if (k) { + for (i=0; i < z; ++i) + memcpy(buffer[i]+n, f->channel_buffers+f->channel_buffer_start, sizeof(float)*k); + for ( ; i < channels; ++i) + memset(buffer[i]+n, 0, sizeof(float) * k); + } + n += k; + f->channel_buffer_start += k; + if (n == num_samples) break; + if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; + } + return n; +} +#endif // STB_VORBIS_NO_PULLDATA_API + +#endif // STB_VORBIS_HEADER_ONLY diff --git a/ext/native/ext/stb_vorbis/stb_vorbis.h b/ext/native/ext/stb_vorbis/stb_vorbis.h new file mode 100644 index 0000000000..16ccc10036 --- /dev/null +++ b/ext/native/ext/stb_vorbis/stb_vorbis.h @@ -0,0 +1,329 @@ +////////////////////////////////////////////////////////////////////////////// +// +// HEADER BEGINS HERE +// + +#ifndef STB_VORBIS_INCLUDE_STB_VORBIS_H +#define STB_VORBIS_INCLUDE_STB_VORBIS_H + +#if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO) +#define STB_VORBIS_NO_STDIO 1 +#endif + +#ifndef STB_VORBIS_NO_STDIO +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/////////// THREAD SAFETY + +// Individual stb_vorbis* handles are not thread-safe; you cannot decode from +// them from multiple threads at the same time. However, you can have multiple +// stb_vorbis* handles and decode from them independently in multiple thrads. + + +/////////// MEMORY ALLOCATION + +// normally stb_vorbis uses malloc() to allocate memory at startup, +// and alloca() to allocate temporary memory during a frame on the +// stack. (Memory consumption will depend on the amount of setup +// data in the file and how you set the compile flags for speed +// vs. size. In my test files the maximal-size usage is ~150KB.) +// +// You can modify the wrapper functions in the source (setup_malloc, +// setup_temp_malloc, temp_malloc) to change this behavior, or you +// can use a simpler allocation model: you pass in a buffer from +// which stb_vorbis will allocate _all_ its memory (including the +// temp memory). "open" may fail with a VORBIS_outofmem if you +// do not pass in enough data; there is no way to determine how +// much you do need except to succeed (at which point you can +// query get_info to find the exact amount required. yes I know +// this is lame). +// +// If you pass in a non-NULL buffer of the type below, allocation +// will occur from it as described above. Otherwise just pass NULL +// to use malloc()/alloca() + +typedef struct +{ + char *alloc_buffer; + int alloc_buffer_length_in_bytes; +} stb_vorbis_alloc; + + +/////////// FUNCTIONS USEABLE WITH ALL INPUT MODES + +typedef struct stb_vorbis stb_vorbis; + +typedef struct +{ + unsigned int sample_rate; + int channels; + + unsigned int setup_memory_required; + unsigned int setup_temp_memory_required; + unsigned int temp_memory_required; + + int max_frame_size; +} stb_vorbis_info; + +// get general information about the file +extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f); + +// get the last error detected (clears it, too) +extern int stb_vorbis_get_error(stb_vorbis *f); + +// close an ogg vorbis file and free all memory in use +extern void stb_vorbis_close(stb_vorbis *f); + +// this function returns the offset (in samples) from the beginning of the +// file that will be returned by the next decode, if it is known, or -1 +// otherwise. after a flush_pushdata() call, this may take a while before +// it becomes valid again. +// NOT WORKING YET after a seek with PULLDATA API +extern int stb_vorbis_get_sample_offset(stb_vorbis *f); + +// returns the current seek point within the file, or offset from the beginning +// of the memory buffer. In pushdata mode it returns 0. +extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f); + +/////////// PUSHDATA API + +#ifndef STB_VORBIS_NO_PUSHDATA_API + +// this API allows you to get blocks of data from any source and hand +// them to stb_vorbis. you have to buffer them; stb_vorbis will tell +// you how much it used, and you have to give it the rest next time; +// and stb_vorbis may not have enough data to work with and you will +// need to give it the same data again PLUS more. Note that the Vorbis +// specification does not bound the size of an individual frame. + +extern stb_vorbis *stb_vorbis_open_pushdata( + unsigned char *datablock, int datablock_length_in_bytes, + int *datablock_memory_consumed_in_bytes, + int *error, + stb_vorbis_alloc *alloc_buffer); +// create a vorbis decoder by passing in the initial data block containing +// the ogg&vorbis headers (you don't need to do parse them, just provide +// the first N bytes of the file--you're told if it's not enough, see below) +// on success, returns an stb_vorbis *, does not set error, returns the amount of +// data parsed/consumed on this call in *datablock_memory_consumed_in_bytes; +// on failure, returns NULL on error and sets *error, does not change *datablock_memory_consumed +// if returns NULL and *error is VORBIS_need_more_data, then the input block was +// incomplete and you need to pass in a larger block from the start of the file + +extern int stb_vorbis_decode_frame_pushdata( + stb_vorbis *f, unsigned char *datablock, int datablock_length_in_bytes, + int *channels, // place to write number of float * buffers + float ***output, // place to write float ** array of float * buffers + int *samples // place to write number of output samples + ); +// decode a frame of audio sample data if possible from the passed-in data block +// +// return value: number of bytes we used from datablock +// possible cases: +// 0 bytes used, 0 samples output (need more data) +// N bytes used, 0 samples output (resynching the stream, keep going) +// N bytes used, M samples output (one frame of data) +// note that after opening a file, you will ALWAYS get one N-bytes,0-sample +// frame, because Vorbis always "discards" the first frame. +// +// Note that on resynch, stb_vorbis will rarely consume all of the buffer, +// instead only datablock_length_in_bytes-3 or less. This is because it wants +// to avoid missing parts of a page header if they cross a datablock boundary, +// without writing state-machiney code to record a partial detection. +// +// The number of channels returned are stored in *channels (which can be +// NULL--it is always the same as the number of channels reported by +// get_info). *output will contain an array of float* buffers, one per +// channel. In other words, (*output)[0][0] contains the first sample from +// the first channel, and (*output)[1][0] contains the first sample from +// the second channel. + +extern void stb_vorbis_flush_pushdata(stb_vorbis *f); +// inform stb_vorbis that your next datablock will not be contiguous with +// previous ones (e.g. you've seeked in the data); future attempts to decode +// frames will cause stb_vorbis to resynchronize (as noted above), and +// once it sees a valid Ogg page (typically 4-8KB, as large as 64KB), it +// will begin decoding the _next_ frame. +// +// if you want to seek using pushdata, you need to seek in your file, then +// call stb_vorbis_flush_pushdata(), then start calling decoding, then once +// decoding is returning you data, call stb_vorbis_get_sample_offset, and +// if you don't like the result, seek your file again and repeat. +#endif + + +////////// PULLING INPUT API + +#ifndef STB_VORBIS_NO_PULLDATA_API +// This API assumes stb_vorbis is allowed to pull data from a source-- +// either a block of memory containing the _entire_ vorbis stream, or a +// FILE * that you or it create, or possibly some other reading mechanism +// if you go modify the source to replace the FILE * case with some kind +// of callback to your code. (But if you don't support seeking, you may +// just want to go ahead and use pushdata.) + +#if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION) +extern int stb_vorbis_decode_filename(char *filename, int *channels, short **output); +#endif +extern int stb_vorbis_decode_memory(unsigned char *mem, int len, int *channels, short **output); +// decode an entire file and output the data interleaved into a malloc()ed +// buffer stored in *output. The return value is the number of samples +// decoded, or -1 if the file could not be opened or was not an ogg vorbis file. +// When you're done with it, just free() the pointer returned in *output. + +extern stb_vorbis * stb_vorbis_open_memory(unsigned char *data, int len, + int *error, stb_vorbis_alloc *alloc_buffer); +// create an ogg vorbis decoder from an ogg vorbis stream in memory (note +// this must be the entire stream!). on failure, returns NULL and sets *error + +#ifndef STB_VORBIS_NO_STDIO +extern stb_vorbis * stb_vorbis_open_filename(char *filename, + int *error, stb_vorbis_alloc *alloc_buffer); +// create an ogg vorbis decoder from a filename via fopen(). on failure, +// returns NULL and sets *error (possibly to VORBIS_file_open_failure). + +extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close, + int *error, stb_vorbis_alloc *alloc_buffer); +// create an ogg vorbis decoder from an open FILE *, looking for a stream at +// the _current_ seek point (ftell). on failure, returns NULL and sets *error. +// note that stb_vorbis must "own" this stream; if you seek it in between +// calls to stb_vorbis, it will become confused. Morever, if you attempt to +// perform stb_vorbis_seek_*() operations on this file, it will assume it +// owns the _entire_ rest of the file after the start point. Use the next +// function, stb_vorbis_open_file_section(), to limit it. + +extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close, + int *error, stb_vorbis_alloc *alloc_buffer, unsigned int len); +// create an ogg vorbis decoder from an open FILE *, looking for a stream at +// the _current_ seek point (ftell); the stream will be of length 'len' bytes. +// on failure, returns NULL and sets *error. note that stb_vorbis must "own" +// this stream; if you seek it in between calls to stb_vorbis, it will become +// confused. +#endif + +extern int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number); +extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number); +// NOT WORKING YET +// these functions seek in the Vorbis file to (approximately) 'sample_number'. +// after calling seek_frame(), the next call to get_frame_*() will include +// the specified sample. after calling stb_vorbis_seek(), the next call to +// stb_vorbis_get_samples_* will start with the specified sample. If you +// do not need to seek to EXACTLY the target sample when using get_samples_*, +// you can also use seek_frame(). + +extern void stb_vorbis_seek_start(stb_vorbis *f); +// this function is equivalent to stb_vorbis_seek(f,0), but it +// actually works + +extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f); +extern float stb_vorbis_stream_length_in_seconds(stb_vorbis *f); +// these functions return the total length of the vorbis stream + +extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output); +// decode the next frame and return the number of samples. the number of +// channels returned are stored in *channels (which can be NULL--it is always +// the same as the number of channels reported by get_info). *output will +// contain an array of float* buffers, one per channel. These outputs will +// be overwritten on the next call to stb_vorbis_get_frame_*. +// +// You generally should not intermix calls to stb_vorbis_get_frame_*() +// and stb_vorbis_get_samples_*(), since the latter calls the former. + +#ifndef STB_VORBIS_NO_INTEGER_CONVERSION +extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts); +extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples); +#endif +// decode the next frame and return the number of samples per channel. the +// data is coerced to the number of channels you request according to the +// channel coercion rules (see below). You must pass in the size of your +// buffer(s) so that stb_vorbis will not overwrite the end of the buffer. +// The maximum buffer size needed can be gotten from get_info(); however, +// the Vorbis I specification implies an absolute maximum of 4096 samples +// per channel. Note that for interleaved data, you pass in the number of +// shorts (the size of your array), but the return value is the number of +// samples per channel, not the total number of samples. + +// Channel coercion rules: +// Let M be the number of channels requested, and N the number of channels present, +// and Cn be the nth channel; let stereo L be the sum of all L and center channels, +// and stereo R be the sum of all R and center channels (channel assignment from the +// vorbis spec). +// M N output +// 1 k sum(Ck) for all k +// 2 * stereo L, stereo R +// k l k > l, the first l channels, then 0s +// k l k <= l, the first k channels +// Note that this is not _good_ surround etc. mixing at all! It's just so +// you get something useful. + +extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats); +extern int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples); +// gets num_samples samples, not necessarily on a frame boundary--this requires +// buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES. +// Returns the number of samples stored per channel; it may be less than requested +// at the end of the file. If there are no more samples in the file, returns 0. + +#ifndef STB_VORBIS_NO_INTEGER_CONVERSION +extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts); +extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples); +#endif +// gets num_samples samples, not necessarily on a frame boundary--this requires +// buffering so you have to supply the buffers. Applies the coercion rules above +// to produce 'channels' channels. Returns the number of samples stored per channel; +// it may be less than requested at the end of the file. If there are no more +// samples in the file, returns 0. + +#endif + +//////// ERROR CODES + +enum STBVorbisError +{ + VORBIS__no_error, + + VORBIS_need_more_data=1, // not a real error + + VORBIS_invalid_api_mixing, // can't mix API modes + VORBIS_outofmem, // not enough memory + VORBIS_feature_not_supported, // uses floor 0 + VORBIS_too_many_channels, // STB_VORBIS_MAX_CHANNELS is too small + VORBIS_file_open_failure, // fopen() failed + VORBIS_seek_without_length, // can't seek in unknown-length file + + VORBIS_unexpected_eof=10, // file is truncated? + VORBIS_seek_invalid, // seek past EOF + + // decoding errors (corrupt/invalid stream) -- you probably + // don't care about the exact details of these + + // vorbis errors: + VORBIS_invalid_setup=20, + VORBIS_invalid_stream, + + // ogg errors: + VORBIS_missing_capture_pattern=30, + VORBIS_invalid_stream_structure_version, + VORBIS_continued_packet_flag_invalid, + VORBIS_incorrect_stream_serial_number, + VORBIS_invalid_first_page, + VORBIS_bad_packet_type, + VORBIS_cant_find_last_page, + VORBIS_seek_failed, +}; + + +#ifdef __cplusplus +} +#endif + +#endif // STB_VORBIS_INCLUDE_STB_VORBIS_H +// +// HEADER ENDS HERE +// +////////////////////////////////////////////////////////////////////////////// + diff --git a/ext/native/ext/vjson/CMakeLists.txt b/ext/native/ext/vjson/CMakeLists.txt new file mode 100644 index 0000000000..b8d19dc34f --- /dev/null +++ b/ext/native/ext/vjson/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 2.6) + +#if(UNIX) +add_definitions(-fPIC) +add_definitions(-g) +add_definitions(-O2) +add_definitions(-Wall) +#endif(UNIX) + +add_library(vjson json.cpp block_allocator.cpp) diff --git a/ext/native/ext/vjson/block_allocator.cpp b/ext/native/ext/vjson/block_allocator.cpp new file mode 100644 index 0000000000..f85de3a5ba --- /dev/null +++ b/ext/native/ext/vjson/block_allocator.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include "block_allocator.h" + +block_allocator::block_allocator(size_t blocksize) + : m_head(0), m_blocksize(blocksize) +{ +} + +block_allocator::~block_allocator() +{ + while (m_head) + { + block *temp = m_head->next; + ::free(m_head); + m_head = temp; + } +} + +void block_allocator::swap(block_allocator &rhs) +{ + std::swap(m_blocksize, rhs.m_blocksize); + std::swap(m_head, rhs.m_head); +} + +void *block_allocator::malloc(size_t size) +{ + if ((m_head && m_head->used + size > m_head->size) || !m_head) + { + // calc needed size for allocation + size_t alloc_size = std::max(sizeof(block) + size, m_blocksize); + + // create new block + char *buffer = (char *)::malloc(alloc_size); + block *b = reinterpret_cast(buffer); + b->size = alloc_size; + b->used = sizeof(block); + b->buffer = buffer; + b->next = m_head; + m_head = b; + } + + void *ptr = m_head->buffer + m_head->used; + m_head->used += size; + return ptr; +} + +void block_allocator::free() +{ + block_allocator(0).swap(*this); +} diff --git a/ext/native/ext/vjson/block_allocator.h b/ext/native/ext/vjson/block_allocator.h new file mode 100644 index 0000000000..90a81814f6 --- /dev/null +++ b/ext/native/ext/vjson/block_allocator.h @@ -0,0 +1,35 @@ +#ifndef BLOCK_ALLOCATOR_H +#define BLOCK_ALLOCATOR_H + +class block_allocator +{ +public: + block_allocator(size_t blocksize); + ~block_allocator(); + + // exchange contents with rhs + void swap(block_allocator &rhs); + + // allocate memory + void *malloc(size_t size); + + // free all allocated blocks + void free(); + +private: + struct block + { + size_t size; + size_t used; + char *buffer; + block *next; + }; + + block *m_head; + size_t m_blocksize; + + block_allocator(const block_allocator &); + block_allocator &operator=(block_allocator &); +}; + +#endif diff --git a/ext/native/ext/vjson/json.cpp b/ext/native/ext/vjson/json.cpp new file mode 100644 index 0000000000..bdd7bb1db4 --- /dev/null +++ b/ext/native/ext/vjson/json.cpp @@ -0,0 +1,646 @@ +#include +#include +#include +#include "json.h" +#include "file/easy_file.h" +#include "file/zip_read.h" +#include "file/vfs.h" + +// true if character represent a digit +#define IS_DIGIT(c) (c >= '0' && c <= '9') + +int json_value::numChildren() const { + int count = 0; + const json_value *c = first_child; + while (c) { + count++; + c = c->next_sibling; + } + return count; +} + +// only works right for first child. includes itself in count. +int json_value::numSiblings() const { + const json_value *s = next_sibling; + int count = 1; + while (s) { + count++; + s = s->next_sibling; + } + return count; +} + +const json_value *json_value::get(const char *child_name) const { + if (!this) { + FLOG("Cannot get from null node"); + return 0; + } + if (!child_name) { + FLOG("JSON: Cannot get from null child name"); + return 0; + } + const json_value *c = first_child; + while (c) { + if (!strcmp(c->name, child_name)) { + return c; + } + c = c->next_sibling; + } + return 0; +} + +const json_value *json_value::get(const char *child_name, json_type type) const { + const json_value *v = get(child_name); + if (v && type == v->type) + return v; + else + return 0; +} + +const char *json_value::getStringOrDie(const char *child_name) const { + const json_value *val = get(child_name, JSON_STRING); + if (val) + return val->string_value; + else + FLOG("String '%s' missing from node '%s'", child_name, this->name); + return 0; +} + +const char *json_value::getString(const char *child_name, const char *default_value) const { + const json_value *val = get(child_name, JSON_STRING); + if (!val) + return default_value; + return val->string_value; +} + +bool json_value::getStringVector(std::vector *vec) const { + vec->clear(); + if (type == JSON_ARRAY) { + json_value *val = first_child; + while (val) { + if (val->type == JSON_STRING) { + vec->push_back(val->string_value); + } + } + return true; + } else { + return false; + } +} + +float json_value::getFloat(const char *child_name) const { + return get(child_name, JSON_FLOAT)->float_value; +} + +float json_value::getFloat(const char *child_name, float default_value) const { + const json_value *val = get(child_name, JSON_FLOAT); + if (!val) { + // Let's try int. + val = get(child_name, JSON_INT); + if (!val) + return default_value; + return val->int_value; + } + return val->float_value; +} + +int json_value::getInt(const char *child_name) const { + return get(child_name, JSON_INT)->int_value; +} + +int json_value::getInt(const char *child_name, int default_value) const { + const json_value *val = get(child_name, JSON_INT); + if (!val) + return default_value; + return val->int_value; +} + +bool json_value::getBool(const char *child_name) const { + return get(child_name, JSON_BOOL)->int_value != 0 ? true : false; +} + +bool json_value::getBool(const char *child_name, bool default_value) const { + const json_value *val = get(child_name, JSON_BOOL); + if (!val) + return default_value; + return val->int_value != 0 ? true : false; +} + + +// convert string to integer +char *atoi(char *first, char *last, int *out) +{ + int sign = 1; + if (first != last) + { + if (*first == '-') + { + sign = -1; + ++first; + } + else if (*first == '+') + { + ++first; + } + } + + int result = 0; + for (; first != last && IS_DIGIT(*first); ++first) + { + result = 10 * result + (*first - '0'); + } + *out = result * sign; + + return first; +} + +// convert hexadecimal string to unsigned integer +char *hatoui(char *first, char *last, unsigned int *out) +{ + unsigned int result = 0; + for (; first != last; ++first) + { + int digit; + if (IS_DIGIT(*first)) + { + digit = *first - '0'; + } + else if (*first >= 'a' && *first <= 'f') + { + digit = *first - 'a' + 10; + } + else if (*first >= 'A' && *first <= 'F') + { + digit = *first - 'A' + 10; + } + else + { + break; + } + result = 16 * result + digit; + } + *out = result; + + return first; +} + +// convert string to floating point +char *atof(char *first, char *last, float *out) +{ + // sign + float sign = 1; + if (first != last) + { + if (*first == '-') + { + sign = -1; + ++first; + } + else if (*first == '+') + { + ++first; + } + } + + // integer part + float result = 0; + for (; first != last && IS_DIGIT(*first); ++first) + { + result = 10 * result + (*first - '0'); + } + + // fraction part + if (first != last && *first == '.') + { + ++first; + + float inv_base = 0.1f; + for (; first != last && IS_DIGIT(*first); ++first) + { + result += (*first - '0') * inv_base; + inv_base *= 0.1f; + } + } + + // result w\o exponent + result *= sign; + + // exponent + bool exponent_negative = false; + int exponent = 0; + if (first != last && (*first == 'e' || *first == 'E')) + { + ++first; + + if (*first == '-') + { + exponent_negative = true; + ++first; + } + else if (*first == '+') + { + ++first; + } + + for (; first != last && IS_DIGIT(*first); ++first) + { + exponent = 10 * exponent + (*first - '0'); + } + } + + if (exponent) + { + float power_of_ten = 10; + for (; exponent > 1; exponent--) + { + power_of_ten *= 10; + } + + if (exponent_negative) + { + result /= power_of_ten; + } + else + { + result *= power_of_ten; + } + } + + *out = result; + + return first; +} + +json_value *json_alloc(block_allocator *allocator) +{ + json_value *value = (json_value *)allocator->malloc(sizeof(json_value)); + memset(value, 0, sizeof(json_value)); + return value; +} + +void json_append(json_value *lhs, json_value *rhs) +{ + rhs->parent = lhs; + if (lhs->last_child) + { + lhs->last_child = lhs->last_child->next_sibling = rhs; + } + else + { + lhs->first_child = lhs->last_child = rhs; + } +} + +#define ERROR(it, desc)\ + *error_pos = it;\ + *error_desc = (char *)desc;\ + *error_line = 1 - escaped_newlines;\ + for (char *c = it; c != source; --c)\ + if (*c == '\n') ++*error_line;\ + return 0 + +#define CHECK_TOP() if (!top) {ERROR(it, "Unexpected character");} + +json_value *json_parse(char *source, char **error_pos, char **error_desc, int *error_line, block_allocator *allocator) +{ + json_value *root = 0; + json_value *top = 0; + + char *name = 0; + char *it = source; + + int escaped_newlines = 0; + + while (*it) + { + switch (*it) + { + case '{': + case '[': + { + // create new value + json_value *object = json_alloc(allocator); + + // name + object->name = name; + name = 0; + + // type + object->type = (*it == '{') ? JSON_OBJECT : JSON_ARRAY; + + // skip open character + ++it; + + // set top and root + if (top) + { + json_append(top, object); + } + else if (!root) + { + root = object; + } + else + { + ERROR(it, "Second root. Only one root allowed"); + } + top = object; + } + break; + + case '}': + case ']': + { + if (!top || top->type != ((*it == '}') ? JSON_OBJECT : JSON_ARRAY)) + { + ERROR(it, "Mismatch closing brace/bracket"); + } + + // skip close character + ++it; + + // set top + top = top->parent; + } + break; + + case ':': + if (!top || top->type != JSON_OBJECT) + { + ERROR(it, "Unexpected character (no top level)"); + } + ++it; + break; + + case ',': + CHECK_TOP(); + ++it; + break; + + case '"': + { + CHECK_TOP(); + + // skip '"' character + ++it; + + char *first = it; + char *last = it; + while (*it) + { + if ((unsigned char)*it < '\x20') + { + ERROR(first, "Control characters not allowed in strings"); + } + else if (*it == '\\') + { + switch (it[1]) + { + case '"': + *last = '"'; + break; + case '\\': + *last = '\\'; + break; + case '/': + *last = '/'; + break; + case 'b': + *last = '\b'; + break; + case 'f': + *last = '\f'; + break; + case 'n': + *last = '\n'; + ++escaped_newlines; + break; + case 'r': + *last = '\r'; + break; + case 't': + *last = '\t'; + break; + case 'u': + { + unsigned int codepoint; + if (hatoui(it + 2, it + 6, &codepoint) != it + 6) + { + ERROR(it, "Bad unicode codepoint"); + } + + if (codepoint <= 0x7F) + { + *last = (char)codepoint; + } + else if (codepoint <= 0x7FF) + { + *last++ = (char)(0xC0 | (codepoint >> 6)); + *last = (char)(0x80 | (codepoint & 0x3F)); + } + else if (codepoint <= 0xFFFF) + { + *last++ = (char)(0xE0 | (codepoint >> 12)); + *last++ = (char)(0x80 | ((codepoint >> 6) & 0x3F)); + *last = (char)(0x80 | (codepoint & 0x3F)); + } + } + it += 4; + break; + default: + ERROR(first, "Unrecognized escape sequence"); + } + + ++last; + it += 2; + } + else if (*it == '"') + { + *last = 0; + ++it; + break; + } + else + { + *last++ = *it++; + } + } + + if (!name && top->type == JSON_OBJECT) + { + // field name in object + name = first; + } + else + { + // new string value + json_value *object = json_alloc(allocator); + + object->name = name; + name = 0; + + object->type = JSON_STRING; + object->string_value = first; + + json_append(top, object); + } + } + break; + + case 'n': + case 't': + case 'f': + { + CHECK_TOP(); + + // new null/bool value + json_value *object = json_alloc(allocator); + + object->name = name; + name = 0; + + // null + if (it[0] == 'n' && it[1] == 'u' && it[2] == 'l' && it[3] == 'l') + { + object->type = JSON_NULL; + it += 4; + } + // true + else if (it[0] == 't' && it[1] == 'r' && it[2] == 'u' && it[3] == 'e') + { + object->type = JSON_BOOL; + object->int_value = 1; + it += 4; + } + // false + else if (it[0] == 'f' && it[1] == 'a' && it[2] == 'l' && it[3] == 's' && it[4] == 'e') + { + object->type = JSON_BOOL; + object->int_value = 0; + it += 5; + } + else + { + ERROR(it, "Unknown identifier"); + } + + json_append(top, object); + } + break; + + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + CHECK_TOP(); + + // new number value + json_value *object = json_alloc(allocator); + + object->name = name; + name = 0; + + object->type = JSON_INT; + + char *first = it; + while (*it != '\x20' && *it != '\x9' && *it != '\xD' && *it != '\xA' && *it != ',' && *it != ']' && *it != '}') + { + if (*it == '.' || *it == 'e' || *it == 'E') + { + object->type = JSON_FLOAT; + } + ++it; + } + + if (object->type == JSON_INT && atoi(first, it, &object->int_value) != it) + { + ERROR(first, "Bad integer number"); + } + + if (object->type == JSON_FLOAT && atof(first, it, &object->float_value) != it) + { + ERROR(first, "Bad float number"); + } + + json_append(top, object); + } + break; + + default: + ERROR(it, "Unexpected character (unknown)"); + } + + // skip white space + while (*it == '\x20' || *it == '\x9' || *it == '\xD' || *it == '\xA') + { + ++it; + } + } + + if (top) + { + ERROR(it, "Not all objects/arrays have been properly closed"); + } + + return root; +} + +#define IDENT(n) for (int i = 0; i < n; ++i) printf(" ") + +void json_print(json_value *value, int ident) +{ + IDENT(ident); + if (value->name) printf("\"%s\" = ", value->name); + switch(value->type) + { + case JSON_NULL: + printf("null\n"); + break; + case JSON_OBJECT: + case JSON_ARRAY: + printf(value->type == JSON_OBJECT ? "{\n" : "[\n"); + for (json_value *it = value->first_child; it; it = it->next_sibling) + { + json_print(it, ident + 1); + } + IDENT(ident); + printf(value->type == JSON_OBJECT ? "}\n" : "]\n"); + break; + case JSON_STRING: + printf("\"%s\"\n", value->string_value); + break; + case JSON_INT: + printf("%d\n", value->int_value); + break; + case JSON_FLOAT: + printf("%f\n", value->float_value); + break; + case JSON_BOOL: + printf(value->int_value ? "true\n" : "false\n"); + break; + } +} + +JsonReader::JsonReader(const std::string &filename) : alloc_(1 << 12), root_(0) { + size_t buf_size; + buffer_ = (char *)VFSReadFile(filename.c_str(), &buf_size); + if (buffer_) { + parse(); + } else { + // Okay, try to read on the local file system + buffer_ = (char *)ReadLocalFile(filename.c_str(), &buf_size); + if (buffer_) { + parse(); + } else { + ELOG("Failed to read json %s", filename.c_str()); + } + } +} diff --git a/ext/native/ext/vjson/json.h b/ext/native/ext/vjson/json.h new file mode 100644 index 0000000000..792ab1cba4 --- /dev/null +++ b/ext/native/ext/vjson/json.h @@ -0,0 +1,113 @@ +#pragma once + +#include +#include +#include +#include "base/logging.h" +#include "block_allocator.h" +#include "file/vfs.h" + +enum json_type { + JSON_NULL, + JSON_OBJECT, + JSON_ARRAY, + JSON_STRING, + JSON_INT, + JSON_FLOAT, + JSON_BOOL, +}; + +struct json_value { + json_value() {} + + json_value *parent; + json_value *next_sibling; + json_value *first_child; + json_value *last_child; + + char *name; + union + { + char *string_value; + int int_value; + float float_value; + }; + + json_type type; + + int numChildren() const; + int numSiblings() const; // num siblings *after* this one only + const json_value *get(const char *child_name) const; + const json_value *get(const char *child_name, json_type type) const; + const json_value *getArray(const char *child_name) const { + return get(child_name, JSON_ARRAY); + } + const json_value *getDict(const char *child_name) const { + return get(child_name, JSON_OBJECT); + } + const char *getStringOrDie(const char *child_name) const; + const char *getString(const char *child_name, const char *default_value) const; + bool getStringVector(std::vector *vec) const; + float getFloat(const char *child_name) const; + float getFloat(const char *child_name, float default_value) const; + int getInt(const char *child_name) const; + int getInt(const char *child_name, int default_value) const; + bool getBool(const char *child_name) const; + bool getBool(const char *child_name, bool default_value) const; + + bool hasChild(const char *child_name, json_type child_type) const { + return get(child_name, child_type) != 0; + } + +private: + DISALLOW_COPY_AND_ASSIGN(json_value); +}; + +// low level interface +json_value *json_parse(char *source, char **error_pos, char **error_desc, int *error_line, block_allocator *allocator); +void json_print(json_value *value, int ident = 0); + +// Easy-wrapper +class JsonReader { +public: + JsonReader(const std::string &filename); + JsonReader(const char *data, size_t size) : alloc_(1 << 12) { + buffer_ = (char *)malloc(size + 1); + memcpy(buffer_, data, size); + buffer_[size] = 0; + parse(); + } + + ~JsonReader() { + if (buffer_) + free(buffer_); + } + + bool ok() const { return root_ != 0; } + + json_value *root() { return root_; } + const json_value *root() const { return root_; } + + void print() { + json_print(root_); + } + +private: + bool parse() { + char *error_pos; + char *error_desc; + int error_line; + root_ = json_parse((char *)buffer_, &error_pos, &error_desc, &error_line, &alloc_); + if (!root_) { + ELOG("Error at (%i): %s\n%s\n\n", error_line, error_desc, error_pos); + return false; + } + return true; + } + + char *buffer_; + block_allocator alloc_; + json_value *root_; + + DISALLOW_COPY_AND_ASSIGN(JsonReader); +}; diff --git a/ext/native/ext/vjson/main.cpp b/ext/native/ext/vjson/main.cpp new file mode 100644 index 0000000000..c0658c3ae0 --- /dev/null +++ b/ext/native/ext/vjson/main.cpp @@ -0,0 +1,118 @@ +#include +#include +#include "json.h" + +void populate_sources(const char *filter, std::vector > &sources) +{ + char filename[256]; + for (int i = 1; i < 64; ++i) + { + sprintf(filename, filter, i); + FILE *fp = fopen(filename, "rb"); + if (fp) + { + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + fseek(fp, 0, SEEK_SET); + std::vector buffer(size + 1); + fread (&buffer[0], 1, size, fp); + fclose(fp); + sources.push_back(buffer); + } + else + { + break; + } + } + + printf("Loaded %d json files\n", sources.size()); +} + +#define IDENT(n) for (int i = 0; i < n; ++i) printf(" ") + +void print(json_value *value, int ident = 0) +{ + IDENT(ident); + if (value->name) printf("\"%s\" = ", value->name); + switch(value->type) + { + case JSON_NULL: + printf("null\n"); + break; + case JSON_OBJECT: + case JSON_ARRAY: + printf(value->type == JSON_OBJECT ? "{\n" : "[\n"); + for (json_value *it = value->first_child; it; it = it->next_sibling) + { + print(it, ident + 1); + } + IDENT(ident); + printf(value->type == JSON_OBJECT ? "}\n" : "]\n"); + break; + case JSON_STRING: + printf("\"%s\"\n", value->string_value); + break; + case JSON_INT: + printf("%d\n", value->int_value); + break; + case JSON_FLOAT: + printf("%f\n", value->float_value); + break; + case JSON_BOOL: + printf(value->int_value ? "true\n" : "false\n"); + break; + } +} + +bool parse(char *source) +{ + char *errorPos = 0; + char *errorDesc = 0; + int errorLine = 0; + block_allocator allocator(1 << 10); + + json_value *root = json_parse(source, &errorPos, &errorDesc, &errorLine, &allocator); + if (root) + { + print(root); + return true; + } + + printf("Error at line %d: %s\n%s\n\n", errorLine, errorDesc, errorPos); + return false; +} + +int main(int argc, char **argv) +{ + // Fail + printf("===FAIL===\n\n"); + std::vector > sources; + populate_sources("test/fail%d.json", sources); + int passed = 0; + for (size_t i = 0; i < sources.size(); ++i) + { + printf("Parsing %d\n", i + 1); + if (parse(&sources[i][0])) + { + ++passed; + } + } + printf("Passed %d from %d tests\n", passed, sources.size()); + + // Pass + sources.clear(); + printf("\n===PASS===\n\n"); + populate_sources("test/pass%d.json", sources); + passed = 0; + for (size_t i = 0; i < sources.size(); ++i) + { + printf("Parsing %d\n", i + 1); + if (parse(&sources[i][0])) + { + ++passed; + } + } + printf("Passed %d from %d tests\n", passed, sources.size()); + + return 0; +} diff --git a/ext/native/file/CMakeLists.txt b/ext/native/file/CMakeLists.txt new file mode 100644 index 0000000000..794d6660c4 --- /dev/null +++ b/ext/native/file/CMakeLists.txt @@ -0,0 +1,15 @@ +set(SRCS + easy_file.cpp + chunk_file.cpp + zip_read.cpp + file_util.cpp + dialog.cpp) + +set(SRCS ${SRCS}) + +add_library(file STATIC ${SRCS}) +target_link_libraries(file general zip) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp new file mode 100644 index 0000000000..0e39a9799f --- /dev/null +++ b/ext/native/file/chunk_file.cpp @@ -0,0 +1,287 @@ +#include "base/logging.h" +#include "file/chunk_file.h" +#include "file/zip_read.h" + +//#define CHUNKDEBUG + +ChunkFile::ChunkFile(const char *filename, bool _read) { + data=0; + fn = filename; + fastMode=false; + numLevels=0; + read=_read; + pos=0; + didFail=false; + + fastMode = read ? true : false; + + if (fastMode) { + size_t size; + data = (uint8_t *)VFSReadFile(filename, &size); + if (!data) { + ELOG("Chunkfile fail: %s", filename); + didFail = true; + return; + } + eof = (int)size; + return; + } + + if (file.open(filename, FILE_WRITE)) { + didFail=false; + eof=file.fileSize(); + } else { + didFail=true; + return; + } +} + +ChunkFile::ChunkFile(const uint8_t *read_data, int data_size) { + data = new uint8_t[data_size]; + memcpy(data, read_data, data_size); + fastMode = true; + numLevels = 0; + read = true; + pos = 0; + didFail = false; + eof = data_size; +} + +ChunkFile::~ChunkFile() { + if (fastMode) + delete [] data; + else + file.close(); +} + +int ChunkFile::readInt() { + if (data && pos>8, id>>16, id>>24); +#endif + stack[numLevels]=temp; + seekTo(stack[numLevels].parentStartLocation); + return false; + } + + //descend into it + //pos was set inside the loop above + eof = stack[numLevels].startLocation + stack[numLevels].length; + numLevels++; +#ifdef CHUNKDEBUG + ILOG("Descended into %c%c%c%c", id, id>>8, id>>16, id>>24); +#endif + return true; + } else { +#ifndef DEMO_VERSION //if this is missing.. heheh + //write a chunk id, and prepare for filling in length later + writeInt(id); + writeInt(0); //will be filled in by Ascend + stack[numLevels].startLocation=pos; + numLevels++; + return true; +#else + return true; +#endif + } +} + +void ChunkFile::seekTo(int _pos) { + if (!fastMode) + file.seekBeg(_pos); + pos=_pos; +} + +//let's ascend out +void ChunkFile::ascend() { + if (read) { + //ascend, and restore information + numLevels--; + seekTo(stack[numLevels].parentStartLocation); + eof = stack[numLevels].parentEOF; +#ifdef CHUNKDEBUG + int id = stack[numLevels].ID; + ILOG("Ascended out of %c%c%c%c", id, id>>8, id>>16, id>>24); +#endif + } else { + numLevels--; + //now fill in the written length automatically + int posNow = pos; + seekTo(stack[numLevels].startLocation - 4); + writeInt(posNow-stack[numLevels].startLocation); + seekTo(posNow); + } +} + +//read a block +void ChunkFile::readData(void *what, int count) { + if (fastMode) + memcpy(what, data + pos, count); + else + file.read(what,count); + + pos+=count; + char temp[4]; //discarded + count &= 3; + if (count) { + count=4-count; + if (!fastMode) + file.read(temp,count); + pos+=count; + } +} + +//write a block +void ChunkFile::writeData(const void *what, int count) { + file.write(what, count); + pos+=count; + char temp[5]={0,0,0,0,0}; + count &= 3; + if (count) + { + count=4-count; + file.write(temp,count); + pos+=count; + } +} + +/* +void ChunkFile::writeWString(String str) { + wchar_t *text; + int len=str.length(); +#ifdef UNICODE +#error + text = str.getPointer(); +#else + text = new wchar_t[len+1]; + str.toUnicode(text); +#endif + writeInt(len); + writeData((char *)text, len * sizeof(wchar_t)); +#ifndef UNICODE + delete [] text; +#endif +} +*/ + +// Takes utf-8 +void ChunkFile::writeWString(const std::string &str) { + unsigned short *text; + int len = (int)str.length(); + text = new unsigned short[len+1]; + for (int i = 0; i < len; i++) + text[i] = str[i]; + text[len]=0; + writeInt(len); + writeData((char *)text, len * sizeof(unsigned short)); + delete [] text; +} + +static void toUnicode(const std::string &str, uint16_t *t) { + for (size_t i = 0; i < str.size(); i++) { + *t++ = str[i]; + } + *t++ = '\0'; +} + +static std::string fromUnicode(const uint16_t *src, int len) { + std::string str; + str.resize(len); + for (int i = 0; i < len; i++) { + str[i] = src[i] > 255 ? ' ' : src[i]; + } + return str; +} + +std::string ChunkFile::readWString() { + int len=readInt(); + uint16_t *text = new uint16_t[len+1]; + readData((char *)text, len*sizeof(uint16_t)); + text[len] = 0; + std::string temp = fromUnicode(text, len); + delete [] text; + return temp; +} + +void ChunkFile::writeString(const std::string &str) { + uint16_t *text; + int len = (int)str.size(); + text=new uint16_t[len+1]; + toUnicode(str, text); + writeInt(len); + writeData((char *)text,len*sizeof(uint16_t)); + delete [] text; +} + +std::string ChunkFile::readString() { + int len=readInt(); + uint16_t *text = new uint16_t[len+1]; + readData((char *)text,len*sizeof(uint16_t)); + text[len]=0; + std::string temp = fromUnicode(text, len); + delete [] text; + return temp; +} +int ChunkFile::getCurrentChunkSize() { + if (numLevels) + return stack[numLevels-1].length; + else + return 0; +} + diff --git a/ext/native/file/chunk_file.h b/ext/native/file/chunk_file.h new file mode 100644 index 0000000000..e227a69f7c --- /dev/null +++ b/ext/native/file/chunk_file.h @@ -0,0 +1,72 @@ +#pragma once + +// RIFF file format reader/writer. Very old code, basically a total mess but it still works. +// Has nothing to do with the ChunkFile.h used in Dolphin or PPSSPP. +// LAMEFile should be removed. + +// TO REMEMBER WHEN USING: + +// EITHER a chunk contains ONLY data +// OR it contains ONLY other chunks +// otherwise the scheme breaks. + +#include + +#include "base/basictypes.h" +#include "file/easy_file.h" + +inline uint32_t flipID(uint32_t id) { + return ((id>>24)&0xFF) | ((id>>8)&0xFF00) | ((id<<8)&0xFF0000) | ((id<<24)&0xFF000000); +} + +class ChunkFile { +public: + ChunkFile(const char *filename, bool _read); + ChunkFile(const uint8_t *read_data, int data_size); + + ~ChunkFile(); + + bool descend(uint32_t id); + void ascend(); + + int readInt(); + void readInt(int &i) {i = readInt();} + void readData(void *data, int count); + // String readWString(); + std::string readWString(); + + void writeString(const std::string &str); + std::string readString(); + + void writeInt(int i); + //void writeWString(String str); + void writeWString(const std::string &str); + void writeData(const void *data, int count); + + int getCurrentChunkSize(); + bool failed() const { return didFail; } + std::string filename() const { return fn; } + +private: + std::string fn; + LAMEFile file; + struct ChunkInfo { + int startLocation; + int parentStartLocation; + int parentEOF; + unsigned int ID; + int length; + }; + ChunkInfo stack[8]; + int numLevels; + + uint8_t *data; + int pos; + int eof; + bool fastMode; + bool read; + bool didFail; + + void seekTo(int _pos); + int getPos() const {return pos;} +}; diff --git a/ext/native/file/dialog.cpp b/ext/native/file/dialog.cpp new file mode 100644 index 0000000000..7a8ab45111 --- /dev/null +++ b/ext/native/file/dialog.cpp @@ -0,0 +1,89 @@ +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include + +#include "util/text/utf8.h" + +// For desktop operating systems only. Stubbed out on Android. +// Simplified as this will only be used in utilities / temp code. +// An false returned means cancel; +bool OpenFileDialog(const char *title, const char *extension, std::string *filename) +{ + std::wstring wtitle = ConvertUTF8ToWString(std::string(title)); + std::wstring wext = ConvertUTF8ToWString(std::string(extension)); + + OPENFILENAME of; + memset(&of, 0, sizeof(of)); + wchar_t buffer[512] = {0}; + of.lStructSize = sizeof(OPENFILENAME); + of.hInstance = 0; + of.hwndOwner = GetActiveWindow(); + + // These weird strings with zeroes in them can't be dealt with using normal string + // functions, so here we go - evil hackery. + wchar_t filter[256] = L"XXX files\0*.XXX\0\0"; + memcpy(filter, wext.c_str(), 3 * sizeof(wchar_t)); + memcpy(filter + 12, wext.c_str(), 3 * sizeof(wchar_t)); + of.lpstrFilter = filter; + + of.lpstrDefExt = wext.c_str(); + of.lpstrFile = buffer; + of.nMaxFile = 511; + + of.Flags = OFN_FILEMUSTEXIST; + if (!GetOpenFileName(&of)) return false; + *filename = ConvertWStringToUTF8(of.lpstrFile); + return true; +} + +bool SaveFileDialog(const char *title, const char *extension, std::string *filename) { + std::wstring wtitle = ConvertUTF8ToWString(std::string(title)); + std::wstring wext = ConvertUTF8ToWString(std::string(extension)); + + OPENFILENAME of; + memset(&of, 0, sizeof(of)); + wchar_t buffer[512] = {0}; + of.lStructSize = sizeof(OPENFILENAME); + of.hInstance = 0; + of.hwndOwner = GetActiveWindow(); + + // These weird strings with zeroes in them can't be dealt with using normal string + // functions, so here we go - evil hackery. + wchar_t filter[256] = L"XXX files\0*.XXX\0\0"; + memcpy(filter, wext.c_str(), 3 * sizeof(wchar_t)); + memcpy(filter + 12, wext.c_str(), 3 * sizeof(wchar_t)); + of.lpstrFilter = filter; + + of.lpstrDefExt = wext.c_str(); + of.lpstrFile = buffer; + of.nMaxFile = 511; + + of.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; + if (!GetSaveFileName(&of)) + return false; + *filename = ConvertWStringToUTF8(of.lpstrFile); + return true; +} + +#else + +#include +#include "base/basictypes.h" +#include "base/logging.h" + +bool OpenFileDialog(const char *title, const char *extension, std::string *filename) +{ + ELOG("Asked for OpenFileDialog, not present on this platform."); + return false; +} + +bool SaveFileDialog(const char *title, const char *extension, std::string *filename) +{ + ELOG("Asked for SaveFileDialog, not present on this platform."); + return false; +} + +#endif diff --git a/ext/native/file/dialog.h b/ext/native/file/dialog.h new file mode 100644 index 0000000000..018b503e70 --- /dev/null +++ b/ext/native/file/dialog.h @@ -0,0 +1,10 @@ +#pragma once + +#pragma once + +#include + +#include "file/dialog.h" + +bool OpenFileDialog(const char *title, const char *extension, std::string *filename); +bool SaveFileDialog(const char *title, const char *extension, std::string *filename); diff --git a/ext/native/file/easy_file.cpp b/ext/native/file/easy_file.cpp new file mode 100644 index 0000000000..f34ef45a47 --- /dev/null +++ b/ext/native/file/easy_file.cpp @@ -0,0 +1,89 @@ +#include + +#include "base/basictypes.h" +#include "file/easy_file.h" + +LAMEFile::LAMEFile() : file_(NULL), isOpen(false), size_(0) { +} + +LAMEFile::~LAMEFile() { } + +bool LAMEFile::open(const char *filename, eFileMode mode) { + file_ = fopen(filename, mode == FILE_READ ? "rb" : "wb"); + + if (!file_) { + isOpen = false; + } else { + isOpen = true; + if (mode == FILE_READ) { + fseek(file_, 0, SEEK_END); + size_ = ftell(file_); + fseek(file_, 0, SEEK_SET); + } + } + return isOpen; +} + +void LAMEFile::close() { + if (isOpen) { + //close the file and reset variables + fclose(file_); + file_ = NULL; + isOpen=false; + } +} + +int LAMEFile::fileSize() { + if (!isOpen) //of course + return 0; + else + return size_; +} + +std::string LAMEFile::readAll() { + std::string s; + size_t size = fileSize(); + s.resize(size); + read(&s[0], size); + return s; +} + +int LAMEFile::write(const void *data, size_t size) { + if (isOpen) { + return (int)fwrite(data, 1, size, file_); //we return the number of bytes that actually got written + } else { + return 0; + } +} + +int LAMEFile::read(void *data, size_t size) { + if (isOpen) { + return (int)fread(data, 1, size, file_); + } else { + return 0; + } +} + +int LAMEFile::readInt() { + int temp; + if (read(&temp, sizeof(int))) + return temp; + else + return 0; +} + +void LAMEFile::writeInt(int i) { + write(&i, sizeof(int)); +} + +char LAMEFile::readChar() { + char temp; + if (read(&temp, sizeof(char))) + return temp; + else + return 0; +} + +void LAMEFile::writeChar(char i) { + write(&i,sizeof(char)); +} diff --git a/ext/native/file/easy_file.h b/ext/native/file/easy_file.h new file mode 100644 index 0000000000..fbc439adf9 --- /dev/null +++ b/ext/native/file/easy_file.h @@ -0,0 +1,58 @@ +#pragma once + +// A dumb wrapper around stdio, for convenience. Very old. + +#include +#include + +#include "base/basictypes.h" + + +// Raw file paths, does not go through VFS. + +enum eFileMode { + FILE_READ=5, + FILE_WRITE=6 +}; + +// TODO: Rename. +class LAMEFile { +public: + LAMEFile(); + virtual ~LAMEFile(); + + bool open(const char *filename, eFileMode mode); + bool open(std::string filename, eFileMode mode) { + return open(filename.c_str(), mode); + } + void close(); + + void writeInt(int i); + void writeChar(char i); + int write(const void *data, size_t size); + void write(const std::string &str) { + write((void *)str.data(), str.size()); + } + + int readInt(); + char readChar(); + int read(void *data, size_t size); + + std::string readAll(); + + int fileSize(); + + void seekBeg(int pos) { + if (isOpen) fseek(file_,pos,SEEK_SET); + } + void seekEnd(int pos) { + if (isOpen) fseek(file_,pos,SEEK_END); + } + void seekCurrent(int pos) { + if (isOpen) fseek(file_,pos,SEEK_CUR); + } +private: + FILE *file_; + bool isOpen; + int size_; +}; diff --git a/ext/native/file/fd_util.cpp b/ext/native/file/fd_util.cpp new file mode 100644 index 0000000000..f8f9fa7e86 --- /dev/null +++ b/ext/native/file/fd_util.cpp @@ -0,0 +1,122 @@ +#include "file/fd_util.h" + +#include +#include +#include +#ifndef _WIN32 +#include +#include +#else +#include +#include +#endif +#include + +#include "base/logging.h" + +namespace fd_util { + +// Slow as hell and should only be used for prototyping. +// Reads from a socket, up to an '\n'. This means that if the line ends +// with '\r', the '\r' will be returned. +ssize_t ReadLine(int fd, char *vptr, size_t buf_size) { + char *buffer = vptr; + size_t n; + for (n = 1; n < buf_size; n++) { + char c; + ssize_t rc; + if ((rc = read(fd, &c, 1)) == 1) { + *buffer++ = c; + if (c == '\n') + break; + } + else if (rc == 0) { + if (n == 1) + return 0; + else + break; + } + else { + if (errno == EINTR) + continue; + FLOG("Error in Readline()"); + } + } + + *buffer = 0; + return n; +} + +// Misnamed, it just writes raw data in a retry loop. +ssize_t WriteLine(int fd, const char *vptr, size_t n) { + const char *buffer = vptr; + size_t nleft = n; + + while (nleft > 0) { + int nwritten; + if ((nwritten = (int)write(fd, buffer, (unsigned int)nleft)) <= 0) { + if (errno == EINTR) + nwritten = 0; + else + FLOG("Error in Writeline()"); + } + nleft -= nwritten; + buffer += nwritten; + } + + return n; +} + +ssize_t WriteLine(int fd, const char *buffer) { + return WriteLine(fd, buffer, strlen(buffer)); +} + +ssize_t Write(int fd, const std::string &str) { + return WriteLine(fd, str.c_str(), str.size()); +} + +bool WaitUntilReady(int fd, double timeout) { + struct timeval tv; + tv.tv_sec = floor(timeout); + tv.tv_usec = (timeout - floor(timeout)) * 1000000.0; + + fd_set fds; + FD_ZERO(&fds); + FD_SET(fd, &fds); + // First argument to select is the highest socket in the set + 1. + int rval = select(fd + 1, &fds, NULL, NULL, &tv); + if (rval < 0) { + // Error calling select. + return false; + } else if (rval == 0) { + // Timeout. + return false; + } else { + // Socket is ready. + return true; + } +} + +void SetNonBlocking(int sock, bool non_blocking) { +#ifndef _WIN32 + int opts = fcntl(sock, F_GETFL); + if (opts < 0) { + perror("fcntl(F_GETFL)"); + ELOG("Error getting socket status while changing nonblocking status"); + } + if (non_blocking) { + opts = (opts | O_NONBLOCK); + } else { + opts = (opts & ~O_NONBLOCK); + } + + if (fcntl(sock, F_SETFL, opts) < 0) { + perror("fcntl(F_SETFL)"); + ELOG("Error setting socket nonblocking status"); + } +#else + WLOG("NonBlocking mode not supported on Win32"); +#endif +} + +} // fd_util diff --git a/ext/native/file/fd_util.h b/ext/native/file/fd_util.h new file mode 100644 index 0000000000..a38e59b357 --- /dev/null +++ b/ext/native/file/fd_util.h @@ -0,0 +1,27 @@ +#ifndef _FD_UTIL +#define _FD_UTIL + +#include +#include + +#include "base/basictypes.h" + +namespace fd_util { + +// Slow as hell and should only be used for prototyping. +ssize_t ReadLine(int fd, char *buffer, size_t buf_size); + +// Decently fast. +ssize_t WriteLine(int fd, const char *buffer, size_t buf_size); +ssize_t WriteLine(int fd, const char *buffer); +ssize_t Write(int fd, const std::string &str); + +// Returns true if the fd became ready, false if it didn't or +// if there was another error. +bool WaitUntilReady(int fd, double timeout); + +void SetNonBlocking(int fd, bool non_blocking); + +} // fd_util + +#endif // _FD_UTIL diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp new file mode 100644 index 0000000000..a173933eda --- /dev/null +++ b/ext/native/file/file_util.cpp @@ -0,0 +1,437 @@ +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#ifndef strcasecmp +#define strcasecmp _stricmp +#endif +#define fseeko _fseeki64 +#define ftello _ftelli64 +#else +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include "base/logging.h" +#include "base/basictypes.h" +#include "file/file_util.h" +#include "util/text/utf8.h" + +#if !defined(__linux__) && !defined(_WIN32) && !defined(__QNX__) +#define stat64 stat +#endif + +// Hack +#ifdef __SYMBIAN32__ +static inline int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { + struct dirent *readdir_entry; + + readdir_entry = readdir(dirp); + if (readdir_entry == NULL) { + *result = NULL; + return errno; + } + + *entry = *readdir_entry; + *result = entry; + return 0; +} +#endif + +FILE *openCFile(const std::string &filename, const char *mode) +{ +#if defined(_WIN32) && defined(UNICODE) + return _wfopen(ConvertUTF8ToWString(filename).c_str(), ConvertUTF8ToWString(mode).c_str()); +#else + return fopen(filename.c_str(), mode); +#endif +} + +bool writeStringToFile(bool text_file, const std::string &str, const char *filename) +{ + FILE *f = openCFile(filename, text_file ? "w" : "wb"); + if (!f) + return false; + size_t len = str.size(); + if (len != fwrite(str.data(), 1, str.size(), f)) + { + fclose(f); + return false; + } + fclose(f); + return true; +} + +bool writeDataToFile(bool text_file, const void* data, const unsigned int size, const char *filename) +{ + FILE *f = openCFile(filename, text_file ? "w" : "wb"); + if (!f) + return false; + size_t len = size; + if (len != fwrite(data, 1, len, f)) + { + fclose(f); + return false; + } + fclose(f); + return true; +} + +uint64_t GetSize(FILE *f) +{ + // This will only support 64-bit when large file support is available. + // That won't be the case on some versions of Android, at least. +#if defined(ANDROID) || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64) + int fd = fileno(f); + + off64_t pos = lseek64(fd, 0, SEEK_CUR); + off64_t size = lseek64(fd, 0, SEEK_END); + if (size != pos && lseek64(fd, pos, SEEK_SET) != pos) { + // Should error here. + return 0; + } + return size; +#else + uint64_t pos = ftello(f); + if (fseek(f, 0, SEEK_END) != 0) { + return 0; + } + uint64_t size = ftello(f); + // Reset the seek position to where it was when we started. + if (size != pos && fseeko(f, pos, SEEK_SET) != 0) { + // Should error here. + return 0; + } + return size; +#endif +} + +bool readFileToString(bool text_file, const char *filename, std::string &str) +{ + FILE *f = openCFile(filename, text_file ? "r" : "rb"); + if (!f) + return false; + size_t len = (size_t)GetSize(f); + char *buf = new char[len + 1]; + buf[fread(buf, 1, len, f)] = 0; + str = std::string(buf, len); + fclose(f); + delete [] buf; + return true; +} + + +bool readDataFromFile(bool text_file, unsigned char* &data, const unsigned int size, const char *filename) +{ + FILE *f = openCFile(filename, text_file ? "r" : "rb"); + if (!f) + return false; + size_t len = (size_t)GetSize(f); + if(len < size) { + fclose(f); + return false; + } + data[fread(data, 1, size, f)] = 0; + fclose(f); + return true; +} + + +#define DIR_SEP "/" +#define DIR_SEP_CHR '\\' + +#ifndef METRO + +// Remove any ending forward slashes from directory paths +// Modifies argument. +static void stripTailDirSlashes(std::string &fname) +{ + if (fname.length() > 1) + { + size_t i = fname.length() - 1; + while (fname[i] == DIR_SEP_CHR) + fname[i--] = '\0'; + } + return; +} + +// Returns true if file filename exists +bool exists(const std::string &filename) { +#ifdef _WIN32 + std::wstring wstr = ConvertUTF8ToWString(filename); + return GetFileAttributes(wstr.c_str()) != 0xFFFFFFFF; +#else + struct stat64 file_info; + + std::string copy(filename); + stripTailDirSlashes(copy); + + int result = stat64(copy.c_str(), &file_info); + + return (result == 0); +#endif +} + +// Returns true if filename is a directory +bool isDirectory(const std::string &filename) { + FileInfo info; + getFileInfo(filename.c_str(), &info); + return info.isDirectory; +} + +bool getFileInfo(const char *path, FileInfo *fileInfo) { + // TODO: Expand relative paths? + fileInfo->fullName = path; + +#ifdef _WIN32 + WIN32_FILE_ATTRIBUTE_DATA attrs; + if (!GetFileAttributesExW(ConvertUTF8ToWString(path).c_str(), GetFileExInfoStandard, &attrs)) { + fileInfo->size = 0; + fileInfo->isDirectory = false; + fileInfo->exists = false; + return false; + } + fileInfo->size = (uint64_t)attrs.nFileSizeLow | ((uint64_t)attrs.nFileSizeHigh << 32); + fileInfo->isDirectory = (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + fileInfo->isWritable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; + fileInfo->exists = true; +#else + struct stat64 file_info; + + std::string copy(path); + stripTailDirSlashes(copy); + + int result = stat64(copy.c_str(), &file_info); + + if (result < 0) { + WLOG("IsDirectory: stat failed on %s", path); + fileInfo->exists = false; + return false; + } + + fileInfo->isDirectory = S_ISDIR(file_info.st_mode); + fileInfo->isWritable = false; + fileInfo->size = file_info.st_size; + fileInfo->exists = true; + // HACK: approximation + if (file_info.st_mode & 0200) + fileInfo->isWritable = true; +#endif + return true; +} + +std::string getFileExtension(const std::string &fn) { + int pos = (int)fn.rfind("."); + if (pos < 0) return ""; + std::string ext = fn.substr(pos+1); + for (size_t i = 0; i < ext.size(); i++) { + ext[i] = tolower(ext[i]); + } + return ext; +} + +bool FileInfo::operator <(const FileInfo &other) const { + if (isDirectory && !other.isDirectory) + return true; + else if (!isDirectory && other.isDirectory) + return false; + if (strcasecmp(name.c_str(), other.name.c_str()) < 0) + return true; + else + return false; +} + +size_t getFilesInDir(const char *directory, std::vector *files, const char *filter, int flags) { + size_t foundEntries = 0; + std::set filters; + std::string tmp; + if (filter) { + while (*filter) { + if (*filter == ':') { + filters.insert(tmp); + tmp = ""; + } else { + tmp.push_back(*filter); + } + filter++; + } + } + if (tmp.size()) + filters.insert(tmp); +#ifdef _WIN32 + // Find the first file in the directory. + WIN32_FIND_DATA ffd; +#ifdef UNICODE + + HANDLE hFind = FindFirstFile((ConvertUTF8ToWString(directory) + L"\\*").c_str(), &ffd); +#else + HANDLE hFind = FindFirstFile((std::string(directory) + "\\*").c_str(), &ffd); +#endif + if (hFind == INVALID_HANDLE_VALUE) { + FindClose(hFind); + return 0; + } + // windows loop + do + { + const std::string virtualName = ConvertWStringToUTF8(ffd.cFileName); +#else + struct dirent_large { struct dirent entry; char padding[FILENAME_MAX+1]; }; + struct dirent_large diren; + struct dirent *result = NULL; + + //std::string directoryWithSlash = directory; + //if (directoryWithSlash.back() != '/') + // directoryWithSlash += "/"; + + DIR *dirp = opendir(directory); + if (!dirp) + return 0; + // non windows loop + while (!readdir_r(dirp, (dirent*) &diren, &result) && result) + { + const std::string virtualName(result->d_name); +#endif + // check for "." and ".." + if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || + ((virtualName[0] == '.') && (virtualName[1] == '.') && + (virtualName[2] == '\0'))) + continue; + + // Remove dotfiles (should be made optional?) + if (!(flags & GETFILES_GETHIDDEN) && virtualName[0] == '.') + continue; + + FileInfo info; + info.name = virtualName; + std::string dir = directory; + + // Only append a slash if there isn't one on the end. + size_t lastSlash = dir.find_last_of("/"); + if (lastSlash != (dir.length() - 1)) + dir.append("/"); + + info.fullName = dir + virtualName; + info.isDirectory = isDirectory(info.fullName); + info.exists = true; + info.size = 0; + if (!info.isDirectory) { + std::string ext = getFileExtension(info.fullName); + if (filter) { + if (filters.find(ext) == filters.end()) + continue; + } + } + + if (files) + files->push_back(info); + foundEntries++; +#ifdef _WIN32 + } while (FindNextFile(hFind, &ffd) != 0); + FindClose(hFind); +#else + } + closedir(dirp); +#endif + if (files) + std::sort(files->begin(), files->end()); + return foundEntries; +} + +void deleteFile(const char *file) +{ +#ifdef _WIN32 + if (!DeleteFile(ConvertUTF8ToWString(file).c_str())) { + ELOG("Error deleting %s: %i", file, GetLastError()); + } +#else + int err = unlink(file); + if (err) { + ELOG("Error unlinking %s: %i", file, err); + } +#endif +} + +void deleteDir(const char *dir) +{ +#ifdef _WIN32 + if (!RemoveDirectory(ConvertUTF8ToWString(dir).c_str())) { + ELOG("Error deleting directory %s: %i", dir, GetLastError()); + } +#else + rmdir(dir); +#endif +} + +#endif + +std::string getDir(const std::string &path) +{ + if (path == "/") + return path; + int n = (int)path.size() - 1; + while (n >= 0 && path[n] != '\\' && path[n] != '/') + n--; + std::string cutpath = n > 0 ? path.substr(0, n) : ""; + for (size_t i = 0; i < cutpath.size(); i++) + { + if (cutpath[i] == '\\') cutpath[i] = '/'; + } +#ifndef _WIN32 + if (!cutpath.size()) { + return "/"; + } +#endif + return cutpath; +} + +std::string getFilename(std::string path) { + size_t off = getDir(path).size() + 1; + if (off < path.size()) + return path.substr(off); + else + return path; +} + +void mkDir(const std::string &path) +{ +#ifdef _WIN32 + mkdir(path.c_str()); +#else + mkdir(path.c_str(), 0777); +#endif +} + +#ifdef _WIN32 +// Returns a vector with the device names +std::vector getWindowsDrives() +{ + std::vector drives; + + const DWORD buffsize = GetLogicalDriveStrings(0, NULL); + std::vector buff(buffsize); + if (GetLogicalDriveStrings(buffsize, buff.data()) == buffsize - 1) + { + auto drive = buff.data(); + while (*drive) + { + std::string str(ConvertWStringToUTF8(drive)); + str.pop_back(); // we don't want the final backslash + str += "/"; + drives.push_back(str); + + // advance to next drive + while (*drive++) {} + } + } + return drives; +} +#endif diff --git a/ext/native/file/file_util.h b/ext/native/file/file_util.h new file mode 100644 index 0000000000..6b659bea9b --- /dev/null +++ b/ext/native/file/file_util.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +#include + +// Whole-file reading/writing +bool writeStringToFile(bool text_file, const std::string &str, const char *filename); +bool readFileToString(bool text_file, const char *filename, std::string &str); + +bool writeDataToFile(bool text_file, const void* data, const unsigned int size, const char *filename); +bool readDataFromFile(bool text_file, unsigned char* &data, const unsigned int size, const char *filename); + +// Beginnings of a directory utility system. TODO: Improve. + +struct FileInfo { + std::string name; + std::string fullName; + bool exists; + bool isDirectory; + bool isWritable; + uint64_t size; + + bool operator <(const FileInfo &other) const; +}; + +std::string getFileExtension(const std::string &fn); +std::string getDir(const std::string &path); +std::string getFilename(std::string path); +bool getFileInfo(const char *path, FileInfo *fileInfo); + +enum { + GETFILES_GETHIDDEN = 1 +}; +size_t getFilesInDir(const char *directory, std::vector *files, const char *filter = 0, int flags = 0); +void deleteFile(const char *file); +void deleteDir(const char *file); +bool exists(const std::string &filename); +void mkDir(const std::string &path); +std::string getDir(const std::string &path); + +#ifdef _WIN32 +std::vector getWindowsDrives(); +#endif diff --git a/ext/native/file/ini_file.cpp b/ext/native/file/ini_file.cpp new file mode 100644 index 0000000000..9070bb8079 --- /dev/null +++ b/ext/native/file/ini_file.cpp @@ -0,0 +1,695 @@ +// IniFile +// Taken from Dolphin but relicensed by me, Henrik Rydgard, under the MIT +// license as I wrote the whole thing originally and it has barely changed. + +#include +#include + +#ifndef _MSC_VER +#include +#endif + +#include +#include +#include +#include +#include + +#include "base/logging.h" +#include "base/stringutil.h" +#include "file/ini_file.h" +#include "file/vfs.h" + +#ifdef _WIN32 +#include "../util/text/utf8.h" + // Function Cross-Compatibility +#define strcasecmp _stricmp +#endif + +static bool ParseLineKey(const std::string &line, size_t &pos, std::string *keyOut) { + std::string key = ""; + + while (pos < line.size()) { + size_t next = line.find_first_of("=#", pos); + if (next == line.npos || next == 0) { + // Key never ended or empty, invalid. + return false; + } else if (line[next] == '#') { + if (line[next - 1] != '\\') { + // Value commented out before =, so not valid. + return false; + } + + // Escaped. + key += line.substr(pos, next - pos - 1) + "#"; + pos = next + 1; + } else if (line[next] == '=') { + // Hurray, done. + key += line.substr(pos, next - pos); + pos = next + 1; + break; + } + } + + if (keyOut) { + *keyOut = StripSpaces(key); + } + return true; +} + +static bool ParseLineValue(const std::string &line, size_t &pos, std::string *valueOut) { + std::string value = ""; + + while (pos < line.size()) { + size_t next = line.find('#', pos); + if (next == line.npos) { + value += line.substr(pos); + pos = line.npos; + break; + } else if (line[next - 1] != '\\') { + // It wasn't escaped, so finish before the #. + value += line.substr(pos, next - pos); + // Include the comment's # in pos. + pos = next; + break; + } else { + // Escaped. + value += line.substr(pos, next - pos - 1) + "#"; + pos = next + 1; + } + } + + if (valueOut) { + *valueOut = StripQuotes(StripSpaces(value)); + } + + return true; +} + +static bool ParseLineComment(const std::string& line, size_t &pos, std::string *commentOut) { + // Don't bother with anything if we don't need the comment data. + if (commentOut) { + // Include any whitespace/formatting in the comment. + size_t commentStartPos = pos; + if (commentStartPos != line.npos) { + while (commentStartPos > 0 && line[commentStartPos - 1] <= ' ') { + --commentStartPos; + } + + *commentOut = line.substr(commentStartPos); + } else { + // There was no comment. + commentOut->clear(); + } + } + + pos = line.npos; + return true; +} + +// Ugh, this is ugly. +static bool ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) +{ + // Rules: + // 1. A line starting with ; is commented out. + // 2. A # in a line (and all the space before it) is the comment. + // 3. A \# in a line is not part of a comment and becomes # in the value. + // 4. Whitespace around values is removed. + // 5. Double quotes around values is removed. + + if (line.size() < 2 || line[0] == ';') + return false; + + size_t pos = 0; + if (!ParseLineKey(line, pos, keyOut)) + return false; + if (!ParseLineValue(line, pos, valueOut)) + return false; + if (!ParseLineComment(line, pos, commentOut)) + return false; + + return true; +} + +static std::string EscapeComments(const std::string &value) { + std::string result = ""; + + for (size_t pos = 0; pos < value.size(); ) { + size_t next = value.find('#', pos); + if (next == value.npos) { + result += value.substr(pos); + pos = value.npos; + } else { + result += value.substr(pos, next - pos) + "\\#"; + pos = next + 1; + } + } + + return result; +} + +void IniFile::Section::Clear() { + lines.clear(); +} + +std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut, std::string* commentOut) +{ + for (std::vector::iterator iter = lines.begin(); iter != lines.end(); ++iter) + { + std::string& line = *iter; + std::string lineKey; + ParseLine(line, &lineKey, valueOut, commentOut); + if (!strcasecmp(lineKey.c_str(), key)) + return &line; + } + return 0; +} + +void IniFile::Section::Set(const char* key, const char* newValue) +{ + std::string value, commented; + std::string* line = GetLine(key, &value, &commented); + if (line) + { + // Change the value - keep the key and comment + *line = StripSpaces(key) + " = " + EscapeComments(newValue) + commented; + } + else + { + // The key did not already exist in this section - let's add it. + lines.push_back(std::string(key) + " = " + EscapeComments(newValue)); + } +} + +void IniFile::Section::Set(const char* key, const std::string& newValue, const std::string& defaultValue) +{ + if (newValue != defaultValue) + Set(key, newValue); + else + Delete(key); +} + +bool IniFile::Section::Get(const char* key, std::string* value, const char* defaultValue) +{ + const std::string* line = GetLine(key, value, 0); + if (!line) + { + if (defaultValue) + { + *value = defaultValue; + } + return false; + } + return true; +} + +void IniFile::Section::Set(const char* key, const float newValue, const float defaultValue) +{ + if (newValue != defaultValue) + Set(key, newValue); + else + Delete(key); +} + +void IniFile::Section::Set(const char* key, int newValue, int defaultValue) +{ + if (newValue != defaultValue) + Set(key, newValue); + else + Delete(key); +} + +void IniFile::Section::Set(const char* key, bool newValue, bool defaultValue) +{ + if (newValue != defaultValue) + Set(key, newValue); + else + Delete(key); +} + +void IniFile::Section::Set(const char* key, const std::vector& newValues) +{ + std::string temp; + // Join the strings with , + std::vector::const_iterator it; + for (it = newValues.begin(); it != newValues.end(); ++it) + { + temp += (*it) + ","; + } + // remove last , + if (temp.length()) + temp.resize(temp.length() - 1); + Set(key, temp.c_str()); +} + +bool IniFile::Section::Get(const char* key, std::vector& values) +{ + std::string temp; + bool retval = Get(key, &temp, 0); + if (!retval || temp.empty()) + { + return false; + } + // ignore starting , if any + size_t subStart = temp.find_first_not_of(","); + size_t subEnd; + + // split by , + while (subStart != std::string::npos) { + + // Find next , + subEnd = temp.find_first_of(",", subStart); + if (subStart != subEnd) + // take from first char until next , + values.push_back(StripSpaces(temp.substr(subStart, subEnd - subStart))); + + // Find the next non , char + subStart = temp.find_first_not_of(",", subEnd); + } + + return true; +} + +bool IniFile::Section::Get(const char* key, int* value, int defaultValue) +{ + std::string temp; + bool retval = Get(key, &temp, 0); + if (retval && TryParse(temp.c_str(), value)) + return true; + *value = defaultValue; + return false; +} + +bool IniFile::Section::Get(const char* key, uint32_t* value, uint32_t defaultValue) +{ + std::string temp; + bool retval = Get(key, &temp, 0); + if (retval && TryParse(temp, value)) + return true; + *value = defaultValue; + return false; +} + +bool IniFile::Section::Get(const char* key, bool* value, bool defaultValue) +{ + std::string temp; + bool retval = Get(key, &temp, 0); + if (retval && TryParse(temp.c_str(), value)) + return true; + *value = defaultValue; + return false; +} + +bool IniFile::Section::Get(const char* key, float* value, float defaultValue) +{ + std::string temp; + bool retval = Get(key, &temp, 0); + if (retval && TryParse(temp.c_str(), value)) + return true; + *value = defaultValue; + return false; +} + +bool IniFile::Section::Get(const char* key, double* value, double defaultValue) +{ + std::string temp; + bool retval = Get(key, &temp, 0); + if (retval && TryParse(temp.c_str(), value)) + return true; + *value = defaultValue; + return false; +} + +bool IniFile::Section::Exists(const char *key) const +{ + for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) + { + std::string lineKey; + ParseLine(*iter, &lineKey, NULL, NULL); + if (!strcasecmp(lineKey.c_str(), key)) + return true; + } + return false; +} + +std::map IniFile::Section::ToMap() const +{ + std::map outMap; + for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) + { + std::string lineKey, lineValue; + if (ParseLine(*iter, &lineKey, &lineValue, NULL)) { + outMap[lineKey] = lineValue; + } + } + return outMap; +} + + +bool IniFile::Section::Delete(const char *key) +{ + std::string* line = GetLine(key, 0, 0); + for (std::vector::iterator liter = lines.begin(); liter != lines.end(); ++liter) + { + if (line == &*liter) + { + lines.erase(liter); + return true; + } + } + return false; +} + +// IniFile + +const IniFile::Section* IniFile::GetSection(const char* sectionName) const +{ + for (std::vector
::const_iterator iter = sections.begin(); iter != sections.end(); ++iter) + if (!strcasecmp(iter->name().c_str(), sectionName)) + return (&(*iter)); + return 0; +} + +IniFile::Section* IniFile::GetSection(const char* sectionName) +{ + for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) + if (!strcasecmp(iter->name().c_str(), sectionName)) + return (&(*iter)); + return 0; +} + +IniFile::Section* IniFile::GetOrCreateSection(const char* sectionName) +{ + Section* section = GetSection(sectionName); + if (!section) + { + sections.push_back(Section(sectionName)); + section = §ions[sections.size() - 1]; + } + return section; +} + +bool IniFile::DeleteSection(const char* sectionName) +{ + Section* s = GetSection(sectionName); + if (!s) + return false; + for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) + { + if (&(*iter) == s) + { + sections.erase(iter); + return true; + } + } + return false; +} + +bool IniFile::Exists(const char* sectionName, const char* key) const +{ + const Section* section = GetSection(sectionName); + if (!section) + return false; + return section->Exists(key); +} + +void IniFile::SetLines(const char* sectionName, const std::vector &lines) +{ + Section* section = GetOrCreateSection(sectionName); + section->lines.clear(); + for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) + { + section->lines.push_back(*iter); + } +} + +bool IniFile::DeleteKey(const char* sectionName, const char* key) +{ + Section* section = GetSection(sectionName); + if (!section) + return false; + std::string* line = section->GetLine(key, 0, 0); + for (std::vector::iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) + { + if (line == &(*liter)) + { + section->lines.erase(liter); + return true; + } + } + return false; //shouldn't happen +} + +// Return a list of all keys in a section +bool IniFile::GetKeys(const char* sectionName, std::vector& keys) const +{ + const Section* section = GetSection(sectionName); + if (!section) + return false; + keys.clear(); + for (std::vector::const_iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) + { + std::string key; + ParseLine(*liter, &key, 0, 0); + if (!key.empty()) + keys.push_back(key); + } + return true; +} + +// Return a list of all lines in a section +bool IniFile::GetLines(const char* sectionName, std::vector& lines, const bool remove_comments) const +{ + const Section* section = GetSection(sectionName); + if (!section) + return false; + + lines.clear(); + for (std::vector::const_iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter) + { + std::string line = StripSpaces(*iter); + + if (remove_comments) + { + int commentPos = (int)line.find('#'); + if (commentPos == 0) + { + continue; + } + + if (commentPos != (int)std::string::npos) + { + line = StripSpaces(line.substr(0, commentPos)); + } + } + + lines.push_back(line); + } + + return true; +} + + +void IniFile::SortSections() +{ + std::sort(sections.begin(), sections.end()); +} + +bool IniFile::Load(const char* filename) +{ + sections.clear(); + sections.push_back(Section("")); + // first section consists of the comments before the first real section + + // Open file + std::ifstream in; +#ifdef _WIN32 + in.open(ConvertUTF8ToWString(filename), std::ios::in); +#else + in.open(filename, std::ios::in); +#endif + if (in.fail()) return false; + + bool success = Load(in); + in.close(); + return success; +} + +bool IniFile::LoadFromVFS(const std::string &filename) { + size_t size; + uint8_t *data = VFSReadFile(filename.c_str(), &size); + if (!data) + return false; + std::string str((const char*)data, size); + delete [] data; + + std::stringstream sstream(str); + return Load(sstream); +} + +bool IniFile::Load(std::istream &in) { + // Maximum number of letters in a line + static const int MAX_BYTES = 1024*32; + + while (!in.eof()) + { + char templine[MAX_BYTES]; + in.getline(templine, MAX_BYTES); + std::string line = templine; + + // Remove UTF-8 byte order marks. + if (line.substr(0, 3) == "\xEF\xBB\xBF") + line = line.substr(3); + +#ifndef _WIN32 + // Check for CRLF eol and convert it to LF + if (!line.empty() && line.at(line.size()-1) == '\r') + { + line.erase(line.size()-1); + } +#endif + + if (line.size() > 0) + { + if (line[0] == '[') + { + size_t endpos = line.find("]"); + + if (endpos != std::string::npos) + { + // New section! + std::string sub = line.substr(1, endpos - 1); + sections.push_back(Section(sub)); + + if (endpos + 1 < line.size()) + { + sections[sections.size() - 1].comment = line.substr(endpos + 1); + } + } + } + else + { + if (sections.size() > 0) + sections[sections.size() - 1].lines.push_back(line); + } + } + } + + return true; +} + +bool IniFile::Save(const char* filename) +{ + std::ofstream out; +#ifdef _WIN32 + out.open(ConvertUTF8ToWString(filename), std::ios::out); +#else + out.open(filename, std::ios::out); +#endif + + if (out.fail()) + { + return false; + } + + // UTF-8 byte order mark. To make sure notepad doesn't go nuts. + out << "\xEF\xBB\xBF"; + + // Currently testing if dolphin community can handle the requirements of C++11 compilation + // If you get a compiler error on this line, your compiler is probably old. + // Update to g++ 4.4 or a recent version of clang (XCode 4.2 on OS X). + // If you don't want to update, complain in a google code issue, the dolphin forums or #dolphin-emu. + for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) + { + const Section& section = *iter; + + if (section.name() != "") + { + out << "[" << section.name() << "]" << section.comment << std::endl; + } + + for (std::vector::const_iterator liter = section.lines.begin(); liter != section.lines.end(); ++liter) + { + std::string s = *liter; + out << s << std::endl; + } + } + + out.close(); + return true; +} + +bool IniFile::Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue) +{ + Section* section = GetSection(sectionName); + if (!section) { + if (defaultValue) { + *value = defaultValue; + } + return false; + } + return section->Get(key, value, defaultValue); +} + +bool IniFile::Get(const char *sectionName, const char* key, std::vector& values) +{ + Section *section = GetSection(sectionName); + if (!section) + return false; + return section->Get(key, values); +} + +bool IniFile::Get(const char* sectionName, const char* key, int* value, int defaultValue) +{ + Section *section = GetSection(sectionName); + if (!section) { + *value = defaultValue; + return false; + } else { + return section->Get(key, value, defaultValue); + } +} + +bool IniFile::Get(const char* sectionName, const char* key, uint32_t* value, uint32_t defaultValue) +{ + Section *section = GetSection(sectionName); + if (!section) { + *value = defaultValue; + return false; + } else { + return section->Get(key, value, defaultValue); + } +} + +bool IniFile::Get(const char* sectionName, const char* key, bool* value, bool defaultValue) +{ + Section *section = GetSection(sectionName); + if (!section) { + *value = defaultValue; + return false; + } else { + return section->Get(key, value, defaultValue); + } +} + + +// Unit test. TODO: Move to the real unit test framework. +/* + int main() + { + IniFile ini; + ini.Load("my.ini"); + ini.Set("Hej", "A", "amaskdfl"); + ini.Set("Mossa", "A", "amaskdfl"); + ini.Set("Aissa", "A", "amaskdfl"); + //ini.Read("my.ini"); + std::string x; + ini.Get("Hej", "B", &x, "boo"); + ini.DeleteKey("Mossa", "A"); + ini.DeleteSection("Mossa"); + ini.SortSections(); + ini.Save("my.ini"); + //UpdateVars(ini); + return 0; + } + */ diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h new file mode 100644 index 0000000000..e64238b62d --- /dev/null +++ b/ext/native/file/ini_file.h @@ -0,0 +1,192 @@ +// IniFile +// Taken from Dolphin but relicensed by me, Henrik Rydgard, under the MIT +// license as I wrote the whole thing originally and it has barely changed. + +#pragma once + +#include +#include +#include + +#include "base/stringutil.h" + +class IniFile +{ +public: + class Section + { + friend class IniFile; + + public: + Section() {} + Section(const std::string& name) : name_(name) {} + + bool Exists(const char *key) const; + bool Delete(const char *key); + + void Clear(); + + std::map ToMap() const; + + std::string* GetLine(const char* key, std::string* valueOut, std::string* commentOut); + void Set(const char* key, const char* newValue); + void Set(const char* key, const std::string& newValue, const std::string& defaultValue); + + void Set(const std::string &key, const std::string &value) { + Set(key.c_str(), value.c_str()); + } + bool Get(const char* key, std::string* value, const char* defaultValue); + + void Set(const char* key, uint32_t newValue) { + Set(key, StringFromFormat("0x%08x", newValue).c_str()); + } + void Set(const char* key, float newValue) { + Set(key, StringFromFormat("%f", newValue).c_str()); + } + void Set(const char* key, const float newValue, const float defaultValue); + void Set(const char* key, double newValue) { + Set(key, StringFromFormat("%f", newValue).c_str()); + } + + void Set(const char* key, int newValue, int defaultValue); + void Set(const char* key, int newValue) { + Set(key, StringFromInt(newValue).c_str()); + } + + void Set(const char* key, bool newValue, bool defaultValue); + void Set(const char* key, bool newValue) { + Set(key, StringFromBool(newValue).c_str()); + } + void Set(const char* key, const std::vector& newValues); + + template + void Set(const char* key, const std::map& newValues) + { + std::vector temp; + for(typename std::map::const_iterator it = newValues.begin(); it != newValues.end(); it++) + { + temp.push_back(ValueToString(it->first)+"_"+ValueToString(it->second)); + } + Set(key,temp); + } + + // Declare without a body to make it fail to compile. This is to prevent accidentally + // setting a pointer as a bool. The failure is in the linker unfortunately, but that's better + // than accidentally succeeding in a bad way. + template + void Set(const char *key, T *ptr); + + bool Get(const char* key, int* value, int defaultValue = 0); + bool Get(const char* key, uint32_t* value, uint32_t defaultValue = 0); + bool Get(const char* key, bool* value, bool defaultValue = false); + bool Get(const char* key, float* value, float defaultValue = false); + bool Get(const char* key, double* value, double defaultValue = false); + bool Get(const char* key, std::vector& values); + template + bool Get(const char* key, std::map& values) + { + std::vector temp; + if(!Get(key,temp)) + { + return false; + } + values.clear(); + for(size_t i = 0; i < temp.size(); i++) + { + std::vector key_val; + SplitString(temp[i],'_',key_val); + if(key_val.size() < 2) + continue; + U mapKey; + V mapValue; + if(!TryParse(key_val[0],&mapKey)) + continue; + if(!TryParse(key_val[1],&mapValue)) + continue; + values[mapKey] = mapValue; + } + return true; + } + + bool operator < (const Section& other) const { + return name_ < other.name_; + } + + const std::string &name() const { + return name_; + } + + protected: + std::vector lines; + std::string name_; + std::string comment; + }; + + bool Load(const char* filename); + bool Load(const std::string &filename) { return Load(filename.c_str()); } + bool Load(std::istream &istream); + bool LoadFromVFS(const std::string &filename); + + bool Save(const char* filename); + bool Save(const std::string &filename) { return Save(filename.c_str()); } + + // Returns true if key exists in section + bool Exists(const char* sectionName, const char* key) const; + + // TODO: Get rid of these, in favor of the Section ones. + void Set(const char* sectionName, const char* key, const char* newValue) { + GetOrCreateSection(sectionName)->Set(key, newValue); + } + void Set(const char* sectionName, const char* key, const std::string& newValue) { + GetOrCreateSection(sectionName)->Set(key, newValue.c_str()); + } + void Set(const char* sectionName, const char* key, int newValue) { + GetOrCreateSection(sectionName)->Set(key, newValue); + } + void Set(const char* sectionName, const char* key, uint32_t newValue) { + GetOrCreateSection(sectionName)->Set(key, newValue); + } + void Set(const char* sectionName, const char* key, bool newValue) { + GetOrCreateSection(sectionName)->Set(key, newValue); + } + void Set(const char* sectionName, const char* key, const std::vector& newValues) { + GetOrCreateSection(sectionName)->Set(key, newValues); + } + + // TODO: Get rid of these, in favor of the Section ones. + bool Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue = ""); + bool Get(const char* sectionName, const char* key, int* value, int defaultValue = 0); + bool Get(const char* sectionName, const char* key, uint32_t* value, uint32_t defaultValue = 0); + bool Get(const char* sectionName, const char* key, bool* value, bool defaultValue = false); + bool Get(const char* sectionName, const char* key, std::vector& values); + + template bool GetIfExists(const char* sectionName, const char* key, T value) + { + if (Exists(sectionName, key)) + return Get(sectionName, key, value); + return false; + } + + bool GetKeys(const char* sectionName, std::vector& keys) const; + + void SetLines(const char* sectionName, const std::vector &lines); + bool GetLines(const char* sectionName, std::vector& lines, const bool remove_comments = true) const; + + bool DeleteKey(const char* sectionName, const char* key); + bool DeleteSection(const char* sectionName); + + void SortSections(); + std::vector
&Sections() { return sections; } + + bool HasSection(const char *section) { return GetSection(section) != 0; } + + Section* GetOrCreateSection(const char* section); + +private: + std::vector
sections; + + const Section* GetSection(const char* section) const; + Section* GetSection(const char* section); + std::string* GetLine(const char* section, const char* key); + void CreateSection(const char* section); +}; diff --git a/ext/native/file/path.cpp b/ext/native/file/path.cpp new file mode 100644 index 0000000000..d50a64f237 --- /dev/null +++ b/ext/native/file/path.cpp @@ -0,0 +1,62 @@ +#include "file/path.h" + +// Normalize slashes. +void PathBrowser::SetPath(const std::string &path) { + if (path[0] == '!') { + path_ = path; + return; + } + path_ = path; + for (size_t i = 0; i < path_.size(); i++) { + if (path_[i] == '\\') path_[i] = '/'; + } + if (!path_.size() || (path_[path_.size() - 1] != '/')) + path_ += "/"; +} + +void PathBrowser::GetListing(std::vector &fileInfo, const char *filter) { +#ifdef _WIN32 + if (path_ == "/") { + // Special path that means root of file system. + std::vector drives = getWindowsDrives(); + for (auto drive = drives.begin(); drive != drives.end(); ++drive) { + if (*drive == "A:/" || *drive == "B:/") + continue; + FileInfo fake; + fake.fullName = *drive; + fake.name = *drive; + fake.isDirectory = true; + fake.exists = true; + fake.size = 0; + fake.isWritable = false; + fileInfo.push_back(fake); + } + } +#endif + + getFilesInDir(path_.c_str(), &fileInfo, filter); +} + +// TODO: Support paths like "../../hello" +void PathBrowser::Navigate(const std::string &path) { + if (path == ".") + return; + if (path == "..") { + // Upwards. + // Check for windows drives. + if (path_.size() == 3 && path_[1] == ':') { + path_ = "/"; + } else { + size_t slash = path_.rfind('/', path_.size() - 2); + if (slash != std::string::npos) + path_ = path_.substr(0, slash + 1); + } + } else { + if (path[1] == ':' && path_ == "/") + path_ = path; + else + path_ = path_ + path; + if (path_[path_.size() - 1] != '/') + path_ += "/"; + } +} diff --git a/ext/native/file/path.h b/ext/native/file/path.h new file mode 100644 index 0000000000..f29492960e --- /dev/null +++ b/ext/native/file/path.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +#include +#include + +#include "file/file_util.h" + +// Abstraction above path that lets you navigate easily. +// "/" is a special path that means the root of the file system. On Windows, +// listing this will yield drives. +class PathBrowser { +public: + PathBrowser() {} + PathBrowser(std::string path) { SetPath(path); } + + void SetPath(const std::string &path); + void GetListing(std::vector &fileInfo, const char *filter = 0); + void Navigate(const std::string &path); + + std::string GetPath() const { + if (path_ != "/") + return path_; + else + return ""; + } + std::string GetFriendlyPath() { + std::string str = GetPath(); +#if defined(BLACKBERRY) + char *home = getenv("PERIMETER_HOME"); + if (home != NULL && !strncmp(str.c_str(), home, strlen(home))) { + str = str.substr(strlen(home)); + str.insert(0, 1, '~'); + } +#elif defined(ANDROID) + // Do nothing +#elif defined(__linux) + char *home = getenv("HOME"); + if (home != NULL && !strncmp(str.c_str(), home, strlen(home))) { + str = str.substr(strlen(home)); + str.insert(0, 1, '~'); + } +#endif + return str; + } + + std::string path_; +}; + diff --git a/ext/native/file/vfs.h b/ext/native/file/vfs.h new file mode 100644 index 0000000000..ce1023b635 --- /dev/null +++ b/ext/native/file/vfs.h @@ -0,0 +1,19 @@ +#pragma once + +#include "base/basictypes.h" +#include "file/file_util.h" +// Basic virtual file system. Used to manage assets on Android, where we have to +// read them manually out of the APK zipfile, while being able to run on other +// platforms as well with the appropriate directory set-up. + +class AssetReader; + +void VFSRegister(const char *prefix, AssetReader *reader); +void VFSShutdown(); + +// Use delete [] to release the returned memory. +// Always allocates an extra zero byte at the end, so that it +// can be used for text like shader sources. +uint8_t *VFSReadFile(const char *filename, size_t *size); +bool VFSGetFileListing(const char *path, std::vector *listing, const char *filter = 0); +bool VFSGetFileInfo(const char *filename, FileInfo *fileInfo); diff --git a/ext/native/file/zip_read.cpp b/ext/native/file/zip_read.cpp new file mode 100644 index 0000000000..76966127ad --- /dev/null +++ b/ext/native/file/zip_read.cpp @@ -0,0 +1,422 @@ +#include +#include +#include + +#ifdef USING_QT_UI +#include +#include +#endif + +#ifdef ANDROID +#include +#endif + +#include "base/basictypes.h" +#include "base/logging.h" +#include "file/zip_read.h" + +#ifdef ANDROID +uint8_t *ReadFromZip(zip *archive, const char* filename, size_t *size) { + // Figure out the file size first. + struct zip_stat zstat; + zip_file *file = zip_fopen(archive, filename, ZIP_FL_NOCASE|ZIP_FL_UNCHANGED); + if (!file) { + ELOG("Error opening %s from ZIP", filename); + return 0; + } + zip_stat(archive, filename, ZIP_FL_NOCASE|ZIP_FL_UNCHANGED, &zstat); + + uint8_t *contents = new uint8_t[zstat.size + 1]; + zip_fread(file, contents, zstat.size); + zip_fclose(file); + contents[zstat.size] = 0; + + *size = zstat.size; + return contents; +} + +#endif + +// The return is non-const because - why not? +uint8_t *ReadLocalFile(const char *filename, size_t *size) { + FILE *file = fopen(filename, "rb"); + if (!file) { + *size = 0; + return nullptr; + } + fseek(file, 0, SEEK_END); + size_t f_size = ftell(file); + if ((long)f_size < 0) { + *size = 0; + fclose(file); + return nullptr; + } + fseek(file, 0, SEEK_SET); + uint8_t *contents = new uint8_t[f_size+1]; + if (fread(contents, 1, f_size, file) != f_size) { + delete [] contents; + contents = nullptr; + *size = 0; + } else { + contents[f_size] = 0; + *size = f_size; + } + fclose(file); + return contents; +} + +#ifdef USING_QT_UI +uint8_t *AssetsAssetReader::ReadAsset(const char *path, size_t *size) { + QFile asset(QString(":/assets/") + path); + if (!asset.open(QIODevice::ReadOnly)) + return 0; + + uint8_t *contents = new uint8_t[asset.size()+1]; + memcpy(contents, (uint8_t*)asset.readAll().data(), asset.size()); + contents[asset.size()] = 0; + *size = asset.size(); + asset.close(); + return contents; +} + +bool AssetsAssetReader::GetFileListing(const char *path, std::vector *listing, const char *filter = 0) +{ + QDir assetDir(QString(":/assets/") + path); + QStringList filters = QString(filter).split(':', QString::SkipEmptyParts); + for (int i = 0; i < filters.count(); i++) + filters[i].prepend("*."); + + QFileInfoList infoList = assetDir.entryInfoList(filters, QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Files, QDir::Name); + foreach(QFileInfo qinfo, infoList) { + FileInfo info; + info.name = qinfo.fileName().toStdString(); + info.fullName = qinfo.absoluteFilePath().remove(":/assets/").toStdString(); + info.exists = true; + info.isWritable = false; + info.isDirectory = qinfo.isDir(); + listing->push_back(info); + } + return true; +} + +bool AssetsAssetReader::GetFileInfo(const char *path, FileInfo *info) { + QFileInfo qinfo(QString(":/assets/") + path); + if (!qinfo.exists()) { + info->exists = false; + info->size = 0; + return false; + } + + info->fullName = path; + info->exists = true; + info->isWritable = false; + info->isDirectory = qinfo.isDir(); + info->size = qinfo.size(); + return true; +} + +#endif + +#ifdef ANDROID + +ZipAssetReader::ZipAssetReader(const char *zip_file, const char *in_zip_path) { + zip_file_ = zip_open(zip_file, 0, NULL); + strcpy(in_zip_path_, in_zip_path); + if (!zip_file_) { + ELOG("Failed to open %s as a zip file", zip_file); + } + + std::vector info; + GetFileListing("assets", &info, 0); + for (size_t i = 0; i < info.size(); i++) { + if (info[i].isDirectory) { + DLOG("Directory: %s", info[i].name.c_str()); + } else { + DLOG("File: %s", info[i].name.c_str()); + } + } +} + +ZipAssetReader::~ZipAssetReader() { + zip_close(zip_file_); +} + +uint8_t *ZipAssetReader::ReadAsset(const char *path, size_t *size) { + char temp_path[1024]; + strcpy(temp_path, in_zip_path_); + strcat(temp_path, path); + return ReadFromZip(zip_file_, temp_path, size); +} + +bool ZipAssetReader::GetFileListing(const char *orig_path, std::vector *listing, const char *filter = 0) { + char path[1024]; + strcpy(path, in_zip_path_); + strcat(path, orig_path); + + std::set filters; + std::string tmp; + if (filter) { + while (*filter) { + if (*filter == ':') { + filters.insert(tmp); + tmp = ""; + } else { + tmp.push_back(*filter); + } + filter++; + } + } + if (tmp.size()) + filters.insert(tmp); + + // We just loop through the whole ZIP file and deduce what files are in this directory, and what subdirectories there are. + std::set files; + std::set directories; + int numFiles = zip_get_num_files(zip_file_); + size_t pathlen = strlen(path); + if (path[pathlen-1] == '/') + pathlen--; + for (int i = 0; i < numFiles; i++) { + const char* name = zip_get_name(zip_file_, i, 0); + if (!name) + continue; + if (!memcmp(name, path, pathlen)) { + // The prefix is right. Let's see if this is a file or path. + char *slashPos = strchr(name + pathlen + 1, '/'); + if (slashPos != 0) { + // A directory. + std::string dirName = std::string(name + pathlen + 1, slashPos - (name + pathlen + 1)); + directories.insert(dirName); + } else if (name[pathlen] == '/') { + const char *fn = name + pathlen + 1; + files.insert(std::string(fn)); + } // else, it was a file with the same prefix as the path. like langregion.ini next to lang/. + } + } + + for (auto diter = directories.begin(); diter != directories.end(); ++diter) { + FileInfo info; + info.name = *diter; + info.fullName = std::string(path); + if (info.fullName[info.fullName.size() - 1] == '/') + info.fullName = info.fullName.substr(0, info.fullName.size() - 1); + + // Remove the "inzip" part of the fullname. + info.fullName = info.fullName.substr(strlen(in_zip_path_)); + info.fullName += "/" + *diter; + info.exists = true; + info.isWritable = false; + info.isDirectory = true; + listing->push_back(info); + } + + for (auto fiter = files.begin(); fiter != files.end(); ++fiter) { + FileInfo info; + info.name = *fiter; + info.fullName = std::string(path); + if (info.fullName[info.fullName.size() - 1] == '/') + info.fullName = info.fullName.substr(0, info.fullName.size() - 1); + info.fullName = info.fullName.substr(strlen(in_zip_path_)); + info.fullName += "/" + *fiter; + info.exists = true; + info.isWritable = false; + info.isDirectory = false; + std::string ext = getFileExtension(info.fullName); + if (filter) { + if (filters.find(ext) == filters.end()) + continue; + } + listing->push_back(info); + } + + std::sort(listing->begin(), listing->end()); + return true; +} + +bool ZipAssetReader::GetFileInfo(const char *path, FileInfo *info) { + struct zip_stat zstat; + char temp_path[1024]; + strcpy(temp_path, in_zip_path_); + strcat(temp_path, path); + if (0 != zip_stat(zip_file_, temp_path, ZIP_FL_NOCASE|ZIP_FL_UNCHANGED, &zstat)) { + // ZIP files do not have real directories, so we'll end up here if we + // try to stat one. For now that's fine. + info->exists = false; + info->size = 0; + return false; + } + + info->fullName = path; + info->exists = true; // TODO + info->isWritable = false; + info->isDirectory = false; // TODO + info->size = zstat.size; + return true; +} + +#endif + +uint8_t *DirectoryAssetReader::ReadAsset(const char *path, size_t *size) { + char new_path[2048]; + new_path[0] = '\0'; + // Check if it already contains the path + if (strlen(path) > strlen(path_) && 0 == memcmp(path, path_, strlen(path_))) { + } + else { + strcpy(new_path, path_); + } + strcat(new_path, path); + return ReadLocalFile(new_path, size); +} + +bool DirectoryAssetReader::GetFileListing(const char *path, std::vector *listing, const char *filter = 0) +{ + char new_path[2048]; + new_path[0] = '\0'; + // Check if it already contains the path + if (strlen(path) > strlen(path_) && 0 == memcmp(path, path_, strlen(path_))) { + } + else { + strcpy(new_path, path_); + } + strcat(new_path, path); + FileInfo info; + if (!getFileInfo(new_path, &info)) + return false; + + if (info.isDirectory) + { + getFilesInDir(new_path, listing, filter); + return true; + } + else + { + return false; + } +} + +bool DirectoryAssetReader::GetFileInfo(const char *path, FileInfo *info) +{ + char new_path[2048]; + new_path[0] = '\0'; + // Check if it already contains the path + if (strlen(path) > strlen(path_) && 0 == memcmp(path, path_, strlen(path_))) { + } + else { + strcpy(new_path, path_); + } + strcat(new_path, path); + return getFileInfo(new_path, info); +} + +struct VFSEntry { + const char *prefix; + AssetReader *reader; +}; + +static VFSEntry entries[16]; +static int num_entries = 0; + +void VFSRegister(const char *prefix, AssetReader *reader) { + entries[num_entries].prefix = prefix; + entries[num_entries].reader = reader; + DLOG("Registered VFS for prefix %s: %s", prefix, reader->toString().c_str()); + num_entries++; +} + +void VFSShutdown() { + for (int i = 0; i < num_entries; i++) { + delete entries[i].reader; + } + num_entries = 0; +} + +uint8_t *VFSReadFile(const char *filename, size_t *size) { + if (filename[0] == '/') { + // Local path, not VFS. + ILOG("Not a VFS path: %s . Reading local file.", filename); + return ReadLocalFile(filename, size); + } + + int fn_len = (int)strlen(filename); + bool fileSystemFound = false; + for (int i = 0; i < num_entries; i++) { + int prefix_len = (int)strlen(entries[i].prefix); + if (prefix_len >= fn_len) continue; + if (0 == memcmp(filename, entries[i].prefix, prefix_len)) { + fileSystemFound = true; + // ILOG("Prefix match: %s (%s) -> %s", entries[i].prefix, filename, filename + prefix_len); + uint8_t *data = entries[i].reader->ReadAsset(filename + prefix_len, size); + if (data) + return data; + else + continue; + // Else try the other registered file systems. + } + } + if (!fileSystemFound) { + ELOG("Missing filesystem for %s", filename); + } // Otherwise, the file was just missing. No need to log. + return 0; +} + +bool VFSGetFileListing(const char *path, std::vector *listing, const char *filter) { +#ifdef _WIN32 + if (path[1] == ':') { +#else + if (path[0] == '/') { +#endif + // Local path, not VFS. + ILOG("Not a VFS path: %s . Reading local directory.", path); + getFilesInDir(path, listing, filter); + return true; + } + + int fn_len = (int)strlen(path); + bool fileSystemFound = false; + for (int i = 0; i < num_entries; i++) { + int prefix_len = (int)strlen(entries[i].prefix); + if (prefix_len >= fn_len) continue; + if (0 == memcmp(path, entries[i].prefix, prefix_len)) { + fileSystemFound = true; + if (entries[i].reader->GetFileListing(path + prefix_len, listing, filter)) { + return true; + } + } + } + + if (!fileSystemFound) { + ELOG("Missing filesystem for %s", path); + } // Otherwise, the file was just missing. No need to log. + return false; +} + +bool VFSGetFileInfo(const char *path, FileInfo *info) { +#ifdef _WIN32 + if (path[1] == ':') { +#else + if (path[0] == '/') { +#endif + // Local path, not VFS. + ILOG("Not a VFS path: %s . Getting local file info.", path); + return getFileInfo(path, info); + } + + bool fileSystemFound = false; + int fn_len = (int)strlen(path); + for (int i = 0; i < num_entries; i++) { + int prefix_len = (int)strlen(entries[i].prefix); + if (prefix_len >= fn_len) continue; + if (0 == memcmp(path, entries[i].prefix, prefix_len)) { + fileSystemFound = true; + if (entries[i].reader->GetFileInfo(path + prefix_len, info)) + return true; + else + continue; + } + } + if (!fileSystemFound) { + ELOG("Missing filesystem for %s", path); + } // Otherwise, the file was just missing. No need to log. + return false; +} diff --git a/ext/native/file/zip_read.h b/ext/native/file/zip_read.h new file mode 100644 index 0000000000..57141f3216 --- /dev/null +++ b/ext/native/file/zip_read.h @@ -0,0 +1,81 @@ +// TODO: Move much of this code to vfs.cpp +#pragma once + +#ifdef ANDROID +#include +#endif + +#include +#include + +#include "base/basictypes.h" +#include "file/vfs.h" +#include "file/file_util.h" + +// Direct readers. deallocate using delete []. +uint8_t *ReadLocalFile(const char *filename, size_t *size); + +class AssetReader { +public: + virtual ~AssetReader() {} + // use delete[] + virtual uint8_t *ReadAsset(const char *path, size_t *size) = 0; + // Filter support is optional but nice to have + virtual bool GetFileListing(const char *path, std::vector *listing, const char *filter = 0) = 0; + virtual bool GetFileInfo(const char *path, FileInfo *info) = 0; + virtual std::string toString() const = 0; +}; + +#ifdef USING_QT_UI +class AssetsAssetReader : public AssetReader { +public: + AssetsAssetReader() {} + ~AssetsAssetReader() {} + // use delete[] + virtual uint8_t *ReadAsset(const char *path, size_t *size); + virtual bool GetFileListing(const char *path, std::vector *listing, const char *filter); + virtual bool GetFileInfo(const char *path, FileInfo *info); + virtual std::string toString() const { + return ":assets/"; + } +}; +#endif + +#ifdef ANDROID +uint8_t *ReadFromZip(zip *archive, const char* filename, size_t *size); +class ZipAssetReader : public AssetReader { +public: + ZipAssetReader(const char *zip_file, const char *in_zip_path); + ~ZipAssetReader(); + // use delete[] + virtual uint8_t *ReadAsset(const char *path, size_t *size); + virtual bool GetFileListing(const char *path, std::vector *listing, const char *filter); + virtual bool GetFileInfo(const char *path, FileInfo *info); + virtual std::string toString() const { + return in_zip_path_; + } + +private: + zip *zip_file_; + char in_zip_path_[256]; +}; +#endif + +class DirectoryAssetReader : public AssetReader { +public: + DirectoryAssetReader(const char *path) { + strncpy(path_, path, ARRAY_SIZE(path_)); + path_[ARRAY_SIZE(path_) - 1] = '\0'; + } + // use delete[] + virtual uint8_t *ReadAsset(const char *path, size_t *size); + virtual bool GetFileListing(const char *path, std::vector *listing, const char *filter); + virtual bool GetFileInfo(const char *path, FileInfo *info); + virtual std::string toString() const { + return path_; + } + +private: + char path_[512]; +}; + diff --git a/ext/native/gfx/CMakeLists.txt b/ext/native/gfx/CMakeLists.txt new file mode 100644 index 0000000000..97264f7d85 --- /dev/null +++ b/ext/native/gfx/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SRCS + gl_debug_log.cpp + gl_lost_manager.cpp + texture.cpp + texture_atlas.cpp + texture_gen.cpp) + +set(SRCS ${SRCS}) + +add_library(gfx STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/gfx/gl_common.h b/ext/native/gfx/gl_common.h new file mode 100644 index 0000000000..24f121b3a7 --- /dev/null +++ b/ext/native/gfx/gl_common.h @@ -0,0 +1,99 @@ +#pragma once + +#ifdef IOS +#include +#include +#elif defined(USING_GLES2) +#include +#include +// At least Nokia platforms need the three below +#include +typedef char GLchar; +#define GL_BGRA_EXT 0x80E1 +#else // OpenGL +#include "GL/glew.h" +#if defined(__APPLE__) +#include +#else +#include +#endif +#endif + +#ifdef USING_GLES2 +// Support OpenGL ES 3.0 +// This uses the "DYNAMIC" approach from the gles3jni NDK sample. +#include "../gfx_es2/gl3stub.h" +#endif + + +#ifdef USING_GLES2 + +#ifndef GL_MIN_EXT +#define GL_MIN_EXT 0x8007 +#endif + +#ifndef GL_MAX_EXT +#define GL_MAX_EXT 0x8008 +#endif + +#if defined(ANDROID) || defined(BLACKBERRY) +#include +// Additional extensions not included in GLES2/gl2ext.h from the NDK + +typedef uint64_t EGLuint64NV; +typedef EGLuint64NV(EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); +typedef EGLuint64NV(EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); +extern PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC eglGetSystemTimeFrequencyNV; +extern PFNEGLGETSYSTEMTIMENVPROC eglGetSystemTimeNV; + +typedef GLvoid* (GL_APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +extern PFNGLMAPBUFFERPROC glMapBuffer; + +typedef void (EGLAPIENTRYP PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +extern PFNGLDRAWTEXTURENVPROC glDrawTextureNV; +typedef void (EGLAPIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum + srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, + GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei + width, GLsizei height, GLsizei depth); +extern PFNGLCOPYIMAGESUBDATANVPROC glCopyImageSubDataNV; +#ifndef ARM64 +typedef void (EGLAPIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) ( + GLint srcX0, GLint srcY0, GLint srcX1, GLuint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLuint dstY1, + GLint mask, GLenum filter); +#endif +extern PFNGLBLITFRAMEBUFFERNVPROC glBlitFramebufferNV; + +extern PFNGLDISCARDFRAMEBUFFEREXTPROC glDiscardFramebufferEXT; +extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOES; +extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOES; +extern PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArraysOES; +extern PFNGLISVERTEXARRAYOESPROC glIsVertexArrayOES; + +// Rename standard functions to the OES version. +#define glGenVertexArrays glGenVertexArraysOES +#define glBindVertexArray glBindVertexArrayOES +#define glDeleteVertexArrays glDeleteVertexArraysOES +#define glIsVertexArray glIsVertexArrayOES + +#endif + +#if !defined(BLACKBERRY) +#ifndef GL_READ_FRAMEBUFFER +#define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER +#define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER +#endif +#ifndef GL_DEPTH_COMPONENT24 +#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES +#endif +#endif + +#ifndef GL_RGBA8 +#define GL_RGBA8 GL_RGBA +#endif + +#endif /* EGL_NV_system_time */ + +#ifndef GL_DEPTH24_STENCIL8_OES +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif diff --git a/ext/native/gfx/gl_debug_log.cpp b/ext/native/gfx/gl_debug_log.cpp new file mode 100644 index 0000000000..e895fd81e6 --- /dev/null +++ b/ext/native/gfx/gl_debug_log.cpp @@ -0,0 +1,54 @@ +#include "gfx/gl_common.h" +#include "base/logging.h" + +void glCheckzor(const char *file, int line) { + GLenum err = glGetError(); + if (err != GL_NO_ERROR) { + ELOG("GL error on line %i in %s: %i (%04x)", line, file, (int)err, (int)err); + } +} + +#if !defined(USING_GLES2) +#if 0 +void log_callback(GLenum source, GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + GLvoid* userParam) { + const char *src = "unknown"; + switch (source) { + case GL_DEBUG_SOURCE_API_GL_ARB: + src = "GL"; + break; + case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: + src = "GLSL"; + break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: + src = "X"; + break; + default: + break; + } + switch (type) { + case GL_DEBUG_TYPE_ERROR_ARB: + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: + ELOG("%s: %s", src, message); + break; + default: + ILOG("%s: %s", src, message); + break; + } +} +#endif +#endif + +void gl_log_enable() { +#if !defined(USING_GLES2) +#if 0 + glEnable(DEBUG_OUTPUT_SYNCHRONOUS_ARB); // TODO: Look into disabling, for more perf + glDebugMessageCallback(&log_callback, 0); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); +#endif +#endif +} diff --git a/ext/native/gfx/gl_debug_log.h b/ext/native/gfx/gl_debug_log.h new file mode 100644 index 0000000000..411f55668d --- /dev/null +++ b/ext/native/gfx/gl_debug_log.h @@ -0,0 +1,25 @@ +#pragma once + +// Utility to be able to liberally sprinkle GL error checks around your code +// and easily disable them all in release builds - just undefine DEBUG_OPENGL. + + +void gl_log_enable(); + +#if !defined(USING_GLES2) +//#define DEBUG_OPENGL +#endif + +#if defined(DEBUG_OPENGL) + +void glCheckzor(const char *file, int line); +#define GL_CHECK() glCheckzor(__FILE__, __LINE__) + +#else + +#define GL_CHECK() + +#endif + + + diff --git a/ext/native/gfx/gl_lost_manager.cpp b/ext/native/gfx/gl_lost_manager.cpp new file mode 100644 index 0000000000..98cf37c52d --- /dev/null +++ b/ext/native/gfx/gl_lost_manager.cpp @@ -0,0 +1,76 @@ +#include + +#include "base/basictypes.h" +#include "base/logging.h" +#include "gfx/gl_lost_manager.h" + +std::vector *holders; + +static bool inLost; + +void register_gl_resource_holder(GfxResourceHolder *holder) { + if (inLost) { + FLOG("BAD: Should not call register_gl_resource_holder from lost path"); + return; + } + if (holders) { + holders->push_back(holder); + } else { + WLOG("GL resource holder not initialized, cannot register resource"); + } +} + +void unregister_gl_resource_holder(GfxResourceHolder *holder) { + if (inLost) { + FLOG("BAD: Should not call unregister_gl_resource_holder from lost path"); + return; + } + if (holders) { + for (size_t i = 0; i < holders->size(); i++) { + if ((*holders)[i] == holder) { + holders->erase(holders->begin() + i); + return; + } + } + WLOG("unregister_gl_resource_holder: Resource not registered"); + } else { + WLOG("GL resource holder not initialized or already shutdown, cannot unregister resource"); + } +} + +void gl_lost() { + inLost = true; + if (!holders) { + WLOG("GL resource holder not initialized, cannot process lost request"); + inLost = false; + return; + } + + // TODO: We should really do this when we get the context back, not during gl_lost... + ILOG("gl_lost() restoring %i items:", (int)holders->size()); + for (size_t i = 0; i < holders->size(); i++) { + ILOG("GLLost(%i / %i, %p)", (int)(i + 1), (int) holders->size(), (*holders)[i]); + (*holders)[i]->GLLost(); + } + ILOG("gl_lost() completed restoring %i items:", (int)holders->size()); + inLost = false; +} + +void gl_lost_manager_init() { + if (holders) { + FLOG("Double GL lost manager init"); + // Dead here (FLOG), no need to delete holders + } + holders = new std::vector(); +} + +void gl_lost_manager_shutdown() { + if (!holders) { + FLOG("Lost manager already shutdown"); + } else if (holders->size() > 0) { + ELOG("Lost manager shutdown with %i objects still registered", (int)holders->size()); + } + + delete holders; + holders = 0; +} diff --git a/ext/native/gfx/gl_lost_manager.h b/ext/native/gfx/gl_lost_manager.h new file mode 100644 index 0000000000..3d26ec3f3c --- /dev/null +++ b/ext/native/gfx/gl_lost_manager.h @@ -0,0 +1,19 @@ +#pragma once + +// On Android, even OpenGL can lose allocated resources. This is a utility to keep +// track of them. + +class GfxResourceHolder { +public: + virtual ~GfxResourceHolder() {} + virtual void GLLost() = 0; +}; + +void gl_lost_manager_init(); +void gl_lost_manager_shutdown(); + +void register_gl_resource_holder(GfxResourceHolder *holder); +void unregister_gl_resource_holder(GfxResourceHolder *holder); + +// Notifies all objects about the loss. +void gl_lost(); diff --git a/ext/native/gfx/texture.cpp b/ext/native/gfx/texture.cpp new file mode 100644 index 0000000000..62ef3860c8 --- /dev/null +++ b/ext/native/gfx/texture.cpp @@ -0,0 +1,376 @@ +#include +#include +#include + +#include "ext/rg_etc1/rg_etc1.h" +#include "ext/jpge/jpgd.h" +#include "image/png_load.h" +#include "image/zim_load.h" +#include "base/logging.h" +#include "gfx/texture.h" +#include "gfx/texture_gen.h" +#include "gfx/gl_debug_log.h" +#include "gfx/gl_lost_manager.h" +#include "gfx/gl_common.h" +#include "gfx_es2/gpu_features.h" + +Texture::Texture() : id_(0) { + CheckGLExtensions(); + register_gl_resource_holder(this); +} + +Texture::~Texture() { + unregister_gl_resource_holder(this); + Destroy(); +} + +void Texture::Destroy() { + if (id_) { + glDeleteTextures(1, &id_); + id_ = 0; + } +} + +void Texture::GLLost() { + if (!filename_.empty()) { + Load(filename_.c_str()); + ILOG("Reloaded lost texture %s", filename_.c_str()); + } else { + WLOG("Texture %p cannot be restored - has no filename", this); + Destroy(); + } +} + +static void SetTextureParameters(int zim_flags) { + GLenum wrap = GL_REPEAT; + if (zim_flags & ZIM_CLAMP) + wrap = GL_CLAMP_TO_EDGE; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + GL_CHECK(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if ((zim_flags & (ZIM_HAS_MIPS | ZIM_GEN_MIPS))) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + GL_CHECK(); +} + +bool Texture::Load(const char *filename) { + // hook for generated textures + if (!memcmp(filename, "gen:", 4)) { + int bpp, w, h; + bool clamp; + uint8_t *data = generateTexture(filename, bpp, w, h, clamp); + if (!data) + return false; + glGenTextures(1, &id_); + glBindTexture(GL_TEXTURE_2D, id_); + if (bpp == 1) { + if (gl_extensions.IsGLES) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, 1, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); + } + } else { + FLOG("unsupported"); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + delete [] data; + return true; + } + + filename_ = filename; + + // Currently here are a bunch of project-specific workarounds. + // They shouldn't really hurt anything else very much though. + + size_t len = strlen(filename); + char fn[1024]; + strncpy(fn, filename, sizeof(fn)); + fn[1023] = 0; + bool zim = false; + if (!strcmp("dds", &filename[len-3])) { + strcpy(&fn[len-3], "zim"); + zim = true; + } + if (!strcmp("6TX", &filename[len-3]) || !strcmp("6tx", &filename[len-3])) { + ILOG("Detected 6TX %s", filename); + strcpy(&fn[len-3], "zim"); + zim = true; + } + for (int i = 0; i < (int)strlen(fn); i++) { + if (fn[i] == '\\') fn[i] = '/'; + } + + if (fn[0] == 'm') fn[0] = 'M'; + const char *name = fn; + if (zim && 0==memcmp(name, "Media/textures/", strlen("Media/textures"))) name += strlen("Media/textures/"); + len = strlen(name); + if (!strcmp("png", &name[len-3]) || !strcmp("PNG", &name[len-3])) { + if (!LoadPNG(fn)) { + WLOG("WARNING: Failed to load .png %s, falling back to ugly gray XOR pattern!", fn); + LoadXOR(); + return false; + } else { + return true; + } + } else if (!strcmp("zim", &name[len-3])) { + if (LoadZIM(name)) { + return true; + } else { + WLOG("WARNING: Failed to load .zim texture %s, falling back to ugly gray XOR pattern!", fn); + LoadXOR(); + return false; + } + } else if (!strcmp("jpg", &name[len-3]) || !strcmp("JPG", &name[len-3]) || + !strcmp("jpeg", &name[len-4]) || !strcmp("JPEG", &name[len-4])) { + if (!LoadJPEG(fn)) { + WLOG("WARNING: Failed to load jpeg %s, falling back to ugly gray XOR pattern!", fn); + LoadXOR(); + return false; + } else { + return true; + } + } else if (!name || !strlen(name)) { + ELOG("Failed to identify image file %s by extension", name); + } else { + ELOG("Cannot load a texture with an empty filename"); + } + LoadXOR(); + return false; +} + +bool Texture::LoadPNG(const char *filename, bool genMips) { + unsigned char *image_data; + if (1 != pngLoad(filename, &width_, &height_, &image_data, false)) { + return false; + } + GL_CHECK(); + glGenTextures(1, &id_); + glBindTexture(GL_TEXTURE_2D, id_); + SetTextureParameters(genMips ? ZIM_GEN_MIPS : ZIM_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image_data); + if (genMips) { + if (gl_extensions.ARB_framebuffer_object) { + glGenerateMipmap(GL_TEXTURE_2D); + } else { +#ifndef USING_GLES2 + glGenerateMipmapEXT(GL_TEXTURE_2D); +#endif + } + } + GL_CHECK(); + free(image_data); + return true; +} + +bool Texture::LoadJPEG(const char *filename, bool genMips) { + ILOG("Loading jpeg %s", filename); + unsigned char *image_data; + int actual_comps; + image_data = jpgd::decompress_jpeg_image_from_file(filename, &width_, &height_, &actual_comps, 4); + if (!image_data) { + ELOG("jpeg: image data returned was 0"); + return false; + } + ILOG("Jpeg decoder failed to get RGB, got: %i x %i x %i", actual_comps, width_, height_); + ILOG("First four bytes: %i %i %i %i", image_data[0], image_data[1], image_data[2], image_data[3]); + + GL_CHECK(); + glGenTextures(1, &id_); + glBindTexture(GL_TEXTURE_2D, id_); + SetTextureParameters(genMips ? ZIM_GEN_MIPS : ZIM_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data); + if (genMips) { + if (gl_extensions.ARB_framebuffer_object) { + glGenerateMipmap(GL_TEXTURE_2D); + } else { +#ifndef USING_GLES2 + glGenerateMipmapEXT(GL_TEXTURE_2D); +#endif + } + } + GL_CHECK(); + free(image_data); + return true; +} + +bool Texture::LoadPNG(const uint8_t *data, size_t size, bool genMips) { + unsigned char *image_data; + if (1 != pngLoadPtr(data, size, &width_, &height_, &image_data, false)) { + return false; + } + GL_CHECK(); + // TODO: should check for power of 2 tex size and disallow genMips when not. + glGenTextures(1, &id_); + glBindTexture(GL_TEXTURE_2D, id_); + SetTextureParameters(genMips ? ZIM_GEN_MIPS : ZIM_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data); + if (genMips) { + if (gl_extensions.ARB_framebuffer_object) { + glGenerateMipmap(GL_TEXTURE_2D); + } else { +#ifndef USING_GLES2 + glGenerateMipmapEXT(GL_TEXTURE_2D); +#endif + } + } + GL_CHECK(); + free(image_data); + return true; +} + +bool Texture::LoadXOR() { + width_ = height_ = 256; + unsigned char *buf = new unsigned char[width_*height_*4]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + buf[(y*width_ + x)*4 + 0] = x^y; + buf[(y*width_ + x)*4 + 1] = x^y; + buf[(y*width_ + x)*4 + 2] = x^y; + buf[(y*width_ + x)*4 + 3] = 0xFF; + } + } + GL_CHECK(); + glGenTextures(1, &id_); + glBindTexture(GL_TEXTURE_2D, id_); + SetTextureParameters(ZIM_GEN_MIPS); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, + GL_RGBA, GL_UNSIGNED_BYTE, buf); + if(gl_extensions.ARB_framebuffer_object){ + glGenerateMipmap(GL_TEXTURE_2D); + }else{ +#ifndef USING_GLES2 + glGenerateMipmapEXT(GL_TEXTURE_2D); +#endif + } + GL_CHECK(); + delete [] buf; + return true; +} + + +#if !defined(USING_GLES2) || defined(IOS) + +// Allocates using new[], doesn't free. +uint8_t *ETC1ToRGBA(uint8_t *etc1, int width, int height) { + uint8_t *rgba = new uint8_t[width * height * 4]; + memset(rgba, 0xFF, width * height * 4); + for (int y = 0; y < height; y += 4) { + for (int x = 0; x < width; x += 4) { + rg_etc1::unpack_etc1_block(etc1 + ((y / 4) * width/4 + (x / 4)) * 8, + (uint32_t *)rgba + (y * width + x), width, false); + } + } + return rgba; +} + +#endif + +bool Texture::LoadZIM(const char *filename) { + uint8_t *image_data[ZIM_MAX_MIP_LEVELS]; + int width[ZIM_MAX_MIP_LEVELS]; + int height[ZIM_MAX_MIP_LEVELS]; + + int flags; + int num_levels = ::LoadZIM(filename, &width[0], &height[0], &flags, &image_data[0]); + if (!num_levels) + return false; + if (num_levels >= ZIM_MAX_MIP_LEVELS) + return false; + width_ = width[0]; + height_ = height[0]; + int data_type = GL_UNSIGNED_BYTE; + int colors = GL_RGBA; + int storage = GL_RGBA; + bool compressed = false; + switch (flags & ZIM_FORMAT_MASK) { + case ZIM_RGBA8888: + data_type = GL_UNSIGNED_BYTE; + break; + case ZIM_RGBA4444: + data_type = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case ZIM_RGB565: + data_type = GL_UNSIGNED_SHORT_5_6_5; + colors = GL_RGB; + storage = GL_RGB; + break; + case ZIM_ETC1: + compressed = true; + break; + } + + GL_CHECK(); + + glGenTextures(1, &id_); + glBindTexture(GL_TEXTURE_2D, id_); + SetTextureParameters(flags); + + if (compressed) { + for (int l = 0; l < num_levels; l++) { + int data_w = width[l]; + int data_h = height[l]; + if (data_w < 4) data_w = 4; + if (data_h < 4) data_h = 4; +#if defined(USING_GLES2) && !defined(IOS) + int compressed_image_bytes = data_w * data_h / 2; + glCompressedTexImage2D(GL_TEXTURE_2D, l, GL_ETC1_RGB8_OES, width[l], height[l], 0, compressed_image_bytes, image_data[l]); + GL_CHECK(); +#else + // TODO: OpenGL 4.3+ accepts ETC1 so we should not have to do this anymore on those cards. + // Also, iOS does not have support for ETC1 compressed textures so we just decompress. + // TODO: Use PVR texture compression on iOS. + image_data[l] = ETC1ToRGBA(image_data[l], data_w, data_h); + glTexImage2D(GL_TEXTURE_2D, l, GL_RGBA, width[l], height[l], 0, + GL_RGBA, GL_UNSIGNED_BYTE, image_data[l]); +#endif + } + GL_CHECK(); +#if !defined(USING_GLES2) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, num_levels - 2); +#endif + } else { + for (int l = 0; l < num_levels; l++) { + glTexImage2D(GL_TEXTURE_2D, l, storage, width[l], height[l], 0, + colors, data_type, image_data[l]); + } + if (num_levels == 1 && (flags & ZIM_GEN_MIPS)) { + if(gl_extensions.ARB_framebuffer_object) { + glGenerateMipmap(GL_TEXTURE_2D); + }else{ +#ifndef USING_GLES2 + glGenerateMipmapEXT(GL_TEXTURE_2D); +#endif + } + } + } + SetTextureParameters(flags); + + GL_CHECK(); + // Only free the top level, since the allocation is used for all of them. + free(image_data[0]); + return true; +} + +void Texture::Bind(int stage) { + GL_CHECK(); + if (stage != -1) + glActiveTexture(GL_TEXTURE0 + stage); + glBindTexture(GL_TEXTURE_2D, id_); + GL_CHECK(); +} + +void Texture::Unbind(int stage) { + GL_CHECK(); + if (stage != -1) + glActiveTexture(GL_TEXTURE0 + stage); + glBindTexture(GL_TEXTURE_2D, 0); + GL_CHECK(); +} diff --git a/ext/native/gfx/texture.h b/ext/native/gfx/texture.h new file mode 100644 index 0000000000..702cb74189 --- /dev/null +++ b/ext/native/gfx/texture.h @@ -0,0 +1,54 @@ +#pragma once + +// Load and manage OpenGL textures easily. Supports ETC1 compressed texture with mipmaps +// in the custom ZIM format. + +// This is deprecated - start using Thin3D instead. + +#include + +#include "base/basictypes.h" +#include "gfx/gl_lost_manager.h" + +class Texture : public GfxResourceHolder { +public: + Texture(); + ~Texture(); + + // Deduces format from the filename. + // If loading fails, will load a 256x256 XOR texture. + // If filename begins with "gen:", will defer to texture_gen.cpp/h. + // When format is known, it's fine to use LoadZIM etc directly. + // Those will NOT auto-fall back to xor texture however! + bool Load(const char *filename); + void Bind(int stage = -1); + void Destroy(); + + // PNG from memory buffer + bool LoadPNG(const uint8_t *data, size_t size, bool genMips = true); + bool LoadZIM(const char *filename); + bool LoadPNG(const char *filename, bool genMips = true); + bool LoadJPEG(const char *filename, bool genMips = true); + + unsigned int Handle() const { + return id_; + } + + virtual void GLLost(); + std::string filename() const { return filename_; } + + static void Unbind(int stage = -1); + + int Width() const { return width_; } + int Height() const { return height_; } + +private: + bool LoadXOR(); // Loads a placeholder texture. + + std::string filename_; +#ifdef METRO + ID3D11Texture2D *tex_; +#endif + unsigned int id_; + int width_, height_; +}; diff --git a/ext/native/gfx/texture_atlas.cpp b/ext/native/gfx/texture_atlas.cpp new file mode 100644 index 0000000000..275d17f0cb --- /dev/null +++ b/ext/native/gfx/texture_atlas.cpp @@ -0,0 +1,33 @@ +#include +#include "gfx/texture_atlas.h" + +const AtlasFont *Atlas::getFontByName(const char *name) const +{ + for (int i = 0; i < num_fonts; i++) { + if (!strcmp(name, fonts[i]->name)) + return fonts[i]; + } + return 0; +} + +const AtlasImage *Atlas::getImageByName(const char *name) const +{ + for (int i = 0; i < num_images; i++) { + if (!strcmp(name, images[i].name)) + return &images[i]; + } + return 0; +} + +const AtlasChar *AtlasFont::getChar(int utf32) const { + for (int i = 0; i < numRanges; i++) { + if (utf32 >= ranges[i].start && utf32 < ranges[i].end) { + const AtlasChar *c = &charData[ranges[i].start_index + utf32 - ranges[i].start]; + if (c->ex == 0 && c->ey == 0) + return 0; + else + return c; + } + } + return 0; +} diff --git a/ext/native/gfx/texture_atlas.h b/ext/native/gfx/texture_atlas.h new file mode 100644 index 0000000000..54949e1253 --- /dev/null +++ b/ext/native/gfx/texture_atlas.h @@ -0,0 +1,52 @@ +#pragma once + +typedef int ImageID; + +struct AtlasChar { + // texcoords + float sx, sy, ex, ey; + // offset from the origin + float ox, oy; + // distance to move the origin forward + float wx; + // size in pixels + unsigned short pw, ph; +}; + +struct AtlasCharRange { + int start; + int end; + int start_index; +}; + +struct AtlasFont { + float padding; + float height; + float ascend; + float distslope; + const AtlasChar *charData; + const AtlasCharRange *ranges; + int numRanges; + const char *name; + + // Returns 0 on no match. + const AtlasChar *getChar(int utf32) const ; +}; + +struct AtlasImage { + float u1, v1, u2, v2; + int w, h; + const char *name; +}; + +struct Atlas { + const char *filename; + const AtlasFont **fonts; + int num_fonts; + const AtlasImage *images; + int num_images; + + // These are inefficient linear searches, try not to call every frame. + const AtlasFont *getFontByName(const char *name) const; + const AtlasImage *getImageByName(const char *name) const; +}; diff --git a/ext/native/gfx/texture_dx11.cpp b/ext/native/gfx/texture_dx11.cpp new file mode 100644 index 0000000000..5737aba3ca --- /dev/null +++ b/ext/native/gfx/texture_dx11.cpp @@ -0,0 +1,271 @@ +// WIP, please ignore +#include + +#include +#include +#include + +#if !defined(USING_GLES2) +#include "image/png_load.h" +#include "ext/etcpack/etcdec.h" +#endif + +#include "image/zim_load.h" +#include "base/logging.h" +#include "gfx/texture.h" +#include "gfx/texture_gen.h" +#include "gfx/gl_debug_log.h" +#include "gfx/gl_lost_manager.h" + +Texture::Texture() : tex_(0) { + register_gl_resource_holder(this); + + + +} + +void Texture::Destroy() { + if (tex_) { + tex_->Release(); + tex_ = 0; + } +} + +void Texture::GLLost() { + ILOG("Reloading lost texture %s", filename_.c_str()); + Load(filename_.c_str()); +} + +Texture::~Texture() { + unregister_gl_resource_holder(this); + Destroy(); +} + +static void SetTextureParameters(int zim_flags) { +/* + GLenum wrap = GL_REPEAT; + if (zim_flags & ZIM_CLAMP) wrap = GL_CLAMP_TO_EDGE; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + GL_CHECK(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if ((zim_flags & (ZIM_HAS_MIPS | ZIM_GEN_MIPS))) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + GL_CHECK();*/ +} + +bool Texture::Load(const char *filename) { + // hook for generated textures + if (!memcmp(filename, "gen:", 4)) { + // TODO + // return false; + tex_ = (LPVOID)generateTexture(filename); + if (tex_) { + this->filename_ = filename; + } + return true; + } + + filename_ = filename; + // Currently contains many Rollerball-specific workarounds. + // They shouldn't really hurt anything else very much though. + int len = strlen(filename); + char fn[256]; + strcpy(fn, filename); + bool zim = false; + if (!strcmp("dds", &filename[len-3])) { + strcpy(&fn[len-3], "zim"); + zim = true; + } + if (!strcmp("6TX", &filename[len-3]) || !strcmp("6tx", &filename[len-3])) { + ILOG("Detected 6TX %s", filename); + strcpy(&fn[len-3], "zim"); + zim = true; + } + for (int i = 0; i < (int)strlen(fn); i++) { + if (fn[i] == '\\') fn[i] = '/'; + } + + if (fn[0] == 'm') fn[0] = 'M'; + const char *name = fn; + if (zim && 0 == memcmp(name, "Media/textures/", strlen("Media/textures"))) name += strlen("Media/textures/"); + len = strlen(name); + #if !defined(USING_GLES2) + if (!strcmp("png", &name[len-3]) || + !strcmp("PNG", &name[len-3])) { + if (!LoadPNG(fn)) { + LoadXOR(); + return false; + } else { + return true; + } + } else + #endif + if (!strcmp("zim", &name[len-3])) { + if (!LoadZIM(name)) { + LoadXOR(); + return false; + } else { + return true; + } + } + LoadXOR(); + return false; +} + +#ifndef METRO +#if !defined(USING_GLES2) +bool Texture::LoadPNG(const char *filename) { + unsigned char *image_data; + if (1 != pngLoad(filename, &width_, &height_, &image_data, false)) { + return false; + } + GL_CHECK(); + glGenTextures(1, &id_); + glBindTexture(GL_TEXTURE_2D, id_); + SetTextureParameters(ZIM_GEN_MIPS); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image_data); + glGenerateMipmap(GL_TEXTURE_2D); + GL_CHECK(); + free(image_data); + return true; +} +#endif +#endif + +bool Texture::LoadXOR() { + width_ = height_ = 256; + unsigned char *buf = new unsigned char[width_*height_*4]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + buf[(y*width_ + x)*4 + 0] = x^y; + buf[(y*width_ + x)*4 + 1] = x^y; + buf[(y*width_ + x)*4 + 2] = x^y; + buf[(y*width_ + x)*4 + 3] = 0xFF; + } + } + GL_CHECK(); + ID3D11Device *ctx; + D3D11_TEXTURE2D_DESC desc; + desc.Width = width_; + desc.Height = height_; + desc.MipLevels = 0; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + if (FAILED(ctx->CreateTexture2D(&desc, 0, &tex_))) { + FLOG("Failed creating XOR texture"); + } + SetTextureParameters(ZIM_GEN_MIPS); + GL_CHECK(); + delete [] buf; + return true; +} + + +#if !defined(USING_GLES2) + +// Allocates using new[], doesn't free. +uint8_t *ETC1ToRGBA(uint8_t *etc1, int width, int height) { + uint8_t *rgba = new uint8_t[width * height * 4]; + memset(rgba, 0xFF, width * height * 4); + for (int y = 0; y < height; y += 4) { + for (int x = 0; x < width; x += 4) { + DecompressBlock(etc1 + ((y / 4) * width/4 + (x / 4)) * 8, + rgba + (y * width + x) * 4, width, 255); + } + } + return rgba; +} + +#endif + +bool Texture::LoadZIM(const char *filename) { + uint8_t *image_data[ZIM_MAX_MIP_LEVELS]; + int width[ZIM_MAX_MIP_LEVELS]; + int height[ZIM_MAX_MIP_LEVELS]; + + int flags; + int num_levels = ::LoadZIM(filename, &width[0], &height[0], &flags, &image_data[0]); + if (!num_levels) + return false; + width_ = width[0]; + height_ = height[0]; + int data_type = GL_UNSIGNED_BYTE; + int colors = GL_RGBA; + int storage = GL_RGBA; + bool compressed = false; + switch (flags & ZIM_FORMAT_MASK) { + case ZIM_RGBA8888: + data_type = GL_UNSIGNED_BYTE; + break; + case ZIM_RGBA4444: + data_type = DXGI_FORMAT_B4G4R4A4_UNORM; + break; + case ZIM_RGB565: + data_type = DXGI_FORMAT_B5G6R5_UNORM; + colors = GL_RGB; + storage = GL_RGB; + break; + case ZIM_ETC1: + compressed = true; + break; + } + + GL_CHECK(); + //glGenTextures(1, &id_); + //glBindTexture(GL_TEXTURE_2D, id_); + SetTextureParameters(flags); + + if (compressed) { + for (int l = 0; l < num_levels; l++) { + int data_w = width[l]; + int data_h = height[l]; + if (data_w < 4) data_w = 4; + if (data_h < 4) data_h = 4; +#if defined(USING_GLES2) + int compressed_image_bytes = data_w * data_h / 2; + glCompressedTexImage2D(GL_TEXTURE_2D, l, GL_ETC1_RGB8_OES, width[l], height[l], 0, compressed_image_bytes, image_data[l]); + GL_CHECK(); +#else + //image_data[l] = ETC1ToRGBA(image_data[l], data_w, data_h); + //glTexImage2D(GL_TEXTURE_2D, l, GL_RGBA, width[l], height[l], 0, + // GL_RGBA, GL_UNSIGNED_BYTE, image_data[l]); +#endif + } + GL_CHECK(); +#if !defined(USING_GLES2) + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, num_levels - 2); +#endif + } else { + for (int l = 0; l < num_levels; l++) { + //glTexImage2D(GL_TEXTURE_2D, l, storage, width[l], height[l], 0, + // colors, data_type, image_data[l]); + } + if (num_levels == 1 && (flags & ZIM_GEN_MIPS)) { + //glGenerateMipmap(GL_TEXTURE_2D); + } + } + SetTextureParameters(flags); + + GL_CHECK(); + // Only free the top level, since the allocation is used for all of them. + delete [] image_data[0]; + return true; +} + +void Texture::Bind(int stage) { + GL_CHECK(); + //if (stage != -1) + // glActiveTexture(GL_TEXTURE0 + stage); + // glBindTexture(GL_TEXTURE_2D, id_); + GL_CHECK(); +} diff --git a/ext/native/gfx/texture_gen.cpp b/ext/native/gfx/texture_gen.cpp new file mode 100644 index 0000000000..673126de72 --- /dev/null +++ b/ext/native/gfx/texture_gen.cpp @@ -0,0 +1,55 @@ +// Minimal procedural texture generator to generate some usual textures like circles and vignette textures. +// "Gen" textures have filenames like this: "gen:256:256:vignette:0.1" +// +// These must be VERY VERY fast to not slow down loading. Could multicore this in the +// future. + +#include +#include +#include + +#include "base/basictypes.h" +#include "gfx/texture.h" + + +uint8_t *generateTexture(const char *filename, int &bpp, int &w, int &h, bool &clamp) { + char name_and_params[256]; + // security check :) + if (strlen(filename) > 200) + return 0; + sscanf(filename, "gen:%i:%i:%s", &w, &h, name_and_params); + + uint8_t *data; + if (!strcmp(name_and_params, "vignette")) { + bpp = 1; + data = new uint8_t[w*h]; + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; x++) { + float dx = (float)(x - w/2) / (w/2); + float dy = (float)(y - h/2) / (h/2); + float dist = sqrtf(dx * dx + dy * dy); + dist /= 1.414f; + float val = 1.0 - powf(dist, 1.4f); + data[y*w + x] = val * 255; + } + } + } else if (!strcmp(name_and_params, "circle")) { + bpp = 1; + // TODO + data = new uint8_t[w*h]; + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; x++) { + float dx = (float)(x - w/2) / (w/2); + float dy = (float)(y - h/2) / (h/2); + float dist = sqrtf(dx * dx + dy * dy); + dist /= 1.414f; + float val = 1.0 - powf(dist, 1.4f); + data[y*w + x] = val * 255; + } + } + } else { + data = NULL; + } + + return data; +} diff --git a/ext/native/gfx/texture_gen.h b/ext/native/gfx/texture_gen.h new file mode 100644 index 0000000000..063aeae8cb --- /dev/null +++ b/ext/native/gfx/texture_gen.h @@ -0,0 +1,6 @@ +// Minimal procedural texture generator to generate some useful but unnecessary-to-store textures like circles. +// "Gen" textures have filenames like this: "gen:256:256:4444:vignette:0.1" + +#include "gfx/texture.h" + +uint8_t *generateTexture(const char *filename, int &bpp, int &w, int &h, bool &clamp); diff --git a/ext/native/gfx_es2/CMakeLists.txt b/ext/native/gfx_es2/CMakeLists.txt new file mode 100644 index 0000000000..9d2471f50e --- /dev/null +++ b/ext/native/gfx_es2/CMakeLists.txt @@ -0,0 +1,18 @@ +set(SRCS + draw_buffer.cpp + draw_text.cpp + fbo.cpp + glsl_program.cpp + gpu_features.cpp + gl_state.cpp + vertex_format.cpp) + +set(SRCS ${SRCS}) + +add_library(gfx_es2 STATIC ${SRCS}) +target_link_libraries(gfx_es2 general gfx) +target_link_libraries(gfx_es2 general file) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp new file mode 100644 index 0000000000..ee333ed3bc --- /dev/null +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -0,0 +1,477 @@ +#include +#include +#include +#include + +#include "base/display.h" +#include "base/logging.h" +#include "math/math_util.h" +#include "gfx/texture_atlas.h" +#include "gfx/gl_debug_log.h" +#include "gfx/gl_common.h" +#include "gfx_es2/draw_buffer.h" +#include "gfx_es2/draw_text.h" +#include "gfx_es2/glsl_program.h" +#include "util/text/utf8.h" + +enum { + // Enough? + MAX_VERTS = 65536, +}; + +// #define USE_VBO + +DrawBuffer::DrawBuffer() : count_(0), atlas(0) { + verts_ = new Vertex[MAX_VERTS]; + fontscalex = 1.0f; + fontscaley = 1.0f; + inited_ = false; +} + +DrawBuffer::~DrawBuffer() { + delete [] verts_; +} + +void DrawBuffer::Init(Thin3DContext *t3d) { + if (inited_) + return; + + t3d_ = t3d; +#ifdef USE_VBO + vbuf_ = t3d_->CreateBuffer(MAX_VERTS * sizeof(Vertex), T3DBufferUsage::DYNAMIC | T3DBufferUsage::VERTEXDATA); +#else + vbuf_ = nullptr; +#endif + inited_ = true; + + std::vector components; + components.push_back(Thin3DVertexComponent("Position", SEM_POSITION, FLOATx3, 0)); + components.push_back(Thin3DVertexComponent("TexCoord0", SEM_TEXCOORD0, FLOATx2, 12)); + components.push_back(Thin3DVertexComponent("Color0", SEM_COLOR0, UNORM8x4, 20)); + + Thin3DShader *vshader = t3d_->GetVshaderPreset(VS_TEXTURE_COLOR_2D); + + vformat_ = t3d_->CreateVertexFormat(components, 24, vshader); +} + +void DrawBuffer::Shutdown() { + if (vbuf_) { + vbuf_->Release(); + } + vformat_->Release(); + + inited_ = false; +} + +void DrawBuffer::Begin(Thin3DShaderSet *program, DrawBufferPrimitiveMode dbmode) { + shaderSet_ = program; + count_ = 0; + mode_ = dbmode; +} + +void DrawBuffer::End() { + // Currently does nothing, but call it! +} + +void DrawBuffer::Flush(bool set_blend_state) { + if (!shaderSet_) { + ELOG("No program set!"); + return; + } + + if (count_ == 0) + return; + + shaderSet_->SetMatrix4x4("WorldViewProj", drawMatrix_); +#ifdef USE_VBO + vbuf_->SubData((const uint8_t *)verts_, 0, sizeof(Vertex) * count_); + int offset = 0; + t3d_->Draw(mode_ == DBMODE_NORMAL ? PRIM_TRIANGLES : PRIM_LINES, shaderSet_, vformat_, vbuf_, count_, offset); +#else + t3d_->DrawUP(mode_ == DBMODE_NORMAL ? PRIM_TRIANGLES : PRIM_LINES, shaderSet_, vformat_, (const void *)verts_, count_); +#endif + count_ = 0; +} + +void DrawBuffer::V(float x, float y, float z, uint32_t color, float u, float v) { + if (count_ >= MAX_VERTS) { + FLOG("Overflowed the DrawBuffer"); + return; + } + + Vertex *vert = &verts_[count_++]; + vert->x = x; + vert->y = y; + vert->z = z; + vert->rgba = color; + vert->u = u; + vert->v = v; +} + +void DrawBuffer::Rect(float x, float y, float w, float h, uint32_t color, int align) { + DoAlign(align, &x, &y, &w, &h); + RectVGradient(x, y, w, h, color, color); +} + +void DrawBuffer::hLine(float x1, float y, float x2, uint32_t color) { + Rect(x1, y, x2 - x1, pixel_in_dps, color); +} + +void DrawBuffer::vLine(float x, float y1, float y2, uint32_t color) { + Rect(x, y1, pixel_in_dps, y2 - y1, color); +} + +void DrawBuffer::vLineAlpha50(float x, float y1, float y2, uint32_t color) { + Rect(x, y1, pixel_in_dps, y2 - y1, (color | 0xFF000000) & 0x7F000000); +} + +void DrawBuffer::RectVGradient(float x, float y, float w, float h, uint32_t colorTop, uint32_t colorBottom) { + V(x, y, 0, colorTop, 0, 0); + V(x + w, y, 0, colorTop, 1, 0); + V(x + w, y + h, 0, colorBottom, 1, 1); + V(x, y, 0, colorTop, 0, 0); + V(x + w, y + h, 0, colorBottom, 1, 1); + V(x, y + h, 0, colorBottom, 0, 1); +} + +void DrawBuffer::RectOutline(float x, float y, float w, float h, uint32_t color, int align) { + hLine(x, y, x + w + pixel_in_dps, color); + hLine(x, y + h, x + w + pixel_in_dps, color); + + vLine(x, y, y + h + pixel_in_dps, color); + vLine(x + w, y, y + h + pixel_in_dps, color); +} + +void DrawBuffer::MultiVGradient(float x, float y, float w, float h, GradientStop *stops, int numStops) { + for (int i = 0; i < numStops - 1; i++) { + float t0 = stops[i].t, t1 = stops[i+1].t; + uint32_t c0 = stops[i].t, c1 = stops[i+1].t; + RectVGradient(x, y + h * t0, w, h * (t1 - t0), c0, c1); + } +} + +void DrawBuffer::Rect(float x, float y, float w, float h, + float u, float v, float uw, float uh, + uint32_t color) { + V(x, y, 0, color, u, v); + V(x + w, y, 0, color, u + uw, v); + V(x + w, y + h, 0, color, u + uw, v + uh); + V(x, y, 0, color, u, v); + V(x + w, y + h, 0, color, u + uw, v + uh); + V(x, y + h, 0, color, u, v + uh); +} + +void DrawBuffer::Line(int atlas_image, float x1, float y1, float x2, float y2, float thickness, uint32_t color) { + const AtlasImage &image = atlas->images[atlas_image]; + + // No caps yet! + // Pre-rotated - we are making a thick line here + float dx = -(y2 - y1); + float dy = x2 - x1; + float len = sqrtf(dx * dx + dy * dy) / thickness; + if (len <= 0.0f) + len = 1.0f; + + dx /= len; + dy /= len; + + float x[4] = { x1 - dx, x2 - dx, x1 + dx, x2 + dx }; + float y[4] = { y1 - dy, y2 - dy, y1 + dy, y2 + dy }; + + V(x[0], y[0], color, image.u1, image.v1); + V(x[1], y[1], color, image.u2, image.v1); + V(x[2], y[2], color, image.u1, image.v2); + V(x[2], y[2], color, image.u1, image.v2); + V(x[1], y[1], color, image.u2, image.v1); + V(x[3], y[3], color, image.u2, image.v2); +} + +void DrawBuffer::MeasureImage(ImageID atlas_image, float *w, float *h) { + const AtlasImage &image = atlas->images[atlas_image]; + *w = (float)image.w; + *h = (float)image.h; +} + +void DrawBuffer::DrawImage(ImageID atlas_image, float x, float y, float scale, Color color, int align) { + const AtlasImage &image = atlas->images[atlas_image]; + float w = (float)image.w * scale; + float h = (float)image.h * scale; + if (align & ALIGN_HCENTER) x -= w / 2; + if (align & ALIGN_RIGHT) x -= w; + if (align & ALIGN_VCENTER) y -= h / 2; + if (align & ALIGN_BOTTOM) y -= h; + DrawImageStretch(atlas_image, x, y, x + w, y + h, color); +} + +void DrawBuffer::DrawImageStretch(ImageID atlas_image, float x1, float y1, float x2, float y2, Color color) { + const AtlasImage &image = atlas->images[atlas_image]; + V(x1, y1, color, image.u1, image.v1); + V(x2, y1, color, image.u2, image.v1); + V(x2, y2, color, image.u2, image.v2); + V(x1, y1, color, image.u1, image.v1); + V(x2, y2, color, image.u2, image.v2); + V(x1, y2, color, image.u1, image.v2); +} + +inline void rot(float *v, float angle, float xc, float yc) { + const float x = v[0] - xc; + const float y = v[1] - yc; + const float sa = sinf(angle); + const float ca = cosf(angle); + v[0] = x * ca + y * -sa + xc; + v[1] = x * sa + y * ca + yc; +} + +void DrawBuffer::DrawImageRotated(ImageID atlas_image, float x, float y, float scale, float angle, Color color, bool mirror_h) { + const AtlasImage &image = atlas->images[atlas_image]; + float w = (float)image.w * scale; + float h = (float)image.h * scale; + float x1 = x - w / 2; + float x2 = x + w / 2; + float y1 = y - h / 2; + float y2 = y + h / 2; + float v[6][2] = { + {x1, y1}, + {x2, y1}, + {x2, y2}, + {x1, y1}, + {x2, y2}, + {x1, y2}, + }; + float u1 = image.u1; + float u2 = image.u2; + if (mirror_h) { + float temp = u1; + u1 = u2; + u2 = temp; + } + const float uv[6][2] = { + {u1, image.v1}, + {u2, image.v1}, + {u2, image.v2}, + {u1, image.v1}, + {u2, image.v2}, + {u1, image.v2}, + }; + for (int i = 0; i < 6; i++) { + rot(v[i], angle, x, y); + V(v[i][0], v[i][1], 0, color, uv[i][0], uv[i][1]); + } +} + +// TODO: add arc support +void DrawBuffer::Circle(float xc, float yc, float radius, float thickness, int segments, float startAngle, uint32_t color, float u_mul) { + float angleDelta = PI * 2 / segments; + float uDelta = 1.0f / segments; + float t2 = thickness / 2.0f; + float r1 = radius + t2; + float r2 = radius - t2; + for (int i = 0; i < segments + 1; i++) { + float angle1 = i * angleDelta; + float angle2 = (i + 1) * angleDelta; + float u1 = u_mul * i * uDelta; + float u2 = u_mul * (i + 1) * uDelta; + // TODO: get rid of one pair of cos/sin per loop, can reuse from last iteration + float c1 = cosf(angle1), s1 = sinf(angle1), c2 = cosf(angle2), s2 = sinf(angle2); + const float x[4] = {c1 * r1 + xc, c2 * r1 + xc, c1 * r2 + xc, c2 * r2 + xc}; + const float y[4] = {s1 * r1 + yc, s2 * r1 + yc, s1 * r2 + yc, s2 * r2 + yc}; + V(x[0], y[0], color, u1, 0); + V(x[1], y[1], color, u2, 0); + V(x[2], y[2], color, u1, 1); + V(x[1], y[1], color, u2, 0); + V(x[3], y[3], color, u2, 1); + V(x[2], y[2], color, u1, 1); + } +} + +void DrawBuffer::DrawTexRect(float x1, float y1, float x2, float y2, float u1, float v1, float u2, float v2, Color color) { + V(x1, y1, color, u1, v1); + V(x2, y1, color, u2, v1); + V(x2, y2, color, u2, v2); + V(x1, y1, color, u1, v1); + V(x2, y2, color, u2, v2); + V(x1, y2, color, u1, v2); +} + +void DrawBuffer::DrawImage4Grid(ImageID atlas_image, float x1, float y1, float x2, float y2, Color color, float corner_scale) { + const AtlasImage &image = atlas->images[atlas_image]; + + float u1 = image.u1, v1 = image.v1, u2 = image.u2, v2 = image.v2; + float um = (u2 + u1) * 0.5f; + float vm = (v2 + v1) * 0.5f; + float iw2 = (image.w * 0.5f) * corner_scale; + float ih2 = (image.h * 0.5f) * corner_scale; + float xa = x1 + iw2; + float xb = x2 - iw2; + float ya = y1 + ih2; + float yb = y2 - ih2; + // Top row + DrawTexRect(x1, y1, xa, ya, u1, v1, um, vm, color); + DrawTexRect(xa, y1, xb, ya, um, v1, um, vm, color); + DrawTexRect(xb, y1, x2, ya, um, v1, u2, vm, color); + // Middle row + DrawTexRect(x1, ya, xa, yb, u1, vm, um, vm, color); + DrawTexRect(xa, ya, xb, yb, um, vm, um, vm, color); + DrawTexRect(xb, ya, x2, yb, um, vm, u2, vm, color); + // Bottom row + DrawTexRect(x1, yb, xa, y2, u1, vm, um, v2, color); + DrawTexRect(xa, yb, xb, y2, um, vm, um, v2, color); + DrawTexRect(xb, yb, x2, y2, um, vm, u2, v2, color); +} + +void DrawBuffer::DrawImage2GridH(ImageID atlas_image, float x1, float y1, float x2, Color color, float corner_scale) { + const AtlasImage &image = atlas->images[atlas_image]; + float um = (image.u1 + image.u2) * 0.5f; + float iw2 = (image.w * 0.5f) * corner_scale; + float xa = x1 + iw2; + float xb = x2 - iw2; + float u1 = image.u1, v1 = image.v1, u2 = image.u2, v2 = image.v2; + float y2 = y1 + image.h; + DrawTexRect(x1, y1, xa, y2, u1, v1, um, v2, color); + DrawTexRect(xa, y1, xb, y2, um, v1, um, v2, color); + DrawTexRect(xb, y1, x2, y2, um, v1, u2, v2, color); +} + +void DrawBuffer::MeasureTextCount(int font, const char *text, int count, float *w, float *h) { + const AtlasFont &atlasfont = *atlas->fonts[font]; + + unsigned int cval; + float wacc = 0; + float maxX = 0.0f; + int lines = 1; + UTF8 utf(text); + while (true) { + if (utf.end()) + break; + if (utf.byteIndex() >= count) + break; + cval = utf.next(); + // Translate non-breaking space to space. + if (cval == 0xA0) { + cval = ' '; + } + if (cval == '\n') { + maxX = std::max(maxX, wacc); + wacc = 0; + lines++; + continue; + } else if (cval == '&' && utf.peek() != '&') { + // Ignore lone ampersands + continue; + } + const AtlasChar *c = atlasfont.getChar(cval); + if (c) { + wacc += c->wx * fontscalex; + } + } + if (w) *w = std::max(wacc, maxX); + if (h) *h = atlasfont.height * fontscaley * lines; +} + +void DrawBuffer::MeasureText(int font, const char *text, float *w, float *h) { + return MeasureTextCount(font, text, (int)strlen(text), w, h); +} + +void DrawBuffer::DrawTextShadow(int font, const char *text, float x, float y, Color color, int flags) { + uint32_t alpha = (color >> 1) & 0xFF000000; + DrawText(font, text, x + 2, y + 2, alpha, flags); + DrawText(font, text, x, y, color, flags); +} + +void DrawBuffer::DoAlign(int flags, float *x, float *y, float *w, float *h) { + if (flags & ALIGN_HCENTER) *x -= *w / 2; + if (flags & ALIGN_RIGHT) *x -= *w; + if (flags & ALIGN_VCENTER) *y -= *h / 2; + if (flags & ALIGN_BOTTOM) *y -= *h; + if (flags & (ROTATE_90DEG_LEFT | ROTATE_90DEG_RIGHT)) { + std::swap(*w, *h); + std::swap(*x, *y); + } +} + + +// TODO: Actually use the rect properly, take bounds. +void DrawBuffer::DrawTextRect(int font, const char *text, float x, float y, float w, float h, Color color, int align) { + if (align & ALIGN_HCENTER) { + x += w / 2; + } else if (align & ALIGN_RIGHT) { + x += w; + } + if (align & ALIGN_VCENTER) { + y += h / 2; + } else if (align & ALIGN_BOTTOM) { + y += h; + } + + DrawText(font, text, x, y, color, align); +} + +// ROTATE_* doesn't yet work right. +void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color color, int align) { + // rough estimate + if (count_ + strlen(text) * 6 > MAX_VERTS) { + Flush(true); + } + + const AtlasFont &atlasfont = *atlas->fonts[font]; + unsigned int cval; + float w, h; + MeasureText(font, text, &w, &h); + if (align) { + DoAlign(align, &x, &y, &w, &h); + } + + if (align & ROTATE_90DEG_LEFT) { + x -= atlasfont.ascend*fontscaley; + // y += h; + } + else + y += atlasfont.ascend*fontscaley; + float sx = x; + UTF8 utf(text); + while (true) { + if (utf.end()) + break; + cval = utf.next(); + // Translate non-breaking space to space. + if (cval == 0xA0) { + cval = ' '; + } + if (cval == '\n') { + y += atlasfont.height * fontscaley; + x = sx; + continue; + } else if (cval == '&' && utf.peek() != '&') { + // Ignore lone ampersands + continue; + } + const AtlasChar *ch = atlasfont.getChar(cval); + if (!ch) + ch = atlasfont.getChar('?'); + if (ch) { + const AtlasChar &c = *ch; + float cx1, cy1, cx2, cy2; + if (align & ROTATE_90DEG_LEFT) { + cy1 = y - c.ox * fontscalex; + cx1 = x + c.oy * fontscaley; + cy2 = y - (c.ox + c.pw) * fontscalex; + cx2 = x + (c.oy + c.ph) * fontscaley; + } else { + cx1 = x + c.ox * fontscalex; + cy1 = y + c.oy * fontscaley; + cx2 = x + (c.ox + c.pw) * fontscalex; + cy2 = y + (c.oy + c.ph) * fontscaley; + } + V(cx1, cy1, color, c.sx, c.sy); + V(cx2, cy1, color, c.ex, c.sy); + V(cx2, cy2, color, c.ex, c.ey); + V(cx1, cy1, color, c.sx, c.sy); + V(cx2, cy2, color, c.ex, c.ey); + V(cx1, cy2, color, c.sx, c.ey); + if (align & ROTATE_90DEG_LEFT) + y -= c.wx * fontscalex; + else + x += c.wx * fontscalex; + } + } +} diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h new file mode 100644 index 0000000000..f08c580cc9 --- /dev/null +++ b/ext/native/gfx_es2/draw_buffer.h @@ -0,0 +1,170 @@ +#pragma once + +// "Immediate mode"-lookalike buffered drawing. Very fast way to draw 2D. + +#include "base/basictypes.h" +#include "base/color.h" +#include "gfx/gl_lost_manager.h" +#include "gfx/texture_atlas.h" +#include "math/geom2d.h" +#include "math/lin/matrix4x4.h" +#include "thin3d/thin3d.h" + +#undef DrawText + +struct Atlas; + +enum { + ALIGN_LEFT = 0, + ALIGN_RIGHT = 16, + ALIGN_TOP = 0, + ALIGN_BOTTOM = 1, + ALIGN_HCENTER = 4, + ALIGN_VCENTER = 8, + ALIGN_VBASELINE = 32, // text only, possibly not yet working + + ALIGN_CENTER = ALIGN_HCENTER | ALIGN_VCENTER, + ALIGN_TOPLEFT = ALIGN_TOP | ALIGN_LEFT, + ALIGN_TOPRIGHT = ALIGN_TOP | ALIGN_RIGHT, + ALIGN_BOTTOMLEFT = ALIGN_BOTTOM | ALIGN_LEFT, + ALIGN_BOTTOMRIGHT = ALIGN_BOTTOM | ALIGN_RIGHT, + + // Only for text drawing + ROTATE_90DEG_LEFT = 256, + ROTATE_90DEG_RIGHT = 512, + ROTATE_180DEG = 1024, + + // For "uncachable" text like debug log. + // Avoids using system font drawing as it's too slow. + // Not actually used here but is reserved for whatever system wraps DrawBuffer. + FLAG_DYNAMIC_ASCII = 2048, + FLAG_NO_PREFIX = 4096 // means to not process ampersands +}; + +class Thin3DShaderSet; + +enum DrawBufferPrimitiveMode { + DBMODE_NORMAL = 0, + DBMODE_LINES = 1 +}; + +struct GradientStop { + float t; + uint32_t color; +}; + +class TextDrawer; + +class DrawBuffer { +public: + DrawBuffer(); + ~DrawBuffer(); + + void Begin(Thin3DShaderSet *shaders, DrawBufferPrimitiveMode mode = DBMODE_NORMAL); + void End(); + + // TODO: Enforce these. Now Init is autocalled and shutdown not called. + void Init(Thin3DContext *t3d); + void Shutdown(); + + int Count() const { return count_; } + + void Flush(bool set_blend_state = true); + + void Rect(float x, float y, float w, float h, uint32_t color, int align = ALIGN_TOPLEFT); + void hLine(float x1, float y, float x2, uint32_t color); + void vLine(float x, float y1, float y2, uint32_t color); + void vLineAlpha50(float x, float y1, float y2, uint32_t color); + + void Line(int atlas_image, float x1, float y1, float x2, float y2, float thickness, uint32_t color); + + void RectOutline(float x, float y, float w, float h, uint32_t color, int align = ALIGN_TOPLEFT); + + void RectVGradient(float x, float y, float w, float h, uint32_t colorTop, uint32_t colorBottom); + void RectVDarkFaded(float x, float y, float w, float h, uint32_t colorTop) { + RectVGradient(x, y, w, h, colorTop, darkenColor(colorTop)); + } + + void MultiVGradient(float x, float y, float w, float h, GradientStop *stops, int numStops); + + void RectCenter(float x, float y, float w, float h, uint32_t color) { + Rect(x - w/2, y - h/2, w, h, color); + } + void Rect(float x, float y, float w, float h, float u, float v, float uw, float uh, uint32_t color); + + void V(float x, float y, float z, uint32_t color, float u, float v); + void V(float x, float y, uint32_t color, float u, float v) { + V(x, y, 0.0f, color, u, v); + } + + void Circle(float x, float y, float radius, float thickness, int segments, float startAngle, uint32_t color, float u_mul); + + // New drawing APIs + + // Must call this before you use any functions with atlas_image etc. + void SetAtlas(const Atlas *_atlas) { + atlas = _atlas; + } + const Atlas *GetAtlas() const { return atlas; } + void MeasureImage(ImageID atlas_image, float *w, float *h); + void DrawImage(ImageID atlas_image, float x, float y, float scale, Color color = COLOR(0xFFFFFF), int align = ALIGN_TOPLEFT); + void DrawImageStretch(ImageID atlas_image, float x1, float y1, float x2, float y2, Color color = COLOR(0xFFFFFF)); + void DrawImageStretch(int atlas_image, const Bounds &bounds, Color color = COLOR(0xFFFFFF)) { + DrawImageStretch(atlas_image, bounds.x, bounds.y, bounds.x2(), bounds.y2(), color); + } + void DrawImageRotated(ImageID atlas_image, float x, float y, float scale, float angle, Color color = COLOR(0xFFFFFF), bool mirror_h = false); // Always centers + void DrawTexRect(float x1, float y1, float x2, float y2, float u1, float v1, float u2, float v2, Color color); + void DrawTexRect(const Bounds &bounds, float u1, float v1, float u2, float v2, Color color) { + DrawTexRect(bounds.x, bounds.y, bounds.x2(), bounds.y2(), u1, v1, u2, v2, color); + } + // Results in 18 triangles. Kind of expensive for a button. + void DrawImage4Grid(ImageID atlas_image, float x1, float y1, float x2, float y2, Color color = COLOR(0xFFFFFF), float corner_scale = 1.0); + // This is only 6 triangles, much cheaper. + void DrawImage2GridH(ImageID atlas_image, float x1, float y1, float x2, Color color = COLOR(0xFFFFFF), float scale = 1.0); + + void MeasureText(int font, const char *text, float *w, float *h); + + // NOTE: Count is in plain chars not utf-8 chars! + void MeasureTextCount(int font, const char *text, int count, float *w, float *h); + + void DrawTextRect(int font, const char *text, float x, float y, float w, float h, Color color = 0xFFFFFFFF, int align = 0); + void DrawText(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0); + void DrawTextShadow(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0); + + void RotateSprite(ImageID atlas_image, float x, float y, float angle, float scale, Color color); + + void SetFontScale(float xs, float ys) { + fontscalex = xs; + fontscaley = ys; + } + + static void DoAlign(int flags, float *x, float *y, float *w, float *h); + + void SetDrawMatrix(const Matrix4x4 &m) { + drawMatrix_ = m; + } + +private: + struct Vertex { + float x, y, z; + float u, v; + uint32_t rgba; + }; + + Matrix4x4 drawMatrix_; + + Thin3DContext *t3d_; + Thin3DBuffer *vbuf_; + Thin3DVertexFormat *vformat_; + Thin3DShaderSet *shaderSet_; + + Vertex *verts_; + int count_; + DrawBufferPrimitiveMode mode_; + const Atlas *atlas; + + bool inited_; + float fontscalex; + float fontscaley; +}; + diff --git a/ext/native/gfx_es2/draw_text.cpp b/ext/native/gfx_es2/draw_text.cpp new file mode 100644 index 0000000000..a4ebb22bfe --- /dev/null +++ b/ext/native/gfx_es2/draw_text.cpp @@ -0,0 +1,365 @@ +#include "base/logging.h" +#include "base/stringutil.h" +#include "thin3d/thin3d.h" +#include "util/hash/hash.h" +#include "util/text/utf8.h" +#include "gfx_es2/draw_text.h" + +#ifdef USING_QT_UI +#include +#include +#include +#include +#endif + +#if defined(_WIN32) && !defined(USING_QT_UI) + +#define WIN32_LEAN_AND_MEAN +#include + +enum { + MAX_TEXT_WIDTH = 1024, + MAX_TEXT_HEIGHT = 512 +}; + +struct TextDrawerFontContext { + HFONT hFont; +}; + +struct TextDrawerContext { + HDC hDC; + HBITMAP hbmBitmap; + int *pBitmapBits; +}; + +TextDrawer::TextDrawer(Thin3DContext *thin3d) : thin3d_(thin3d), ctx_(NULL) { + fontScaleX_ = 1.0f; + fontScaleY_ = 1.0f; + + ctx_ = new TextDrawerContext(); + ctx_->hDC = CreateCompatibleDC(NULL); + + BITMAPINFO bmi; + ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) ); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = MAX_TEXT_WIDTH; + bmi.bmiHeader.biHeight = -MAX_TEXT_HEIGHT; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biBitCount = 32; + + ctx_->hbmBitmap = CreateDIBSection(ctx_->hDC, &bmi, DIB_RGB_COLORS, (VOID**)&ctx_->pBitmapBits, NULL, 0); + SetMapMode(ctx_->hDC, MM_TEXT); + + SelectObject(ctx_->hDC, ctx_->hbmBitmap); +} + +TextDrawer::~TextDrawer() { + for (auto iter = cache_.begin(); iter != cache_.end(); ++iter) { + if (iter->second->texture) + iter->second->texture->Release(); + delete iter->second; + } + cache_.clear(); + + for (auto iter = fontMap_.begin(); iter != fontMap_.end(); ++iter) { + DeleteObject(iter->second->hFont); + delete iter->second; + } + fontMap_.clear(); + + DeleteObject(ctx_->hbmBitmap); + DeleteDC(ctx_->hDC); + + delete ctx_; +} + +uint32_t TextDrawer::SetFont(const char *fontName, int size, int flags) { + std::wstring fname; + if (fontName) + fname = ConvertUTF8ToWString(fontName); + else + fname = L"Tahoma"; + + uint32_t fontHash = hash::Fletcher((const uint8_t *)fontName, strlen(fontName)); + fontHash ^= size; + fontHash ^= flags << 10; + + auto iter = fontMap_.find(fontHash); + if (iter != fontMap_.end()) { + fontHash_ = fontHash; + return fontHash; + } + + TextDrawerFontContext *font = new TextDrawerFontContext(); + + float textScale = 1.0f; + + INT nHeight = -MulDiv( size, (INT)(GetDeviceCaps(ctx_->hDC, LOGPIXELSY) * textScale), 72 ); + int dwBold = FW_LIGHT; ///FW_BOLD + font->hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0, + FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, PROOF_QUALITY, + VARIABLE_PITCH, fname.c_str()); + fontMap_[fontHash] = font; + fontHash_ = fontHash; + return fontHash; +} + +void TextDrawer::SetFont(uint32_t fontHandle) { + auto iter = fontMap_.find(fontHandle); + if (iter != fontMap_.end()) { + fontHash_ = fontHandle; + } +} + +void TextDrawer::MeasureString(const char *str, float *w, float *h) { + auto iter = fontMap_.find(fontHash_); + if (iter != fontMap_.end()) { + SelectObject(ctx_->hDC, iter->second->hFont); + } + + SIZE size; + std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(str, "\n", "\r\n")); + GetTextExtentPoint32(ctx_->hDC, wstr.c_str(), (int)wstr.size(), &size); + *w = size.cx * fontScaleX_; + *h = size.cy * fontScaleY_; +} + +void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float y, uint32_t color, int align) { + if (!strlen(str)) + return; + + uint32_t stringHash = hash::Fletcher((const uint8_t *)str, strlen(str)); + uint32_t entryHash = stringHash ^ fontHash_; + + target.Flush(true); + + TextStringEntry *entry; + + auto iter = cache_.find(entryHash); + if (iter != cache_.end()) { + entry = iter->second; + entry->lastUsedFrame = frameCount_; + } else { + // Render the string to our bitmap and save to a GL texture. + std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(str, "\n", "\r\n")); + SIZE size; + + auto iter = fontMap_.find(fontHash_); + if (iter != fontMap_.end()) { + SelectObject(ctx_->hDC, iter->second->hFont); + } + // Set text properties + SetTextColor(ctx_->hDC, 0xFFFFFF); + SetBkColor(ctx_->hDC, 0); + SetTextAlign(ctx_->hDC, TA_TOP); + + RECT textRect = {0}; + DrawTextExW(ctx_->hDC, (LPWSTR)wstr.c_str(), (int)wstr.size(), &textRect, DT_HIDEPREFIX|DT_TOP|DT_LEFT|DT_CALCRECT, 0); + size.cx = textRect.right; + size.cy = textRect.bottom; + + // GetTextExtentPoint32(ctx_->hDC, wstr.c_str(), (int)wstr.size(), &size); + RECT rc = {0}; + rc.right = size.cx + 4; + rc.bottom = size.cy + 4; + FillRect(ctx_->hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); + //ExtTextOut(ctx_->hDC, 0, 0, ETO_OPAQUE | ETO_CLIPPED, NULL, wstr.c_str(), (int)wstr.size(), NULL); + DrawTextExW(ctx_->hDC, (LPWSTR)wstr.c_str(), (int)wstr.size(), &rc, DT_HIDEPREFIX|DT_TOP|DT_LEFT, 0); + + if (size.cx > MAX_TEXT_WIDTH) + size.cx = MAX_TEXT_WIDTH; + if (size.cy > MAX_TEXT_HEIGHT) + size.cy = MAX_TEXT_HEIGHT; + + entry = new TextStringEntry(); + entry->width = size.cx; + entry->height = size.cy; + entry->bmWidth = (size.cx + 3) & ~3; + entry->bmHeight = (size.cy + 3) & ~3; + entry->lastUsedFrame = frameCount_; + entry->texture = thin3d_->CreateTexture(LINEAR2D, RGBA4444, entry->bmWidth, entry->bmHeight, 1, 1); + + // Convert the bitmap to a gl-compatible array of pixels. + uint16_t *bitmapData = new uint16_t[entry->bmWidth * entry->bmHeight]; + for (int y = 0; y < entry->bmHeight; y++) { + for (int x = 0; x < entry->bmWidth; x++) { + BYTE bAlpha = (BYTE)((ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff) >> 4); + bitmapData[entry->bmWidth * y + x] = (bAlpha) | 0xfff0; // ^ rand(); + } + } + entry->texture->SetImageData(0, 0, 0, entry->bmWidth, entry->bmHeight, 1, 0, entry->bmWidth * 2, (const uint8_t *)bitmapData); + entry->texture->Finalize(0); + delete [] bitmapData; + + cache_[entryHash] = entry; + } + + thin3d_->SetTexture(0, entry->texture); + + // Okay, the texture is bound, let's draw. + float w = entry->bmWidth * fontScaleX_; + float h = entry->bmHeight * fontScaleY_; + DrawBuffer::DoAlign(align, &x, &y, &w, &h); + target.DrawTexRect(x, y, x + w, y + h, 0.0f, 0.0f, 1.0f, 1.0f, color); + target.Flush(true); +} + +#else + +TextDrawer::TextDrawer(Thin3DContext *thin3d) : thin3d_(thin3d), ctx_(NULL) { + fontScaleX_ = 1.0f; + fontScaleY_ = 1.0f; +} + +TextDrawer::~TextDrawer() { + for (auto iter = cache_.begin(); iter != cache_.end(); ++iter) { + iter->second->texture->Release(); + delete iter->second; + } + cache_.clear(); +} + +uint32_t TextDrawer::SetFont(const char *fontName, int size, int flags) { +#ifdef USING_QT_UI + // We will only use the default font + uint32_t fontHash = 0; //hash::Fletcher((const uint8_t *)fontName, strlen(fontName)); + fontHash ^= size; + fontHash ^= flags << 10; + + auto iter = fontMap_.find(fontHash); + if (iter != fontMap_.end()) { + fontHash_ = fontHash; + return fontHash; + } + + QFont* font = new QFont(); + font->setPixelSize(size + 6); + fontMap_[fontHash] = font; + fontHash_ = fontHash; + return fontHash; +#else + ELOG("System fonts not supported on this platform"); + return 0; +#endif +} + +void TextDrawer::SetFont(uint32_t fontHandle) { + +} + +void TextDrawer::MeasureString(const char *str, float *w, float *h) { +#ifdef USING_QT_UI + QFont* font = fontMap_.find(fontHash_)->second; + QFontMetrics fm(*font); + QSize size = fm.size(0, QString::fromUtf8(str)); + *w = (float)size.width() * fontScaleX_; + *h = (float)size.height() * fontScaleY_; +#else + *w = 0; + *h = 0; +#endif +} + +void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float y, uint32_t color, int align) { + if (!strlen(str)) + return; + +#ifdef USING_QT_UI + uint32_t stringHash = hash::Fletcher((const uint8_t *)str, strlen(str)); + uint32_t entryHash = stringHash ^ fontHash_; + + target.Flush(true); + + TextStringEntry *entry; + + auto iter = cache_.find(entryHash); + if (iter != cache_.end()) { + entry = iter->second; + entry->lastUsedFrame = frameCount_; + thin3d_->SetTexture(0, entry->texture); + } else { + QFont *font = fontMap_.find(fontHash_)->second; + QFontMetrics fm(*font); + QSize size = fm.size(0, QString::fromUtf8(str)); + QImage image((size.width() + 3) & ~ 3, (size.height() + 3) & ~ 3, QImage::Format_ARGB32_Premultiplied); + if (image.isNull()) { + return; + } + image.fill(0); + + QPainter painter; + painter.begin(&image); + painter.setFont(*font); + painter.setPen(color); + painter.drawText(image.rect(), Qt::AlignTop | Qt::AlignLeft, QString::fromUtf8(str).replace("&&", "&")); + painter.end(); + + entry = new TextStringEntry(); + entry->bmWidth = entry->width = image.width(); + entry->bmHeight = entry->height = image.height(); + entry->lastUsedFrame = frameCount_; + entry->texture = thin3d_->CreateTexture(LINEAR2D, RGBA4444, entry->bmWidth, entry->bmHeight, 1, 0); + + uint16_t *bitmapData = new uint16_t[entry->bmWidth * entry->bmHeight]; + for (int x = 0; x < entry->bmWidth; x++) { + for (int y = 0; y < entry->bmHeight; y++) { + bitmapData[entry->bmWidth * y + x] = 0xfff0 | image.pixel(x, y) >> 28; + } + } + entry->texture->SetImageData(0, 0, 0, entry->bmWidth, entry->bmHeight, 1, 0, entry->bmWidth * 2, (const uint8_t *)bitmapData); + entry->texture->Finalize(0); + + delete [] bitmapData; + + cache_[entryHash] = entry; + } + float w = entry->bmWidth * fontScaleX_; + float h = entry->bmHeight * fontScaleY_; + DrawBuffer::DoAlign(align, &x, &y, &w, &h); + target.DrawTexRect(x, y, x + w, y + h, 0.0f, 0.0f, 1.0f, 1.0f, color); + target.Flush(true); +#endif +} + +#endif + +void TextDrawer::SetFontScale(float xscale, float yscale) { + fontScaleX_ = xscale; + fontScaleY_ = xscale; +} + +void TextDrawer::DrawStringRect(DrawBuffer &target, const char *str, const Bounds &bounds, uint32_t color, int align) { + float x = bounds.x; + float y = bounds.y; + if (align & ALIGN_HCENTER) { + x = bounds.centerX(); + } else if (align & ALIGN_RIGHT) { + x = bounds.x2(); + } + if (align & ALIGN_VCENTER) { + y = bounds.centerY(); + } else if (align & ALIGN_BOTTOM) { + y = bounds.y2(); + } + + DrawString(target, str, x, y, color, align); +} + +void TextDrawer::OncePerFrame() { + frameCount_++; + // Use a prime number to reduce clashing with other rhythms + if (frameCount_ % 23 == 0) { + for (auto iter = cache_.begin(); iter != cache_.end();) { + if (frameCount_ - iter->second->lastUsedFrame > 100) { + if (iter->second->texture) + iter->second->texture->Release(); + delete iter->second; + cache_.erase(iter++); + } else { + iter++; + } + } + } +} diff --git a/ext/native/gfx_es2/draw_text.h b/ext/native/gfx_es2/draw_text.h new file mode 100644 index 0000000000..58caab3a09 --- /dev/null +++ b/ext/native/gfx_es2/draw_text.h @@ -0,0 +1,74 @@ +// draw_text + +// Uses system fonts to draw text. +// Platform support will be added over time, initially just Win32. + +// Caches strings in individual textures. Might later combine them into a big one +// with dynamically allocated space but too much trouble for now. + +#pragma once + +#include + +#include "base/basictypes.h" +#include "gfx_es2/draw_buffer.h" + +class Thin3DContext; +class Thin3DTexture; + +#ifdef USING_QT_UI +#include +#endif + +struct TextStringEntry { + Thin3DTexture *texture; + int width; + int height; + int bmWidth; + int bmHeight; + int lastUsedFrame; +}; + +// Not yet functional +enum { + FONTSTYLE_BOLD = 1, + FONTSTYLE_ITALIC = 2, +}; + +// Internal struct but all details in .cpp file (pimpl to avoid pulling in excessive headers here) +struct TextDrawerContext; +struct TextDrawerFontContext; + +class TextDrawer { +public: + TextDrawer(Thin3DContext *thin3d); + ~TextDrawer(); + + uint32_t SetFont(const char *fontName, int size, int flags); + void SetFont(uint32_t fontHandle); // Shortcut once you've set the font once. + + void SetFontScale(float xscale, float yscale); + void MeasureString(const char *str, float *w, float *h); + void DrawString(DrawBuffer &target, const char *str, float x, float y, uint32_t color, int align = ALIGN_TOPLEFT); + void DrawStringRect(DrawBuffer &target, const char *str, const Bounds &bounds, uint32_t color, int align); + // Use for housekeeping like throwing out old strings. + void OncePerFrame(); + +private: + Thin3DContext *thin3d_; + + int frameCount_; + float fontScaleX_; + float fontScaleY_; + + TextDrawerContext *ctx_; +#ifdef USING_QT_UI + std::map fontMap_; +#else + std::map fontMap_; +#endif + + uint32_t fontHash_; + // The key is the CityHash of the string xor the fontHash_. + std::map cache_; +}; diff --git a/ext/native/gfx_es2/gl3stub.c b/ext/native/gfx_es2/gl3stub.c new file mode 100644 index 0000000000..83117ea231 --- /dev/null +++ b/ext/native/gfx_es2/gl3stub.c @@ -0,0 +1,356 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "../gfx/gl_common.h" + +#if defined(USING_GLES2) +#if !defined(IOS) +#include "EGL/egl.h" +#endif + +GLboolean gl3stubInit() { +#if !defined(IOS) + #define FIND_PROC(s) s = (void*)eglGetProcAddress(#s) + FIND_PROC(glReadBuffer); + FIND_PROC(glDrawRangeElements); + FIND_PROC(glTexImage3D); + FIND_PROC(glTexSubImage3D); + FIND_PROC(glCopyTexSubImage3D); + FIND_PROC(glCompressedTexImage3D); + FIND_PROC(glCompressedTexSubImage3D); + FIND_PROC(glGenQueries); + FIND_PROC(glDeleteQueries); + FIND_PROC(glIsQuery); + FIND_PROC(glBeginQuery); + FIND_PROC(glEndQuery); + FIND_PROC(glGetQueryiv); + FIND_PROC(glGetQueryObjectuiv); + FIND_PROC(glUnmapBuffer); + FIND_PROC(glGetBufferPointerv); + FIND_PROC(glDrawBuffers); + FIND_PROC(glUniformMatrix2x3fv); + FIND_PROC(glUniformMatrix3x2fv); + FIND_PROC(glUniformMatrix2x4fv); + FIND_PROC(glUniformMatrix4x2fv); + FIND_PROC(glUniformMatrix3x4fv); + FIND_PROC(glUniformMatrix4x3fv); + FIND_PROC(glBlitFramebuffer); + FIND_PROC(glRenderbufferStorageMultisample); + FIND_PROC(glFramebufferTextureLayer); + FIND_PROC(glMapBufferRange); + FIND_PROC(glFlushMappedBufferRange); + FIND_PROC(glBindVertexArray); + FIND_PROC(glDeleteVertexArrays); + FIND_PROC(glGenVertexArrays); + FIND_PROC(glIsVertexArray); + FIND_PROC(glGetIntegeri_v); + FIND_PROC(glBeginTransformFeedback); + FIND_PROC(glEndTransformFeedback); + FIND_PROC(glBindBufferRange); + FIND_PROC(glBindBufferBase); + FIND_PROC(glTransformFeedbackVaryings); + FIND_PROC(glGetTransformFeedbackVarying); + FIND_PROC(glVertexAttribIPointer); + FIND_PROC(glGetVertexAttribIiv); + FIND_PROC(glGetVertexAttribIuiv); + FIND_PROC(glVertexAttribI4i); + FIND_PROC(glVertexAttribI4ui); + FIND_PROC(glVertexAttribI4iv); + FIND_PROC(glVertexAttribI4uiv); + FIND_PROC(glGetUniformuiv); + FIND_PROC(glGetFragDataLocation); + FIND_PROC(glUniform1ui); + FIND_PROC(glUniform2ui); + FIND_PROC(glUniform3ui); + FIND_PROC(glUniform4ui); + FIND_PROC(glUniform1uiv); + FIND_PROC(glUniform2uiv); + FIND_PROC(glUniform3uiv); + FIND_PROC(glUniform4uiv); + FIND_PROC(glClearBufferiv); + FIND_PROC(glClearBufferuiv); + FIND_PROC(glClearBufferfv); + FIND_PROC(glClearBufferfi); + FIND_PROC(glGetStringi); + FIND_PROC(glCopyBufferSubData); + FIND_PROC(glGetUniformIndices); + FIND_PROC(glGetActiveUniformsiv); + FIND_PROC(glGetUniformBlockIndex); + FIND_PROC(glGetActiveUniformBlockiv); + FIND_PROC(glGetActiveUniformBlockName); + FIND_PROC(glUniformBlockBinding); + FIND_PROC(glDrawArraysInstanced); + FIND_PROC(glDrawElementsInstanced); + FIND_PROC(glFenceSync); + FIND_PROC(glIsSync); + FIND_PROC(glDeleteSync); + FIND_PROC(glClientWaitSync); + FIND_PROC(glWaitSync); + FIND_PROC(glGetInteger64v); + FIND_PROC(glGetSynciv); + FIND_PROC(glGetInteger64i_v); + FIND_PROC(glGetBufferParameteri64v); + FIND_PROC(glGenSamplers); + FIND_PROC(glDeleteSamplers); + FIND_PROC(glIsSampler); + FIND_PROC(glBindSampler); + FIND_PROC(glSamplerParameteri); + FIND_PROC(glSamplerParameteriv); + FIND_PROC(glSamplerParameterf); + FIND_PROC(glSamplerParameterfv); + FIND_PROC(glGetSamplerParameteriv); + FIND_PROC(glGetSamplerParameterfv); + FIND_PROC(glVertexAttribDivisor); + FIND_PROC(glBindTransformFeedback); + FIND_PROC(glDeleteTransformFeedbacks); + FIND_PROC(glGenTransformFeedbacks); + FIND_PROC(glIsTransformFeedback); + FIND_PROC(glPauseTransformFeedback); + FIND_PROC(glResumeTransformFeedback); + FIND_PROC(glGetProgramBinary); + FIND_PROC(glProgramBinary); + FIND_PROC(glProgramParameteri); + FIND_PROC(glInvalidateFramebuffer); + FIND_PROC(glInvalidateSubFramebuffer); + FIND_PROC(glTexStorage2D); + FIND_PROC(glTexStorage3D); + FIND_PROC(glGetInternalformativ); + #undef FIND_PROC + +#endif // IOS + if (!glReadBuffer || + !glDrawRangeElements || + !glTexImage3D || + !glTexSubImage3D || + !glCopyTexSubImage3D || + !glCompressedTexImage3D || + !glCompressedTexSubImage3D || + !glGenQueries || + !glDeleteQueries || + !glIsQuery || + !glBeginQuery || + !glEndQuery || + !glGetQueryiv || + !glGetQueryObjectuiv || + !glUnmapBuffer || + !glGetBufferPointerv || + !glDrawBuffers || + !glUniformMatrix2x3fv || + !glUniformMatrix3x2fv || + !glUniformMatrix2x4fv || + !glUniformMatrix4x2fv || + !glUniformMatrix3x4fv || + !glUniformMatrix4x3fv || + !glBlitFramebuffer || + !glRenderbufferStorageMultisample || + !glFramebufferTextureLayer || + !glMapBufferRange || + !glFlushMappedBufferRange || + !glBindVertexArray || + !glDeleteVertexArrays || + !glGenVertexArrays || + !glIsVertexArray || + !glGetIntegeri_v || + !glBeginTransformFeedback || + !glEndTransformFeedback || + !glBindBufferRange || + !glBindBufferBase || + !glTransformFeedbackVaryings || + !glGetTransformFeedbackVarying || + !glVertexAttribIPointer || + !glGetVertexAttribIiv || + !glGetVertexAttribIuiv || + !glVertexAttribI4i || + !glVertexAttribI4ui || + !glVertexAttribI4iv || + !glVertexAttribI4uiv || + !glGetUniformuiv || + !glGetFragDataLocation || + !glUniform1ui || + !glUniform2ui || + !glUniform3ui || + !glUniform4ui || + !glUniform1uiv || + !glUniform2uiv || + !glUniform3uiv || + !glUniform4uiv || + !glClearBufferiv || + !glClearBufferuiv || + !glClearBufferfv || + !glClearBufferfi || + !glGetStringi || + !glCopyBufferSubData || + !glGetUniformIndices || + !glGetActiveUniformsiv || + !glGetUniformBlockIndex || + !glGetActiveUniformBlockiv || + !glGetActiveUniformBlockName || + !glUniformBlockBinding || + !glDrawArraysInstanced || + !glDrawElementsInstanced || + !glFenceSync || + !glIsSync || + !glDeleteSync || + !glClientWaitSync || + !glWaitSync || + !glGetInteger64v || + !glGetSynciv || + !glGetInteger64i_v || + !glGetBufferParameteri64v || + !glGenSamplers || + !glDeleteSamplers || + !glIsSampler || + !glBindSampler || + !glSamplerParameteri || + !glSamplerParameteriv || + !glSamplerParameterf || + !glSamplerParameterfv || + !glGetSamplerParameteriv || + !glGetSamplerParameterfv || + !glVertexAttribDivisor || + !glBindTransformFeedback || + !glDeleteTransformFeedbacks || + !glGenTransformFeedbacks || + !glIsTransformFeedback || + !glPauseTransformFeedback || + !glResumeTransformFeedback || + !glGetProgramBinary || + !glProgramBinary || + !glProgramParameteri || + !glInvalidateFramebuffer || + !glInvalidateSubFramebuffer || + !glTexStorage2D || + !glTexStorage3D || + !glGetInternalformativ) + { + return GL_FALSE; + } + + return GL_TRUE; +} + +#if !defined(IOS) + +/* Function pointer definitions */ +GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode); +GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices); +GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids); +GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids); +GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id); +GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id); +GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target); +GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params); +GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params); +GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target); +GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params); +GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs); +GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length); +GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array); +GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays); +GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays); +GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array); +GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data); +GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode); +GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void); +GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer); +GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode); +GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name); +GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer); +GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params); +GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params); +GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v); +GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v); +GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params); +GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name); +GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0); +GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1); +GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value); +GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value); +GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value); +GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value); +GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value); +GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value); +GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value); +GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index); +GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices); +GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); +GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName); +GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); +GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); +GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); +GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount); +GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync); +GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync); +GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params); +GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values); +GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data); +GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params); +GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers); +GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers); +GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler); +GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler); +GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param); +GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param); +GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params); +GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params); +GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor); +GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id); +GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids); +GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids); +GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id); +GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void); +GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void); +GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary); +GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length); +GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value); +GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments); +GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params); + +#endif // IOS + +#endif // GLES2 + diff --git a/ext/native/gfx_es2/gl3stub.h b/ext/native/gfx_es2/gl3stub.h new file mode 100644 index 0000000000..8082484bdf --- /dev/null +++ b/ext/native/gfx_es2/gl3stub.h @@ -0,0 +1,494 @@ +#pragma once + +/* + * stub gl3.h for dynamic loading, based on: + * gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $ + * + * Changes: + * - Removed duplicate OpenGL ES 2.0 declarations + * - Converted OpenGL ES 3.0 function prototypes to function pointer + * declarations + * - Added gl3stubInit() declaration + */ + +#if defined(USING_GLES2) + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2007-2013 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. +*/ + +/* Call this function before calling any OpenGL ES 3.0 functions. It will + * return GL_TRUE if the OpenGL ES 3.0 was successfully initialized, GL_FALSE + * otherwise. */ +GLboolean gl3stubInit(); + +#if !defined(IOS) + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +/* OpenGL ES 3.0 */ + +typedef unsigned short GLhalf; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef struct __GLsync *GLsync; + +/*------------------------------------------------------------------------- + * Token definitions + *-----------------------------------------------------------------------*/ + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_3_0 1 + +/* OpenGL ES 3.0 */ + +#define GL_READ_BUFFER 0x0C02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_RED 0x1903 +#define GL_RGB8 0x8051 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#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_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#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_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#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_SRGB8_ALPHA8 0x8C43 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#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_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#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_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_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_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#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_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#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_2D_ARRAY 0x8DD7 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#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_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING +#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_TEXTURE_LAYER 0x8CD4 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#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_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_HALF_FLOAT 0x140B +#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 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_RG8 0x822B +#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 GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING GL_COPY_READ_BUFFER +#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF + +/*------------------------------------------------------------------------- + * Entrypoint definitions + *-----------------------------------------------------------------------*/ + +/* OpenGL ES 3.0 */ + +extern GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode); +extern GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices); +extern GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +extern GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +extern GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +extern GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +extern GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +extern GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids); +extern GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids); +extern GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id); +extern GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id); +extern GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target); +extern GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params); +extern GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params); +extern GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target); +extern GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params); +extern GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs); +extern GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +extern GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +extern GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +extern GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +extern GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +extern GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +extern GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +extern GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +extern GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +extern GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +extern GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length); +extern GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array); +extern GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays); +extern GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays); +extern GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array); +extern GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data); +extern GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode); +extern GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void); +extern GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +extern GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer); +extern GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode); +extern GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name); +extern GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer); +extern GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params); +extern GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params); +extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w); +extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v); +extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v); +extern GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params); +extern GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name); +extern GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0); +extern GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1); +extern GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2); +extern GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +extern GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value); +extern GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value); +extern GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value); +extern GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value); +extern GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value); +extern GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value); +extern GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value); +extern GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +extern GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index); +extern GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +extern GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices); +extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); +extern GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName); +extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); +extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); +extern GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +extern GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); +extern GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount); +extern GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags); +extern GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync); +extern GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync); +extern GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout); +extern GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout); +extern GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params); +extern GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values); +extern GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data); +extern GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params); +extern GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers); +extern GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers); +extern GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler); +extern GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler); +extern GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param); +extern GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param); +extern GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param); +extern GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param); +extern GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params); +extern GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params); +extern GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor); +extern GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id); +extern GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids); +extern GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids); +extern GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id); +extern GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void); +extern GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void); +extern GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary); +extern GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length); +extern GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value); +extern GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments); +extern GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); +extern GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +extern GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +extern GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params); + +#endif // IOS + +#ifdef __cplusplus +} +#endif + +#endif // USING_GLES2 + diff --git a/ext/native/gfx_es2/glsl_program.cpp b/ext/native/gfx_es2/glsl_program.cpp new file mode 100644 index 0000000000..38725ccdb4 --- /dev/null +++ b/ext/native/gfx_es2/glsl_program.cpp @@ -0,0 +1,294 @@ +#include + +#include +#include +#include + +#include "base/logging.h" +#include "file/vfs.h" +#include "file/zip_read.h" +#include "glsl_program.h" + +static std::set active_programs; + +bool CompileShader(const char *source, GLuint shader, const char *filename, std::string *error_message) { + glShaderSource(shader, 1, &source, NULL); + glCompileShader(shader); + GLint success; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { +#define MAX_INFO_LOG_SIZE 2048 + GLchar infoLog[MAX_INFO_LOG_SIZE]; + GLsizei len; + glGetShaderInfoLog(shader, MAX_INFO_LOG_SIZE, &len, infoLog); + infoLog[len] = '\0'; + ELOG("Error in shader compilation of %s!\n", filename); + ELOG("Info log: %s\n", infoLog); + ELOG("Shader source:\n%s\n", (const char *)source); + if (error_message) + *error_message = infoLog; + return false; + } + return true; +} + +GLSLProgram *glsl_create(const char *vshader, const char *fshader, std::string *error_message) { + GLSLProgram *program = new GLSLProgram(); + program->program_ = 0; + program->vsh_ = 0; + program->fsh_ = 0; + program->vshader_source = 0; + program->fshader_source = 0; + strcpy(program->name, vshader + strlen(vshader) - 15); + strcpy(program->vshader_filename, vshader); + strcpy(program->fshader_filename, fshader); + if (glsl_recompile(program, error_message)) { + active_programs.insert(program); + } else { + ELOG("Failed compiling GLSL program: %s %s", vshader, fshader); + delete program; + return 0; + } + register_gl_resource_holder(program); + return program; +} + +GLSLProgram *glsl_create_source(const char *vshader_src, const char *fshader_src, std::string *error_message) { + GLSLProgram *program = new GLSLProgram(); + program->program_ = 0; + program->vsh_ = 0; + program->fsh_ = 0; + program->vshader_source = vshader_src; + program->fshader_source = fshader_src; + strcpy(program->name, "[srcshader]"); + strcpy(program->vshader_filename, ""); + strcpy(program->fshader_filename, ""); + if (glsl_recompile(program, error_message)) { + active_programs.insert(program); + } else { + ELOG("Failed compiling GLSL program from source strings"); + delete program; + return 0; + } + register_gl_resource_holder(program); + return program; +} + +bool glsl_up_to_date(GLSLProgram *program) { + struct stat vs, fs; + stat(program->vshader_filename, &vs); + stat(program->fshader_filename, &fs); + if ((time_t)vs.st_mtime != program->vshader_mtime || + (time_t)fs.st_mtime != program->fshader_mtime) { + return false; + } else { + return true; + } +} + +void glsl_refresh() { + ILOG("glsl_refresh()"); + for (std::set::const_iterator iter = active_programs.begin(); + iter != active_programs.end(); ++iter) { + if (!glsl_up_to_date(*iter)) { + glsl_recompile(*iter); + } + } +} + +// Not wanting to change ReadLocalFile semantics. +// Needs to use delete [], not delete like auto_ptr, and can't use unique_ptr because of Symbian. +struct AutoCharArrayBuf { + AutoCharArrayBuf(char *buf = nullptr) : buf_(buf) { + } + ~AutoCharArrayBuf() { + delete [] buf_; + buf_ = nullptr; + } + void reset(char *buf) { + if (buf_) { + delete[] buf_; + } + buf_ = buf; + } + operator char *() { + return buf_; + } + +private: + char *buf_; +}; + +bool glsl_recompile(GLSLProgram *program, std::string *error_message) { + struct stat vs, fs; + AutoCharArrayBuf vsh_src, fsh_src; + + if (strlen(program->vshader_filename) > 0 && 0 == stat(program->vshader_filename, &vs)) { + program->vshader_mtime = vs.st_mtime; + if (!program->vshader_source) { + size_t sz; + vsh_src.reset((char *)ReadLocalFile(program->vshader_filename, &sz)); + } + } else { + program->vshader_mtime = 0; + } + + if (strlen(program->fshader_filename) > 0 && 0 == stat(program->fshader_filename, &fs)) { + program->fshader_mtime = fs.st_mtime; + if (!program->fshader_source) { + size_t sz; + fsh_src.reset((char *)ReadLocalFile(program->fshader_filename, &sz)); + } + } else { + program->fshader_mtime = 0; + } + + if (!program->vshader_source && !vsh_src) { + size_t sz; + vsh_src.reset((char *)VFSReadFile(program->vshader_filename, &sz)); + } + if (!program->vshader_source && !vsh_src) { + ELOG("File missing: %s", program->vshader_filename); + if (error_message) { + *error_message = std::string("File missing: ") + program->vshader_filename; + } + return false; + } + if (!program->fshader_source && !fsh_src) { + size_t sz; + fsh_src.reset((char *)VFSReadFile(program->fshader_filename, &sz)); + } + if (!program->fshader_source && !fsh_src) { + ELOG("File missing: %s", program->fshader_filename); + if (error_message) { + *error_message = std::string("File missing: ") + program->fshader_filename; + } + return false; + } + + GLuint vsh = glCreateShader(GL_VERTEX_SHADER); + const GLchar *vsh_str = program->vshader_source ? program->vshader_source : (const GLchar *)(vsh_src); + if (!CompileShader(vsh_str, vsh, program->vshader_filename, error_message)) { + return false; + } + + const GLchar *fsh_str = program->fshader_source ? program->fshader_source : (const GLchar *)(fsh_src); + GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER); + if (!CompileShader(fsh_str, fsh, program->fshader_filename, error_message)) { + glDeleteShader(vsh); + return false; + } + + GLuint prog = glCreateProgram(); + glAttachShader(prog, vsh); + glAttachShader(prog, fsh); + + glLinkProgram(prog); + + GLint linkStatus; + glGetProgramiv(prog, GL_LINK_STATUS, &linkStatus); + if (linkStatus == GL_FALSE) { + GLint bufLength = 0; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = new char[bufLength + 1]; // safety + glGetProgramInfoLog(prog, bufLength, NULL, buf); + ILOG("vsh: %i fsh: %i", vsh, fsh); + ELOG("Could not link shader program (linkstatus=%i):\n %s \n", linkStatus, buf); + if (error_message) { + *error_message = buf; + } + delete [] buf; + } else { + ILOG("vsh: %i fsh: %i", vsh, fsh); + ELOG("Could not link shader program (linkstatus=%i). No OpenGL error log was available.", linkStatus); + if (error_message) { + *error_message = "(no error message available)"; + } + } + glDeleteShader(vsh); + glDeleteShader(fsh); + return false; + } + + // Destroy the old program, if any. + if (program->program_) { + glDeleteProgram(program->program_); + } + + program->program_ = prog; + program->vsh_ = vsh; + program->fsh_ = fsh; + + program->sampler0 = glGetUniformLocation(program->program_, "sampler0"); + program->sampler1 = glGetUniformLocation(program->program_, "sampler1"); + + program->a_position = glGetAttribLocation(program->program_, "a_position"); + program->a_color = glGetAttribLocation(program->program_, "a_color"); + program->a_normal = glGetAttribLocation(program->program_, "a_normal"); + program->a_texcoord0 = glGetAttribLocation(program->program_, "a_texcoord0"); + program->a_texcoord1 = glGetAttribLocation(program->program_, "a_texcoord1"); + + program->u_worldviewproj = glGetUniformLocation(program->program_, "u_worldviewproj"); + program->u_world = glGetUniformLocation(program->program_, "u_world"); + program->u_viewproj = glGetUniformLocation(program->program_, "u_viewproj"); + program->u_fog = glGetUniformLocation(program->program_, "u_fog"); + program->u_sundir = glGetUniformLocation(program->program_, "u_sundir"); + program->u_camerapos = glGetUniformLocation(program->program_, "u_camerapos"); + + //ILOG("Shader compilation success: %s %s", + // program->vshader_filename, + // program->fshader_filename); + return true; +} + +void GLSLProgram::GLLost() { + // Quoth http://developer.android.com/reference/android/opengl/GLSurfaceView.Renderer.html; + // "Note that when the EGL context is lost, all OpenGL resources associated with that context will be automatically deleted. + // You do not need to call the corresponding "glDelete" methods such as glDeleteTextures to manually delete these lost resources." + // Hence, we comment out: + // glDeleteShader(this->vsh_); + // glDeleteShader(this->fsh_); + // glDeleteProgram(this->program_); + ILOG("Restoring GLSL program %s/%s", + this->vshader_filename ? this->vshader_filename : "(mem)", + this->fshader_filename ? this->fshader_filename : "(mem)"); + this->program_ = 0; + this->vsh_ = 0; + this->fsh_ = 0; + glsl_recompile(this); + // Note that uniforms are still lost, hopefully the client sets them every frame at a minimum... +} + + +int glsl_attrib_loc(const GLSLProgram *program, const char *name) { + return glGetAttribLocation(program->program_, name); +} + +int glsl_uniform_loc(const GLSLProgram *program, const char *name) { + return glGetUniformLocation(program->program_, name); +} + +void glsl_destroy(GLSLProgram *program) { + if (program) { + unregister_gl_resource_holder(program); + glDeleteShader(program->vsh_); + glDeleteShader(program->fsh_); + glDeleteProgram(program->program_); + active_programs.erase(program); + } else { + ELOG("Deleting null GLSL program!"); + } + delete program; +} + +void glsl_bind(const GLSLProgram *program) { + if (program) + glUseProgram(program->program_); + else + glUseProgram(0); +} + +void glsl_unbind() { + glUseProgram(0); +} diff --git a/ext/native/gfx_es2/glsl_program.h b/ext/native/gfx_es2/glsl_program.h new file mode 100644 index 0000000000..c6ee880d27 --- /dev/null +++ b/ext/native/gfx_es2/glsl_program.h @@ -0,0 +1,68 @@ +// Utility code for loading GLSL shaders. +// Has support for auto-reload, see glsl_refresh + +#pragma once + +#include +#include +#include + +#include "gfx/gl_lost_manager.h" +#include "gfx/gl_common.h" + +// Represent a compiled and linked vshader/fshader pair. +// A just-constructed object is valid but cannot be used as a shader program, meaning that +// yes, you can declare these as globals if you like. +struct GLSLProgram : public GfxResourceHolder { + char name[16]; + char vshader_filename[256]; + char fshader_filename[256]; + const char *vshader_source; + const char *fshader_source; + time_t vshader_mtime; + time_t fshader_mtime; + + // Locations to some common uniforms. Hardcoded for speed. + GLint sampler0; + GLint sampler1; + GLint u_worldviewproj; + GLint u_world; + GLint u_viewproj; + GLint u_fog; // rgb = color, a = density + GLint u_sundir; + GLint u_camerapos; + + GLint a_position; + GLint a_color; + GLint a_normal; + GLint a_texcoord0; + GLint a_texcoord1; + + // Private to the implementation, do not touch + GLuint vsh_; + GLuint fsh_; + GLuint program_; + + void GLLost(); +}; + +// C API, old skool. Not much point either... + +// From files (VFS) +GLSLProgram *glsl_create(const char *vshader_file, const char *fshader_file, std::string *error_message = 0); +// Directly from source code +GLSLProgram *glsl_create_source(const char *vshader_src, const char *fshader_src, std::string *error_message = 0); +void glsl_destroy(GLSLProgram *program); + +// If recompilation of the program fails, the program is untouched and error messages +// are logged and the function returns false. +bool glsl_recompile(GLSLProgram *program, std::string *error_message = 0); +void glsl_bind(const GLSLProgram *program); +void glsl_unbind(); +int glsl_attrib_loc(const GLSLProgram *program, const char *name); +int glsl_uniform_loc(const GLSLProgram *program, const char *name); + +// Expensive, try to only call this once per second or so and only when developing. +// fstat-s all the source files of all the shaders to see if they +// should be recompiled, and recompiles them if so. +void glsl_refresh(); diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp new file mode 100644 index 0000000000..bbc9c3eac2 --- /dev/null +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -0,0 +1,357 @@ +#include + +#include "base/logging.h" +#include "base/stringutil.h" +#include "gfx/gl_common.h" +#include "gfx_es2/gpu_features.h" + +#ifdef _WIN32 +#include "GL/wglew.h" +#endif + +#if defined(USING_GLES2) +#if defined(ANDROID) || defined(BLACKBERRY) +PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC eglGetSystemTimeFrequencyNV; +PFNEGLGETSYSTEMTIMENVPROC eglGetSystemTimeNV; +PFNGLDRAWTEXTURENVPROC glDrawTextureNV; +PFNGLCOPYIMAGESUBDATANVPROC glCopyImageSubDataNV; +PFNGLBLITFRAMEBUFFERNVPROC glBlitFramebufferNV; +PFNGLMAPBUFFERPROC glMapBuffer; + +PFNGLDISCARDFRAMEBUFFEREXTPROC glDiscardFramebufferEXT; +PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOES; +PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOES; +PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArraysOES; +PFNGLISVERTEXARRAYOESPROC glIsVertexArrayOES; +#endif +#ifndef IOS +#include "EGL/egl.h" +#endif +#endif + +GLExtensions gl_extensions; +std::string g_all_gl_extensions; +std::string g_all_egl_extensions; + +bool GLExtensions::VersionGEThan(int major, int minor, int sub) { + if (gl_extensions.ver[0] > major) + return true; + if (gl_extensions.ver[0] < major) + return false; + if (gl_extensions.ver[1] > minor) + return true; + if (gl_extensions.ver[1] < minor) + return false; + return gl_extensions.ver[2] >= sub; +} + +void ProcessGPUFeatures() { + gl_extensions.bugs = 0; + + ILOG("Checking for GL driver bugs... vendor=%i model='%s'", (int)gl_extensions.gpuVendor, gl_extensions.model); + // Should be table driven instead, this is a quick hack for Galaxy Y + if (System_GetProperty(SYSPROP_NAME) == "samsung:GT-S5360") { + gl_extensions.bugs |= BUG_FBO_UNUSABLE; + } + + if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) { + if (!strcmp(gl_extensions.model, "PowerVR SGX 543") || + !strcmp(gl_extensions.model, "PowerVR SGX 540") || + !strcmp(gl_extensions.model, "PowerVR SGX 530") || + !strcmp(gl_extensions.model, "PowerVR SGX 520") ) { + WLOG("GL DRIVER BUG: PVR with bad and terrible precision"); + gl_extensions.bugs |= BUG_PVR_SHADER_PRECISION_TERRIBLE | BUG_PVR_SHADER_PRECISION_BAD; + } else { + WLOG("GL DRIVER BUG: PVR with bad precision"); + gl_extensions.bugs |= BUG_PVR_SHADER_PRECISION_BAD; + } + gl_extensions.bugs |= BUG_PVR_GENMIPMAP_HEIGHT_GREATER; + } +} + +// http://stackoverflow.com/questions/16147700/opengl-es-using-tegra-specific-extensions-gl-ext-texture-array + +void CheckGLExtensions() { + // Make sure to only do this once. It's okay to call CheckGLExtensions from wherever. + static bool done = false; + if (done) + return; + done = true; + memset(&gl_extensions, 0, sizeof(gl_extensions)); + +#ifdef USING_GLES2 + gl_extensions.IsGLES = true; +#endif + + const char *renderer = (const char *)glGetString(GL_RENDERER); + const char *versionStr = (const char *)glGetString(GL_VERSION); + const char *glslVersionStr = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); + + // Check vendor string to try and guess GPU + const char *cvendor = (char *)glGetString(GL_VENDOR); + // TODO: move this stuff to gpu_features.cpp + if (cvendor) { + const std::string vendor = StripSpaces(std::string(cvendor)); + if (vendor == "NVIDIA Corporation" + || vendor == "Nouveau" + || vendor == "nouveau") { + gl_extensions.gpuVendor = GPU_VENDOR_NVIDIA; + } else if (vendor == "Advanced Micro Devices, Inc." + || vendor == "ATI Technologies Inc.") { + gl_extensions.gpuVendor = GPU_VENDOR_AMD; + } else if (vendor == "Intel" + || vendor == "Intel Inc." + || vendor == "Intel Corporation" + || vendor == "Tungsten Graphics, Inc") { // We'll assume this last one means Intel + gl_extensions.gpuVendor = GPU_VENDOR_INTEL; + } else if (vendor == "ARM") { + gl_extensions.gpuVendor = GPU_VENDOR_ARM; + } else if (vendor == "Imagination Technologies") { + gl_extensions.gpuVendor = GPU_VENDOR_POWERVR; + } else if (vendor == "Qualcomm") { + gl_extensions.gpuVendor = GPU_VENDOR_ADRENO; + } else if (vendor == "Broadcom") { + gl_extensions.gpuVendor = GPU_VENDOR_BROADCOM; + // Just for reference: Galaxy Y has renderer == "VideoCore IV HW" + } else { + gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN; + } + } else { + gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN; + } + + ILOG("GPU Vendor : %s ; renderer: %s version str: %s ; GLSL version str: %s", cvendor, renderer ? renderer : "N/A", versionStr ? versionStr : "N/A", glslVersionStr ? glslVersionStr : "N/A"); + + if (renderer) { + strncpy(gl_extensions.model, renderer, sizeof(gl_extensions.model)); + gl_extensions.model[sizeof(gl_extensions.model) - 1] = 0; + } + + if (!gl_extensions.IsGLES) { + // For desktop GL, grab the version and attempt to parse. + char buffer[64] = { 0 }; + if (versionStr) { + strncpy(buffer, versionStr, 63); + } + const char *lastNumStart = buffer; + int numVer = 0; + int len = (int)strlen(buffer); + for (int i = 0; i < len && numVer < 3; i++) { + if (buffer[i] == '.') { + buffer[i] = 0; + gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10); + i++; + lastNumStart = buffer + i; + } + } + if (numVer < 3) + gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10); + + // If the GL version >= 4.3, we know it's a true superset of OpenGL ES 3.0 and can thus enable + // all the same modern paths. + // Most of it could be enabled on lower GPUs as well, but let's start this way. + if (gl_extensions.VersionGEThan(4, 3, 0)) { + gl_extensions.GLES3 = true; + } + } else { + // Start by assuming we're at 2.0. + gl_extensions.ver[0] = 2; + +#ifdef USING_GLES2 +#ifdef GL_MAJOR_VERSION + // Before grabbing the values, reset the error. + glGetError(); + glGetIntegerv(GL_MAJOR_VERSION, &gl_extensions.ver[0]); + glGetIntegerv(GL_MINOR_VERSION, &gl_extensions.ver[1]); + // We check error here to detect if these properties were supported. + if (glGetError() != GL_NO_ERROR) { + // They weren't, reset to GLES 2.0. + gl_extensions.ver[0] = 2; + gl_extensions.ver[1] = 0; + } +#endif + + // If the above didn't give us a version, or gave us a crazy version, fallback. + if (gl_extensions.ver[0] < 3 || gl_extensions.ver[0] > 5) { + // Try to load GLES 3.0 only if "3.0" found in version + // This simple heuristic avoids issues on older devices where you can only call eglGetProcAddress a limited + // number of times. Make sure to check for 3.0 in the shader version too to avoid false positives, see #5584. + bool gl_3_0_in_string = strstr(versionStr, "3.0") && strstr(glslVersionStr, "3.0"); + bool gl_3_1_in_string = strstr(versionStr, "3.1") && strstr(glslVersionStr, "3.1"); // intentionally left out .1 + if ((gl_3_0_in_string || gl_3_1_in_string) && gl3stubInit()) { + gl_extensions.ver[0] = 3; + if (gl_3_1_in_string) { + gl_extensions.ver[1] = 1; + } + gl_extensions.GLES3 = true; + // Though, let's ban Mali from the GLES 3 path for now, see #4078 + if (strstr(renderer, "Mali") != 0) { + gl_extensions.GLES3 = false; + } + } else { + // Just to be safe. + gl_extensions.ver[0] = 2; + gl_extensions.ver[1] = 0; + } + } else { + // Otherwise, let's trust GL_MAJOR_VERSION. Note that Mali is intentionally not banned here. + if (gl_extensions.ver[0] >= 3) { + gl_extensions.GLES3 = gl3stubInit(); + } + } +#endif + + if (gl_extensions.GLES3) { + if (gl_extensions.ver[1] >= 1) { + ILOG("OpenGL ES 3.1 support detected!\n"); + } else { + ILOG("OpenGL ES 3.0 support detected!\n"); + } + } + } + + const char *extString = (const char *)glGetString(GL_EXTENSIONS); + if (extString) { + g_all_gl_extensions = extString; + } else { + g_all_gl_extensions = ""; + extString = ""; + } + +#ifdef WIN32 + const char *wglString = 0; + if (wglGetExtensionsStringEXT) + wglString = wglGetExtensionsStringEXT(); + if (wglString) { + gl_extensions.EXT_swap_control_tear = strstr(wglString, "WGL_EXT_swap_control_tear") != 0; + g_all_egl_extensions = wglString; + } else { + g_all_egl_extensions = ""; + } +#elif !defined(USING_GLES2) + // const char *glXString = glXQueryExtensionString(); + // gl_extensions.EXT_swap_control_tear = strstr(glXString, "GLX_EXT_swap_control_tear") != 0; +#endif + + // Check the desktop extension instead of the OES one. They are very similar. + // Also explicitly check those ATI devices that claims to support npot + gl_extensions.OES_texture_npot = strstr(extString, "GL_ARB_texture_non_power_of_two") != 0 + && !(((strncmp(renderer, "ATI RADEON X", 12) == 0) || (strncmp(renderer, "ATI MOBILITY RADEON X", 21) == 0))); + + gl_extensions.ARB_blend_func_extended = strstr(extString, "GL_ARB_blend_func_extended") != 0; + gl_extensions.EXT_blend_func_extended = strstr(extString, "GL_EXT_blend_func_extended") != 0; + gl_extensions.ARB_conservative_depth = strstr(extString, "GL_ARB_conservative_depth") != 0; + gl_extensions.ARB_shader_image_load_store = (strstr(extString, "GL_ARB_shader_image_load_store") != 0) || (strstr(extString, "GL_EXT_shader_image_load_store") != 0); + gl_extensions.EXT_bgra = strstr(extString, "GL_EXT_bgra") != 0; + gl_extensions.EXT_gpu_shader4 = strstr(extString, "GL_EXT_gpu_shader4") != 0; + gl_extensions.NV_framebuffer_blit = strstr(extString, "GL_NV_framebuffer_blit") != 0; + + if (gl_extensions.IsGLES) { + gl_extensions.OES_texture_npot = strstr(extString, "OES_texture_npot") != 0; + gl_extensions.OES_packed_depth_stencil = (strstr(extString, "GL_OES_packed_depth_stencil") != 0) || gl_extensions.GLES3; + gl_extensions.OES_depth24 = strstr(extString, "GL_OES_depth24") != 0; + gl_extensions.OES_depth_texture = strstr(extString, "GL_OES_depth_texture") != 0; + gl_extensions.OES_mapbuffer = strstr(extString, "GL_OES_mapbuffer") != 0; + gl_extensions.EXT_blend_minmax = strstr(extString, "GL_EXT_blend_minmax") != 0; + gl_extensions.EXT_unpack_subimage = strstr(extString, "GL_EXT_unpack_subimage") != 0; + gl_extensions.EXT_shader_framebuffer_fetch = strstr(extString, "GL_EXT_shader_framebuffer_fetch") != 0; + gl_extensions.NV_shader_framebuffer_fetch = strstr(extString, "GL_NV_shader_framebuffer_fetch") != 0; + gl_extensions.ARM_shader_framebuffer_fetch = strstr(extString, "GL_ARM_shader_framebuffer_fetch") != 0; + gl_extensions.NV_copy_image = strstr(extString, "GL_NV_copy_image") != 0; + +#if defined(ANDROID) || defined(BLACKBERRY) + // On Android, incredibly, this is not consistently non-zero! It does seem to have the same value though. + // https://twitter.com/ID_AA_Carmack/status/387383037794603008 +#ifdef _DEBUG + void *invalidAddress = (void *)eglGetProcAddress("InvalidGlCall1"); + void *invalidAddress2 = (void *)eglGetProcAddress("AnotherInvalidGlCall2"); + DLOG("Addresses returned for invalid extensions: %p %p", invalidAddress, invalidAddress2); +#endif + + if (gl_extensions.NV_copy_image) { + glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)eglGetProcAddress("glCopyImageSubDataNV"); + } + + if (gl_extensions.NV_framebuffer_blit) { + glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC)eglGetProcAddress("glBlitFramebufferNV"); + } + + gl_extensions.OES_vertex_array_object = strstr(extString, "GL_OES_vertex_array_object") != 0; + if (gl_extensions.OES_vertex_array_object) { + glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES"); + glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES"); + glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES"); + glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES"); + } + + // Hm, this should be available on iOS too. + gl_extensions.EXT_discard_framebuffer = strstr(extString, "GL_EXT_discard_framebuffer") != 0; + if (gl_extensions.EXT_discard_framebuffer) { + glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)eglGetProcAddress("glDiscardFramebufferEXT"); + } +#else + gl_extensions.OES_vertex_array_object = false; + gl_extensions.EXT_discard_framebuffer = false; +#endif + } else { + // Desktops support minmax and subimage unpack (GL_UNPACK_ROW_LENGTH etc) + gl_extensions.EXT_blend_minmax = true; + gl_extensions.EXT_unpack_subimage = true; + } + + // GLES 3 subsumes many ES2 extensions. + if (gl_extensions.GLES3) { + gl_extensions.EXT_unpack_subimage = true; + } + +#if defined(ANDROID) || defined(BLACKBERRY) + if (gl_extensions.OES_mapbuffer) { + glMapBuffer = (PFNGLMAPBUFFERPROC)eglGetProcAddress("glMapBufferOES"); + } + + // Look for EGL extensions + EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + + const char *eglString = eglQueryString(display, EGL_EXTENSIONS); + if (eglString) { + g_all_egl_extensions = eglString; + + gl_extensions.EGL_NV_system_time = strstr(eglString, "EGL_NV_system_time") != 0; + gl_extensions.EGL_NV_coverage_sample = strstr(eglString, "EGL_NV_coverage_sample") != 0; + + if (gl_extensions.EGL_NV_system_time) { + eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC)eglGetProcAddress("eglGetSystemTimeNV"); + eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)eglGetProcAddress("eglGetSystemTimeFrequencyNV"); + } + } else { + g_all_egl_extensions = ""; + } +#endif + + // This is probably a waste of time, implementations lie. + if (gl_extensions.IsGLES || strstr(extString, "GL_ARB_ES2_compatibility")) { + const GLint precisions[6] = { + GL_LOW_FLOAT, GL_MEDIUM_FLOAT, GL_HIGH_FLOAT, + GL_LOW_INT, GL_MEDIUM_INT, GL_HIGH_INT + }; + GLint shaderTypes[2] = { + GL_VERTEX_SHADER, GL_FRAGMENT_SHADER + }; + for (int st = 0; st < 2; st++) { + for (int p = 0; p < 6; p++) { + glGetShaderPrecisionFormat(shaderTypes[st], precisions[p], gl_extensions.range[st][p], &gl_extensions.precision[st][p]); + } + } + } + + gl_extensions.ARB_framebuffer_object = strstr(extString, "GL_ARB_framebuffer_object") != 0; + gl_extensions.EXT_framebuffer_object = strstr(extString, "GL_EXT_framebuffer_object") != 0; + gl_extensions.ARB_pixel_buffer_object = strstr(extString, "GL_ARB_pixel_buffer_object") != 0; + gl_extensions.NV_pixel_buffer_object = strstr(extString, "GL_NV_pixel_buffer_object") != 0; + + ProcessGPUFeatures(); + + int error = glGetError(); + if (error) + ELOG("GL error in init: %i", error); +} diff --git a/ext/native/gfx_es2/gpu_features.h b/ext/native/gfx_es2/gpu_features.h new file mode 100644 index 0000000000..3b11cddc3a --- /dev/null +++ b/ext/native/gfx_es2/gpu_features.h @@ -0,0 +1,100 @@ +// This file will not pull in the OpenGL headers but will still let you +// access information about the features of the current GPU, for auto-config +// and similar purposes. + +#pragma once + +#include "base/NativeApp.h" + +enum { + GPU_VENDOR_NVIDIA = 1, + GPU_VENDOR_AMD = 2, + GPU_VENDOR_INTEL = 3, + GPU_VENDOR_ARM = 4, // Mali + GPU_VENDOR_POWERVR = 5, + GPU_VENDOR_ADRENO = 6, + GPU_VENDOR_BROADCOM = 7, + GPU_VENDOR_UNKNOWN = 0, +}; + +enum { + BUG_FBO_UNUSABLE = 1, + BUG_PVR_SHADER_PRECISION_BAD = 2, + BUG_PVR_SHADER_PRECISION_TERRIBLE = 4, + BUG_PVR_GENMIPMAP_HEIGHT_GREATER = 8, +}; + +// Extensions to look at using: +// GL_NV_map_buffer_range (same as GL_ARB_map_buffer_range ?) + +// WARNING: This gets memset-d - so no strings please +// TODO: Rename this GLFeatures or something. +struct GLExtensions { + int ver[3]; + int gpuVendor; + char model[128]; + + bool IsGLES; + bool GLES3; // true if the full OpenGL ES 3.0 is supported + + // OES + bool OES_depth24; + bool OES_packed_depth_stencil; + bool OES_depth_texture; + bool OES_texture_npot; // If this is set, can wrap non-pow-2 textures. Set on desktop. + bool OES_mapbuffer; + bool OES_vertex_array_object; + + // ARB + bool ARB_framebuffer_object; + bool ARB_pixel_buffer_object; + bool ARB_blend_func_extended; // dual source blending + bool EXT_blend_func_extended; // dual source blending (GLES, new 2015) + bool ARB_shader_image_load_store; + bool ARB_conservative_depth; + + // EXT + bool EXT_swap_control_tear; + bool EXT_discard_framebuffer; + bool EXT_unpack_subimage; // always supported on desktop and ES3 + bool EXT_bgra; + bool EXT_shader_framebuffer_fetch; + bool EXT_gpu_shader4; + bool EXT_blend_minmax; + bool EXT_framebuffer_object; + bool PBO_EXT; + + // NV + bool NV_shader_framebuffer_fetch; + bool NV_copy_image; + bool NV_framebuffer_blit; + bool NV_pixel_buffer_object; // GL_NV_pixel_buffer_object + + // ARM + bool ARM_shader_framebuffer_fetch; + + // EGL + bool EGL_NV_system_time; + bool EGL_NV_coverage_sample; + + // Bugs + int bugs; + + // Shader precision. Only fetched on ES for now. + int range[2][6][2]; // [vs,fs][lowf,mediumf,highf,lowi,mediumi,highi][min,max] + int precision[2][6]; // [vs,fs][lowf...] + + // greater-or-equal than + bool VersionGEThan(int major, int minor, int sub = 0); +}; + +extern GLExtensions gl_extensions; + +// Call this after filling out vendor etc to lookup the bugs etc. +// Only needs to be called once. Currently called by CheckGLExtensions(). +void ProcessGPUFeatures(); + +extern std::string g_all_gl_extensions; +extern std::string g_all_egl_extensions; + +void CheckGLExtensions(); diff --git a/ext/native/gfx_es2/vertex_format.cpp b/ext/native/gfx_es2/vertex_format.cpp new file mode 100644 index 0000000000..5c0fd6232f --- /dev/null +++ b/ext/native/gfx_es2/vertex_format.cpp @@ -0,0 +1,71 @@ +#include "base/logging.h" +#include "gfx_es2/glsl_program.h" +#include "gfx_es2/vertex_format.h" + +static const GLuint formatLookup[16] = { + GL_FLOAT, + 0, //GL_HALF_FLOAT_EXT, + GL_UNSIGNED_SHORT, + GL_UNSIGNED_BYTE, + 0, //GL_UNSIGNED_INT_10_10_10_2, + 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void SetVertexFormat(const GLSLProgram *program, uint32_t vertexFormat) { + // First special case our favorites + if (vertexFormat == (POS_FLOAT | NRM_FLOAT | UV0_FLOAT)) { + const int vertexSize = 3*4 + 3*4 + 2*4; + glUniform1i(program->sampler0, 0); + glEnableVertexAttribArray(program->a_position); + glEnableVertexAttribArray(program->a_normal); + glEnableVertexAttribArray(program->a_texcoord0); + glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, vertexSize, (void *)0); + glVertexAttribPointer(program->a_normal, 3, GL_FLOAT, GL_FALSE, vertexSize, (void *)12); + glVertexAttribPointer(program->a_texcoord0, 2, GL_FLOAT, GL_FALSE, vertexSize, (void *)24); + return; + } + + // Then have generic code here. + + + int vertexSize = 0; + + FLOG("TODO: Write generic code."); + + if (vertexFormat & UV0_MASK) { + glUniform1i(program->sampler0, 0); + } + + glEnableVertexAttribArray(program->a_position); + glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, vertexSize, (void *)0); + if (vertexFormat & NRM_MASK) { + glEnableVertexAttribArray(program->a_normal); + glVertexAttribPointer(program->a_normal, 3, GL_FLOAT, GL_FALSE, vertexSize, (void *)12); + } + if (vertexFormat & UV0_MASK) { + glEnableVertexAttribArray(program->a_texcoord0); + glVertexAttribPointer(program->a_texcoord0, 2, GL_FLOAT, GL_FALSE, vertexSize, (void *)24); + } + if (vertexFormat & UV1_MASK) { + glEnableVertexAttribArray(program->a_texcoord1); + glVertexAttribPointer(program->a_texcoord1, 2, GL_FLOAT, GL_FALSE, vertexSize, (void *)24); + } + if (vertexFormat & RGBA_MASK) { + glEnableVertexAttribArray(program->a_color); + glVertexAttribPointer(program->a_color, 4, GL_FLOAT, GL_FALSE, vertexSize, (void *)28); + } +} + +// TODO: Save state so that we can get rid of this. +void UnsetVertexFormat(const GLSLProgram *program, uint32_t vertexFormat) { + glDisableVertexAttribArray(program->a_position); + if (vertexFormat & NRM_MASK) + glDisableVertexAttribArray(program->a_normal); + if (vertexFormat & UV0_MASK) + glDisableVertexAttribArray(program->a_texcoord0); + if (vertexFormat & UV1_MASK) + glDisableVertexAttribArray(program->a_texcoord1); + if (vertexFormat & RGBA_MASK) + glDisableVertexAttribArray(program->a_color); +} diff --git a/ext/native/gfx_es2/vertex_format.h b/ext/native/gfx_es2/vertex_format.h new file mode 100644 index 0000000000..edaac48145 --- /dev/null +++ b/ext/native/gfx_es2/vertex_format.h @@ -0,0 +1,51 @@ +#pragma once + +// TODO: Actually use for something :) + +#include "base/basictypes.h" + +// Vertex format flags +enum VtxFmt { + POS_FLOAT = 1, + POS_FLOAT16 = 2, + POS_UINT16 = 3, + POS_UINT8 = 4, + POS_101010 = 5, + + NRM_FLOAT = 1 << 4, + NRM_FLOAT16 = 2 << 4, + NRM_SINT16 = 3 << 4, + NRM_UINT8 = 4 << 4, + NRM_101010 = 5 << 4, + + TANGENT_FLOAT = 1 << 8, + //.... + + UV0_NONE = 1 << 12, + UV0_FLOAT = 1 << 12, + // .... + UV1_NONE = 1 << 16, + UV1_FLOAT = 1 << 16, + + RGBA_NONE = 0 << 20, + RGBA_FLOAT = 1 << 20, + RGBA_FLOAT16 = 2 << 20, + RGBA_UINT16 = 3 << 20, + RGBA_UINT8 = 4 << 20, + RGBA_101010 = 5 << 20, + + POS_MASK = 0x0000000F, + NRM_MASK = 0x000000F0, + TANGENT_MASK = 0x00000F00, + UV0_MASK = 0x0000F000, + UV1_MASK = 0x000F0000, + RGBA_MASK = 0x00F00000, + + // Can add more here, such as a generic AUX or something. Don't know what to use it for though. Hardness for cloth sim? +}; + +struct GLSLProgram; + +// When calling this, the relevant vertex buffer must be bound to GL_ARRAY_BUFFER. +void SetVertexFormat(const GLSLProgram *program, uint32_t format); +void UnsetVertexFormat(const GLSLProgram *program, uint32_t format); diff --git a/ext/native/i18n/i18n.cpp b/ext/native/i18n/i18n.cpp new file mode 100644 index 0000000000..84e7e79822 --- /dev/null +++ b/ext/native/i18n/i18n.cpp @@ -0,0 +1,138 @@ +#include "base/logging.h" +#include "i18n/i18n.h" +#include "file/ini_file.h" +#include "file/vfs.h" + +I18NRepo i18nrepo; + +I18NRepo::~I18NRepo() { + Clear(); +} + +void I18NRepo::Clear() { + for (auto iter = cats_.begin(); iter != cats_.end(); ++iter) { + delete iter->second; + } + cats_.clear(); +} + +const char *I18NCategory::T(const char *key, const char *def) { + if (!key) { + return "ERROR"; + } + // Replace the \n's with \\n's so that key values with newlines will be found correctly. + std::string modifiedKey = key; + modifiedKey = ReplaceAll(modifiedKey, "\n", "\\n"); + + auto iter = map_.find(modifiedKey); + if (iter != map_.end()) { +// ILOG("translation key found in %s: %s", name_.c_str(), key); + return iter->second.text.c_str(); + } else { + if (def) + missedKeyLog_[key] = def; + else + missedKeyLog_[key] = modifiedKey.c_str(); +// ILOG("Missed translation key in %s: %s", name_.c_str(), key); + return def ? def : key; + } +} + +void I18NCategory::SetMap(const std::map &m) { + for (auto iter = m.begin(); iter != m.end(); ++iter) { + if (map_.find(iter->first) == map_.end()) { + std::string text = ReplaceAll(iter->second, "\\n", "\n"); + map_[iter->first] = I18NEntry(text); +// ILOG("Language entry: %s -> %s", iter->first.c_str(), text.c_str()); + } + } +} + +I18NCategory *I18NRepo::GetCategory(const char *category) { + auto iter = cats_.find(category); + if (iter != cats_.end()) { + return iter->second; + } else { + I18NCategory *c = new I18NCategory(this, category); + cats_[category] = c; + return c; + } +} + +std::string I18NRepo::GetIniPath(const std::string &languageID) const { + return "lang/" + languageID + ".ini"; +} + +bool I18NRepo::IniExists(const std::string &languageID) const { + FileInfo info; + if (!VFSGetFileInfo(GetIniPath(languageID).c_str(), &info)) + return false; + if (!info.exists) + return false; + return true; +} + +bool I18NRepo::LoadIni(const std::string &languageID, const std::string &overridePath) { + IniFile ini; + std::string iniPath; + +// ILOG("Loading lang ini %s", iniPath.c_str()); + if (!overridePath.empty()) { + iniPath = overridePath + languageID + ".ini"; + } else { + iniPath = GetIniPath(languageID); + } + + if (!ini.LoadFromVFS(iniPath)) + return false; + + Clear(); + + const std::vector §ions = ini.Sections(); + + for (auto iter = sections.begin(); iter != sections.end(); ++iter) { + if (iter->name() != "") { + cats_[iter->name()] = LoadSection(&(*iter), iter->name().c_str()); + } + } + return true; +} + +I18NCategory *I18NRepo::LoadSection(const IniFile::Section *section, const char *name) { + I18NCategory *cat = new I18NCategory(this, name); + std::map sectionMap = section->ToMap(); + cat->SetMap(sectionMap); + return cat; +} + +// This is a very light touched save variant - it won't overwrite +// anything, only create new entries. +void I18NRepo::SaveIni(const std::string &languageID) { + IniFile ini; + ini.Load(GetIniPath(languageID)); + for (auto iter = cats_.begin(); iter != cats_.end(); ++iter) { + std::string categoryName = iter->first; + IniFile::Section *section = ini.GetOrCreateSection(categoryName.c_str()); + SaveSection(ini, section, iter->second); + } + ini.Save(GetIniPath(languageID)); +} + +void I18NRepo::SaveSection(IniFile &ini, IniFile::Section *section, I18NCategory *cat) { + const std::map &missed = cat->Missed(); + + for (auto iter = missed.begin(); iter != missed.end(); ++iter) { + if (!section->Exists(iter->first.c_str())) { + std::string text = ReplaceAll(iter->second, "\n", "\\n"); + section->Set(iter->first, text); + } + } + + const std::map &entries = cat->GetMap(); + for (auto iter = entries.begin(); iter != entries.end(); ++iter) { + std::string text = ReplaceAll(iter->second.text, "\n", "\\n"); + section->Set(iter->first, text); + } + + cat->ClearMissed(); +} diff --git a/ext/native/i18n/i18n.h b/ext/native/i18n/i18n.h new file mode 100644 index 0000000000..ffa09647aa --- /dev/null +++ b/ext/native/i18n/i18n.h @@ -0,0 +1,102 @@ +#pragma once + +// I18N = I....18..dots.....N = INTERNATIONALIZATION + +// Super simple I18N library. +// Just enough to be useful and usable. +// Spits out easy-to-edit utf-8 .INI files. + +// As usual, everything is UTF-8. Nothing else allowed. + +#include +#include +#include + +#include "base/stringutil.h" +#include "file/ini_file.h" + +// Reasonably thread safe. + +class I18NRepo; + +struct I18NEntry { + I18NEntry(const std::string &t) : text(t), readFlag(false) {} + I18NEntry() : readFlag(false) {} + std::string text; + bool readFlag; +}; + +struct I18NCandidate { + I18NCandidate() : key(0), defVal(0) {} + I18NCandidate(const char *k, const char *d) : key(k), defVal(d) {} + const char *key; + const char *defVal; +}; + +class I18NCategory { +public: + I18NCategory(const char *name) : name_(name) {} + const char *T(const char *key, const char *def = 0); + const char *T(const std::string &key) { + return T(key.c_str(), nullptr); + } + + const std::map &Missed() const { + return missedKeyLog_; + } + + void SetMap(const std::map &m); + const std::map &GetMap() { return map_; } + void ClearMissed() { missedKeyLog_.clear(); } + +private: + I18NCategory(I18NRepo *repo, const char *name) : name_(name) {} + + std::string name_; + + std::map map_; + std::map missedKeyLog_; + + // Noone else can create these. + friend class I18NRepo; + + DISALLOW_COPY_AND_ASSIGN(I18NCategory); +}; + +class I18NRepo { +public: + I18NRepo() {} + ~I18NRepo(); + + bool IniExists(const std::string &languageID) const; + bool LoadIni(const std::string &languageID, const std::string &overridePath = ""); // NOT the filename! + void SaveIni(const std::string &languageID); + + I18NCategory *GetCategory(const char *categoryName); + const char *T(const char *category, const char *key, const char *def = 0); + +private: + std::string GetIniPath(const std::string &languageID) const; + void Clear(); + I18NCategory *LoadSection(const IniFile::Section *section, const char *name); + void SaveSection(IniFile &ini, IniFile::Section *section, I18NCategory *cat); + + std::map cats_; + + DISALLOW_COPY_AND_ASSIGN(I18NRepo); +}; + +extern I18NRepo i18nrepo; + +// These are simply talking to the one global instance of I18NRepo. + +inline I18NCategory *GetI18NCategory(const char *categoryName) { + return i18nrepo.GetCategory(categoryName); +} + +inline const char *T(const char *category, const char *key, const char *def = 0) { + return i18nrepo.T(category, key, def); +} + + + diff --git a/ext/native/image/CMakeLists.txt b/ext/native/image/CMakeLists.txt new file mode 100644 index 0000000000..c835ef7134 --- /dev/null +++ b/ext/native/image/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SRCS + png_load.cpp + zim_load.cpp + zim_save.cpp +) + +set(SRCS ${SRCS}) + +add_library(image STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) + diff --git a/ext/native/image/png_load.cpp b/ext/native/image/png_load.cpp new file mode 100644 index 0000000000..145d084ce3 --- /dev/null +++ b/ext/native/image/png_load.cpp @@ -0,0 +1,108 @@ +#include +#include +#include + +#ifdef USING_QT_UI +#include +#else +#include "libpng17/png.h" +#endif + +#include "png_load.h" +#include "base/logging.h" + +// *image_data_ptr should be deleted with free() +// return value of 1 == success. +int pngLoad(const char *file, int *pwidth, int *pheight, unsigned char **image_data_ptr, bool flip) { +#ifdef USING_QT_UI + QImage image(file, "PNG"); + if (image.isNull()) { + ELOG("pngLoad: Error loading image %s", file); + return 0; + } + + if (flip) + image = image.mirrored(); + *pwidth = image.width(); + *pheight = image.height(); + image = image.convertToFormat(QImage::Format_ARGB32); + *image_data_ptr = (unsigned char *)malloc(image.byteCount()); + uint32_t *src = (uint32_t*) image.bits(); + uint32_t *dest = (uint32_t*) *image_data_ptr; + // Qt4 does not support RGBA + for (size_t sz = 0; sz < (size_t)image.byteCount(); sz+=4, ++src, ++dest) { + const uint32_t v = *src; + *dest = (v & 0xFF00FF00) | ((v & 0xFF) << 16) | (( v >> 16 ) & 0xFF); // ARGB -> RGBA + } +#else + if (flip) + ELOG("pngLoad: flip flag not supported, image will be loaded upside down"); + png_image png; + memset(&png, 0, sizeof(png)); + png.version = PNG_IMAGE_VERSION; + + png_image_begin_read_from_file(&png, file); + + if (PNG_IMAGE_FAILED(png)) + { + ELOG("pngLoad: %s", png.message); + return 0; + } + *pwidth = png.width; + *pheight = png.height; + png.format = PNG_FORMAT_RGBA; + + int stride = PNG_IMAGE_ROW_STRIDE(png); + *image_data_ptr = (unsigned char *)malloc(PNG_IMAGE_SIZE(png)); + png_image_finish_read(&png, NULL, *image_data_ptr, stride, NULL); +#endif + + return 1; +} + +int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, int *pheight, unsigned char **image_data_ptr, + bool flip) { +#ifdef USING_QT_UI + QImage image; + if (!image.loadFromData(input_ptr, input_len, "PNG")) { + ELOG("pngLoad: Error loading image"); + return 0; + } + if (flip) + image = image.mirrored(); + *pwidth = image.width(); + *pheight = image.height(); + image = image.convertToFormat(QImage::Format_ARGB32); + *image_data_ptr = (unsigned char *)malloc(image.byteCount()); + uint32_t *src = (uint32_t*) image.bits(); + uint32_t *dest = (uint32_t*) *image_data_ptr; + // Qt4 does not support RGBA + for (size_t sz = 0; sz < (size_t)image.byteCount(); sz+=4, ++src, ++dest) { + const uint32_t v = *src; + *dest = (v & 0xFF00FF00) | ((v & 0xFF) << 16) | (( v >> 16 ) & 0xFF); // convert it! + } +#else + if (flip) + ELOG("pngLoad: flip flag not supported, image will be loaded upside down"); + png_image png; + memset(&png, 0, sizeof(png)); + png.version = PNG_IMAGE_VERSION; + + png_image_begin_read_from_memory(&png, input_ptr, input_len); + + if (PNG_IMAGE_FAILED(png)) + { + ELOG("pngLoad: %s", png.message); + return 0; + } + *pwidth = png.width; + *pheight = png.height; + png.format = PNG_FORMAT_RGBA; + + int stride = PNG_IMAGE_ROW_STRIDE(png); + *image_data_ptr = (unsigned char *)malloc(PNG_IMAGE_SIZE(png)); + png_image_finish_read(&png, NULL, *image_data_ptr, stride, NULL); +#endif + + return 1; +} diff --git a/ext/native/image/png_load.h b/ext/native/image/png_load.h new file mode 100644 index 0000000000..bae14c210e --- /dev/null +++ b/ext/native/image/png_load.h @@ -0,0 +1,12 @@ +#ifndef _PNG_LOAD_H +#define _PNG_LOAD_H + +// *image_data_ptr should be deleted with free() +// return value of 1 == success. +int pngLoad(const char *file, int *pwidth, + int *pheight, unsigned char **image_data_ptr, bool flip); + +int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, + int *pheight, unsigned char **image_data_ptr, bool flip); + +#endif // _PNG_LOAD_H diff --git a/ext/native/image/zim_load.cpp b/ext/native/image/zim_load.cpp new file mode 100644 index 0000000000..52e4152f80 --- /dev/null +++ b/ext/native/image/zim_load.cpp @@ -0,0 +1,143 @@ +#include +#include +#include + +#include "base/logging.h" +#include "zlib.h" +#include "image/zim_load.h" +#include "file/vfs.h" + +int ezuncompress(unsigned char* pDest, long* pnDestLen, const unsigned char* pSrc, long nSrcLen) { + z_stream stream; + stream.next_in = (Bytef*)pSrc; + stream.avail_in = (uInt)nSrcLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != (uLong)nSrcLen) return Z_BUF_ERROR; + + uInt destlen = (uInt)*pnDestLen; + if ((uLong)destlen != (uLong)*pnDestLen) return Z_BUF_ERROR; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + int err = inflateInit(&stream); + if (err != Z_OK) return err; + + int nExtraChunks = 0; + do { + stream.next_out = pDest; + stream.avail_out = destlen; + err = inflate(&stream, Z_FINISH); + if (err == Z_STREAM_END ) + break; + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + err = Z_DATA_ERROR; + if (err != Z_BUF_ERROR) { + inflateEnd(&stream); + return err; + } + nExtraChunks += 1; + } while (stream.avail_out == 0); + + *pnDestLen = stream.total_out; + + err = inflateEnd(&stream); + if (err != Z_OK) return err; + + return nExtraChunks ? Z_BUF_ERROR : Z_OK; +} + +static unsigned int log2i(unsigned int val) { + unsigned int ret = -1; + while (val != 0) { + val >>= 1; ret++; + } + return ret; +} + +int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int *flags, uint8_t **image) { + if (zim[0] != 'Z' || zim[1] != 'I' || zim[2] != 'M' || zim[3] != 'G') { + ELOG("Not a ZIM file"); + return 0; + } + memcpy(width, zim + 4, 4); + memcpy(height, zim + 8, 4); + memcpy(flags, zim + 12, 4); + + int num_levels = 1; + int image_data_size[ZIM_MAX_MIP_LEVELS]; + if (*flags & ZIM_HAS_MIPS) { + num_levels = log2i(*width < *height ? *width : *height) + 1; + } + int total_data_size = 0; + for (int i = 0; i < num_levels; i++) { + if (i > 0) { + width[i] = width[i-1] / 2; + height[i] = height[i-1] / 2; + } + switch (*flags & ZIM_FORMAT_MASK) { + case ZIM_RGBA8888: + image_data_size[i] = width[i] * height[i] * 4; + break; + case ZIM_RGBA4444: + case ZIM_RGB565: + image_data_size[i] = width[i] * height[i] * 2; + break; + case ZIM_ETC1: + { + int data_width = width[i]; + int data_height = height[i]; + if (data_width < 4) data_width = 4; + if (data_height < 4) data_height = 4; + image_data_size[i] = data_width * data_height / 2; + break; + } + default: + ELOG("Invalid ZIM format %i", *flags & ZIM_FORMAT_MASK); + return 0; + } + total_data_size += image_data_size[i]; + } + + if (total_data_size == 0) + { + ELOG("Invalid ZIM data size 0"); + return 0; + } + + image[0] = (uint8_t *)malloc(total_data_size); + for (int i = 1; i < num_levels; i++) { + image[i] = image[i-1] + image_data_size[i-1]; + } + + if (*flags & ZIM_ZLIB_COMPRESSED) { + long outlen = (long)total_data_size; + if (Z_OK != ezuncompress(*image, &outlen, (unsigned char *)(zim + 16), (long)datasize - 16)) { + free(*image); + *image = 0; + return 0; + } + if (outlen != total_data_size) { + ELOG("Wrong size data in ZIM: %i vs %i", (int)outlen, (int)total_data_size); + } + } else { + memcpy(*image, zim + 16, datasize - 16); + if (datasize - 16 != (size_t)total_data_size) { + ELOG("Wrong size data in ZIM: %i vs %i", (int)(datasize-16), (int)total_data_size); + } + } + return num_levels; +} + +int LoadZIM(const char *filename, int *width, int *height, int *format, uint8_t **image) { + size_t size; + uint8_t *buffer = VFSReadFile(filename, &size); + if (!buffer) { + return 0; + } + int retval = LoadZIMPtr(buffer, (int)size, width, height, format, image); + if (!retval) { + ELOG("Not a valid ZIM file: %s", filename); + } + delete [] buffer; + return retval; +} diff --git a/ext/native/image/zim_load.h b/ext/native/image/zim_load.h new file mode 100644 index 0000000000..65bc1f5490 --- /dev/null +++ b/ext/native/image/zim_load.h @@ -0,0 +1,51 @@ +#pragma once + +#include "base/basictypes.h" + +// LoadZIM's responsibility: +// * Parse the ZIM format +// * Extract all mip levels so they can be uploaded to GPU +// +// * NOT convert formats to anything, except converting ETC1 to RGBA8888 when running on the PC + +// ZIM format: +// 4 byte ZIMG +// 4 byte width +// 4 byte height +// 4 byte flags +// Uncompressed or ZLibbed data. If multiple mips, zlibbed separately. + +// Defined flags: + +enum { + ZIM_RGBA8888 = 0, // Assumed format if no other format is set + ZIM_RGBA4444 = 1, // GL_UNSIGNED_SHORT_4_4_4_4 + ZIM_RGB565 = 2, // GL_UNSIGNED_SHORT_5_6_5 + ZIM_ETC1 = 3, + ZIM_RGB888 = 4, + ZIM_LUMINANCE_ALPHA = 5, + ZIM_LUMINANCE = 6, + ZIM_ALPHA = 7, + // There's space for plenty more formats. + ZIM_FORMAT_MASK = 15, + ZIM_HAS_MIPS = 16, // If set, assumes that a full mip chain is present. Mips are zlib-compressed individually and stored in sequence. Always half sized. + ZIM_GEN_MIPS = 32, // If set, the caller is advised to automatically generate mips. (maybe later, the ZIM lib will generate the mips for you). + ZIM_DITHER = 64, // If set, dithers during save if color reduction is necessary. + ZIM_CLAMP = 128, // Texture should default to clamp instead of wrap. + ZIM_ZLIB_COMPRESSED = 256, + ZIM_ETC1_LOW = 512, + ZIM_ETC1_MEDIUM = 1024, + ZIM_ETC1_HIGH = 0, // default + ZIM_ETC1_DITHER = 2048, +}; + +// ZIM will only ever support up to 12 levels (4096x4096 max). +enum { + ZIM_MAX_MIP_LEVELS = 12, +}; + +// Delete the returned pointer using free() +// Watch out! If the image has mipmaps, multiple values will be written +// to width, height, and image, as if they were arrays, up to 12 (max texture size is 4096 which is 2^12). +int LoadZIM(const char *filename, int *width, int *height, int *flags, uint8_t **image); +int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int *flags, uint8_t **image); \ No newline at end of file diff --git a/ext/native/image/zim_save.cpp b/ext/native/image/zim_save.cpp new file mode 100644 index 0000000000..be9bb5485d --- /dev/null +++ b/ext/native/image/zim_save.cpp @@ -0,0 +1,262 @@ +#include +#include +#include +#include "base/logging.h" +#include "ext/rg_etc1/rg_etc1.h" +#include "image/zim_save.h" +#include "zlib.h" + +static const char magic[5] = "ZIMG"; + +/*int num_levels = 1; +if (flags & ZIM_HAS_MIPS) { +num_levels = log2i(width > height ? width : height); +}*/ +static unsigned int log2i(unsigned int val) { + unsigned int ret = -1; + while (val != 0) { + val >>= 1; ret++; + } + return ret; +} + + +int ezcompress(unsigned char* pDest, long* pnDestLen, const unsigned char* pSrc, long nSrcLen) { + z_stream stream; + int err; + + int nExtraChunks; + uInt destlen; + + stream.next_in = (Bytef*)pSrc; + stream.avail_in = (uInt)nSrcLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != nSrcLen) return Z_BUF_ERROR; +#endif + destlen = (uInt)*pnDestLen; + if ((uLong)destlen != (uLong)*pnDestLen) return Z_BUF_ERROR; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); + if (err != Z_OK) return err; + nExtraChunks = 0; + do { + stream.next_out = pDest; + stream.avail_out = destlen; + err = deflate(&stream, Z_FINISH); + if (err == Z_STREAM_END ) + break; + if (err != Z_OK) { + deflateEnd(&stream); + return err; + } + nExtraChunks += 1; + } while (stream.avail_out == 0); + + *pnDestLen = stream.total_out; + + err = deflateEnd(&stream); + if (err != Z_OK) return err; + + return nExtraChunks ? Z_BUF_ERROR : Z_OK; +} + +inline int clamp16(int x) { if (x < 0) return 0; if (x > 15) return 15; return x; } +inline int clamp32(int x) { if (x < 0) return 0; if (x > 31) return 31; return x; } +inline int clamp64(int x) { if (x < 0) return 0; if (x > 63) return 63; return x; } + + +bool ispowerof2 (int x) { + if (!x || (x&(x-1))) + return false; + else + return true; +} + + + +void Convert(const uint8_t *image_data, int width, int height, int pitch, int flags, + uint8_t **data, int *data_size) { + // For 4444 and 565. Ordered dither matrix. looks really surprisingly good on cell phone screens at 4444. + int dith[16] = { + 1, 9, 3, 11, + 13, 5, 15, 7, + 4, 12, 2, 10, + 16, 8, 14, 6 + }; + if ((flags & ZIM_DITHER) == 0) { + for (int i = 0; i < 16; i++) { dith[i] = 8; } + } + switch (flags & ZIM_FORMAT_MASK) { + case ZIM_RGBA8888: + { + *data_size = width * height * 4; + *data = new uint8_t[width * height * 4]; + for (int y = 0; y < height; y++) { + memcpy((*data) + y * width * 4, image_data + y * pitch, width * 4); + } + break; + } + case ZIM_ETC1: { + rg_etc1::pack_etc1_block_init(); + rg_etc1::etc1_pack_params params; + params.m_dithering = false; //(flags & ZIM_ETC1_DITHER) != 0; + if (flags & ZIM_ETC1_LOW) { + params.m_quality = rg_etc1::cLowQuality; + } else if (flags & ZIM_ETC1_MEDIUM) { + params.m_quality = rg_etc1::cMediumQuality; + } else { + params.m_quality = rg_etc1::cHighQuality; + } + + // Check for power of 2 + if (!ispowerof2(width) || !ispowerof2(height)) { + FLOG("Image must have power of 2 dimensions, %ix%i just isn't that.", width, height); + } + // Convert RGBX to ETC1 before saving. + int blockw = width/4; + int blockh = height/4; + *data_size = blockw * blockh * 8; + *data = new uint8_t[*data_size]; +#pragma omp parallel for + for (int y = 0; y < blockh; y++) { + for (int x = 0; x < blockw; x++) { + uint32_t block[16]; + for (int iy = 0; iy < 4; iy++) { + memcpy(block + 4 * iy, image_data + ((y * 4 + iy) * (pitch/4) + x * 4) * 4, 16); + } + rg_etc1::pack_etc1_block((*data) + (blockw * y + x) * 8, block, params); + } + } + width = blockw * 4; + height = blockh * 4; + break; + } + case ZIM_RGBA4444: + { + *data_size = width * height * 2; + *data = new uint8_t[*data_size]; + uint16_t *dst = (uint16_t *)(*data); + int i = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int dithval = dith[(x&3)+((y&0x3)<<2)] - 8; + int r = clamp16((image_data[i * 4] + dithval) >> 4); + int g = clamp16((image_data[i * 4 + 1] + dithval) >> 4); + int b = clamp16((image_data[i * 4 + 2] + dithval) >> 4); + int a = clamp16((image_data[i * 4 + 3] + dithval) >> 4); // really dither alpha? + // Note: GL_UNSIGNED_SHORT_4_4_4_4, not GL_UNSIGNED_SHORT_4_4_4_4_REV + *dst++ = (r << 12) | (g << 8) | (b << 4) | (a << 0); + i++; + } + } + break; + } + case ZIM_RGB565: + { + *data_size = width * height * 2; + *data = new uint8_t[*data_size]; + uint16_t *dst = (uint16_t *)(*data); + int i = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int dithval = dith[(x&3)+((y&0x3)<<2)] - 8; + dithval = 0; + int r = clamp32((image_data[i * 4] + dithval/2) >> 3); + int g = clamp64((image_data[i * 4 + 1] + dithval/4) >> 2); + int b = clamp32((image_data[i * 4 + 2] + dithval/2) >> 3); + // Note: GL_UNSIGNED_SHORT_5_6_5, not GL_UNSIGNED_SHORT_5_6_5_REV + *dst++ = (r << 11) | (g << 5) | (b); + i++; + } + } + } + break; + + default: + ELOG("Unhandled ZIM format %i", flags & ZIM_FORMAT_MASK); + *data = 0; + *data_size = 0; + return; + } +} + +// Deletes the old buffer. +uint8_t *DownsampleBy2(const uint8_t *image, int width, int height, int pitch) { + uint8_t *out = new uint8_t[(width/2) * (height/2) * 4]; + + int degamma[256]; + int gamma[32768]; + for (int i =0; i < 256; i++) { + degamma[i] = powf((float)i / 255.0f, 1.0f/2.2f) * 8191.0f; + } + for (int i = 0; i < 32768; i++) { + gamma[i] = powf((float)i / 32764.0f, 2.2f) * 255.0f; + } + + // Really stupid mipmap downsampling - at least it does gamma though. + for (int y = 0; y < height; y+=2) { + for (int x = 0; x < width; x+=2) { + const uint8_t *tl = image + pitch * y + x*4; + const uint8_t *tr = tl + 4; + const uint8_t *bl = tl + pitch; + const uint8_t *br = bl + 4; + uint8_t *d = out + ((y/2) * ((width/2)) + x / 2) * 4; + for (int c = 0; c < 4; c++) { + d[c] = gamma[degamma[tl[c]] + degamma[tr[c]] + degamma[bl[c]] + degamma[br[c]]]; + } + } + } + return out; +} + +void SaveZIM(const char *filename, int width, int height, int pitch, int flags, const uint8_t *image_data) { + FILE *f = fopen(filename, "wb"); + fwrite(magic, 1, 4, f); + fwrite(&width, 1, 4, f); + fwrite(&height, 1, 4, f); + fwrite(&flags, 1, 4, f); + + int num_levels = 1; + if (flags & ZIM_HAS_MIPS) { + num_levels = log2i(width > height ? height : width) + 1; + } + for (int i = 0; i < num_levels; i++) { + uint8_t *data = 0; + int data_size; + Convert(image_data, width, height, pitch, flags, &data, &data_size); + if (flags & ZIM_ZLIB_COMPRESSED) { + long dest_len = data_size * 2; + uint8_t *dest = new uint8_t[dest_len]; + if (Z_OK == ezcompress(dest, &dest_len, data, data_size)) { + fwrite(dest, 1, dest_len, f); + } else { + ELOG("Zlib compression failed.\n"); + } + delete [] dest; + } else { + fwrite(data, 1, data_size, f); + } + delete [] data; + + if (i != num_levels - 1) { + uint8_t *smaller = DownsampleBy2(image_data, width, height, pitch); + if (i != 0) { + delete [] image_data; + } + image_data = smaller; + width /= 2; + height /= 2; + if ((flags & ZIM_FORMAT_MASK) == ZIM_ETC1) { + if (width < 4) width = 4; + if (height < 4) height = 4; + } + pitch = width * 4; + } + } + delete [] image_data; + fclose(f); +} diff --git a/ext/native/image/zim_save.h b/ext/native/image/zim_save.h new file mode 100644 index 0000000000..5b79b85149 --- /dev/null +++ b/ext/native/image/zim_save.h @@ -0,0 +1,11 @@ +#pragma once + +#include "base/basictypes.h" +#include "image/zim_load.h" + +// SaveZIM's responsibility: +// * Write the ZIM format +// * Generate mipmaps if requested +// * Convert images to the requested format +// Input image is always 8888 RGBA. SaveZIM takes care of downsampling and mipmap generation. +void SaveZIM(const char *filename, int width, int height, int pitch, int format, const uint8_t *image); diff --git a/ext/native/input/CMakeLists.txt b/ext/native/input/CMakeLists.txt new file mode 100644 index 0000000000..266cff4ba7 --- /dev/null +++ b/ext/native/input/CMakeLists.txt @@ -0,0 +1,13 @@ +set(SRCS + input_state.cpp + gesture_detector.cpp) + +set(SRCS ${SRCS}) + +add_library(input STATIC ${SRCS}) +target_link_libraries(input general gfx) +target_link_libraries(input general file) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/input/gesture_detector.cpp b/ext/native/input/gesture_detector.cpp new file mode 100644 index 0000000000..ef1951b474 --- /dev/null +++ b/ext/native/input/gesture_detector.cpp @@ -0,0 +1,110 @@ +// Unfinished. +// TODO: +// Zoom gesture a la http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-6-implementing-the-pinch-zoom-gesture/1847 + +#include "base/logging.h" +#include "base/timeutil.h" +#include "input/gesture_detector.h" + + +const float estimatedInertiaDamping = 0.75f; + +GestureDetector::GestureDetector() + : active_(0), + estimatedInertiaX_(0.0f), + estimatedInertiaY_(0.0f) { + memset(pointers, 0, sizeof(pointers)); +} + +TouchInput GestureDetector::Update(const TouchInput &touch, const Bounds &bounds) { + // Mouse / 1-finger-touch control. + Pointer &p = pointers[touch.id]; + if ((touch.flags & TOUCH_DOWN) && bounds.Contains(touch.x, touch.y)) { + p.down = true; + p.downTime = time_now_d(); + p.downX = touch.x; + p.downY = touch.y; + p.lastX = touch.x; + p.lastY = touch.y; + p.distanceX = 0.0f; + p.distanceY = 0.0f; + estimatedInertiaX_ = 0.0f; + estimatedInertiaY_ = 0.0f; + } else if (touch.flags & TOUCH_UP) { + p.down = false; + } else { + p.distanceX += fabsf(touch.x - p.lastX); + p.distanceY += fabsf(touch.y - p.lastY); + + estimatedInertiaX_ += touch.x - p.lastX; + estimatedInertiaY_ += touch.y - p.lastY; + estimatedInertiaX_ *= estimatedInertiaDamping; + estimatedInertiaY_ *= estimatedInertiaDamping; + + p.lastX = touch.x; + p.lastY = touch.y; + } + + if (touch.id == 0 && p.distanceY > p.distanceX) { + if (p.down) { + double timeDown = time_now_d() - p.downTime; + if (!active_ && p.distanceY * timeDown > 3) { + active_ |= GESTURE_DRAG_VERTICAL; + // Kill the drag + TouchInput inp2 = touch; + inp2.flags = TOUCH_UP | TOUCH_CANCEL; + return inp2; + } + } else { + active_ = 0; + } + } + + if (touch.id == 0 && p.distanceX > p.distanceY) { + if (p.down) { + double timeDown = time_now_d() - p.downTime; + if (!active_ && p.distanceX * timeDown > 3) { + active_ |= GESTURE_DRAG_HORIZONTAL; + // Kill the drag + TouchInput inp2 = touch; + inp2.flags = TOUCH_UP | TOUCH_CANCEL; + return inp2; + } + } else { + active_ = 0; + } + } + + return touch; +} + +void GestureDetector::UpdateFrame() { + estimatedInertiaX_ *= estimatedInertiaDamping; + estimatedInertiaY_ *= estimatedInertiaDamping; +} + +bool GestureDetector::IsGestureActive(Gesture gesture) const { + return (active_ & gesture) != 0; +} + +bool GestureDetector::GetGestureInfo(Gesture gesture, float info[4]) const { + if (!(active_ & gesture)) { + memset(info, 0, sizeof(float) * 4); + return false; + } + + memset(info, 0, sizeof(float) * 4); + + switch (gesture) { + case GESTURE_DRAG_HORIZONTAL: + info[0] = pointers[0].lastX - pointers[0].downX; + info[1] = estimatedInertiaX_; + return true; + case GESTURE_DRAG_VERTICAL: + info[0] = pointers[0].lastY - pointers[0].downY; + info[1] = estimatedInertiaY_; + return true; + default: + return false; + } +} diff --git a/ext/native/input/gesture_detector.h b/ext/native/input/gesture_detector.h new file mode 100644 index 0000000000..f1a38ef874 --- /dev/null +++ b/ext/native/input/gesture_detector.h @@ -0,0 +1,51 @@ +#include "input/input_state.h" +#include "math/geom2d.h" + +// Mainly for detecting (multi-)touch gestures but also useable for left button mouse dragging etc. +// Currently only supports simple scroll-drags with inertia. +// TODO: Two-finger zoom/rotate etc. + +enum Gesture { + GESTURE_DRAG_VERTICAL = 1, + GESTURE_DRAG_HORIZONTAL = 2, + GESTURE_TWO_FINGER_ZOOM = 4, + GESTURE_TWO_FINGER_ZOOM_ROTATE = 8, +}; + +// May track multiple gestures at the same time. You simply call GetGestureInfo +// with the gesture you are interested in. +class GestureDetector { +public: + GestureDetector(); + TouchInput Update(const TouchInput &touch, const Bounds &bounds); + void UpdateFrame(); + bool IsGestureActive(Gesture gesture) const; + bool GetGestureInfo(Gesture gesture, float info[4]) const; + +private: + // jazzhands! + enum Locals { + MAX_PTRS = 10, + }; + + struct Pointer { + bool down; + double downTime; + float lastX; + float lastY; + float downX; + float downY; + float deltaX; + float deltaY; + float distanceX; + float distanceY; + }; + + Pointer pointers[MAX_PTRS]; + + uint32_t active_; + + // For inertia estimation + float estimatedInertiaX_; + float estimatedInertiaY_; +}; diff --git a/ext/native/input/input_state.cpp b/ext/native/input/input_state.cpp new file mode 100644 index 0000000000..c6923d338e --- /dev/null +++ b/ext/native/input/input_state.cpp @@ -0,0 +1,122 @@ +#include "input/input_state.h" +#include "input/keycodes.h" +#include + +const char *GetDeviceName(int deviceId) { + switch (deviceId) { + case DEVICE_ID_ANY: return "any"; + case DEVICE_ID_DEFAULT: return "built-in"; + case DEVICE_ID_KEYBOARD: return "kbd"; + case DEVICE_ID_PAD_0: return "pad1"; + case DEVICE_ID_PAD_1: return "pad2"; + case DEVICE_ID_PAD_2: return "pad3"; + case DEVICE_ID_PAD_3: return "pad4"; + case DEVICE_ID_PAD_4: return "pad5"; + case DEVICE_ID_PAD_5: return "pad6"; + case DEVICE_ID_PAD_6: return "pad7"; + case DEVICE_ID_PAD_7: return "pad8"; + case DEVICE_ID_PAD_8: return "pad9"; + case DEVICE_ID_PAD_9: return "pad10"; + case DEVICE_ID_X360_0: return "x360"; + case DEVICE_ID_ACCELEROMETER: return "accelerometer"; + case DEVICE_ID_MOUSE: return "mouse"; + default: + return "unknown"; + } +} + +// Default pad mapping to button bits. Used for UI and stuff that doesn't use PPSSPP's key mapping system. +int MapPadButtonFixed(int keycode) { + switch (keycode) { + case NKCODE_BACK: return PAD_BUTTON_BACK; // Back + case NKCODE_MENU: return PAD_BUTTON_MENU; // Menu + + case NKCODE_Z: + case NKCODE_SPACE: + case NKCODE_BUTTON_1: + case NKCODE_BUTTON_A: // same as NKCODE_OUYA_BUTTON_O and NKCODE_BUTTON_CROSS_PS3 + return PAD_BUTTON_A; + + case NKCODE_ESCAPE: + case NKCODE_BUTTON_2: + case NKCODE_BUTTON_B: // same as NKCODE_OUYA_BUTTON_A and NKCODE_BUTTON_CIRCLE_PS3: + return PAD_BUTTON_B; + + case NKCODE_DPAD_LEFT: return PAD_BUTTON_LEFT; + case NKCODE_DPAD_RIGHT: return PAD_BUTTON_RIGHT; + case NKCODE_DPAD_UP: return PAD_BUTTON_UP; + case NKCODE_DPAD_DOWN: return PAD_BUTTON_DOWN; + + default: + return 0; + } +} + +std::vector dpadKeys; +std::vector confirmKeys; +std::vector cancelKeys; +std::vector tabLeftKeys; +std::vector tabRightKeys; + +static void AppendKeys(std::vector &keys, const std::vector &newKeys) { + for (auto iter = newKeys.begin(); iter != newKeys.end(); ++iter) { + keys.push_back(*iter); + } +} + +void SetDPadKeys(const std::vector &leftKey, const std::vector &rightKey, + const std::vector &upKey, const std::vector &downKey) { + dpadKeys.clear(); + + // Store all directions into one vector for now. In the future it might be + // useful to keep track of the different directions separately. + AppendKeys(dpadKeys, leftKey); + AppendKeys(dpadKeys, rightKey); + AppendKeys(dpadKeys, upKey); + AppendKeys(dpadKeys, downKey); +} + +void SetConfirmCancelKeys(const std::vector &confirm, const std::vector &cancel) { + confirmKeys = confirm; + cancelKeys = cancel; +} + +void SetTabLeftRightKeys(const std::vector &tabLeft, const std::vector &tabRight) { + tabLeftKeys = tabLeft; + tabRightKeys = tabRight; +} + +uint32_t ButtonTracker::Update() { + pad_buttons_ |= pad_buttons_async_set; + pad_buttons_ &= ~pad_buttons_async_clear; + return pad_buttons_; +} + +void ButtonTracker::Process(const KeyInput &input) { + int btn = MapPadButtonFixed(input.keyCode); + if (btn == 0) + return; + + // For now, use a fixed mapping. Good enough for the basics on most platforms. + if (input.flags & KEY_DOWN) { + pad_buttons_async_set |= btn; + pad_buttons_async_clear &= ~btn; + } + if (input.flags & KEY_UP) { + pad_buttons_async_set &= ~btn; + pad_buttons_async_clear |= btn; + } +} + +ButtonTracker g_buttonTracker; + +void UpdateInputState(InputState *input, bool merge) { + uint32_t btns = g_buttonTracker.Update(); + input->pad_buttons = merge ? (input->pad_buttons | btns) : btns; + input->pad_buttons_down = (input->pad_last_buttons ^ input->pad_buttons) & input->pad_buttons; + input->pad_buttons_up = (input->pad_last_buttons ^ input->pad_buttons) & input->pad_last_buttons; +} + +void EndInputState(InputState *input) { + input->pad_last_buttons = input->pad_buttons; +} diff --git a/ext/native/input/input_state.h b/ext/native/input/input_state.h new file mode 100644 index 0000000000..bf4cd7b5b5 --- /dev/null +++ b/ext/native/input/input_state.h @@ -0,0 +1,252 @@ +#pragma once + +// InputState is the simple way of getting input. All the input we have is collected +// to a canonical Xbox360-style pad fully automatically. +// +// Recommended for use in game UIs and games that don't have advanced needs. +// +// For more detailed and configurable input, implement NativeTouch, NativeKey and NativeAxis and do your +// own mapping. Might later move the mapping system from PPSSPP to native. + +#include +#include + +#include "math/lin/vec3.h" +#include "base/mutex.h" +#include "base/basictypes.h" +#include "input/keycodes.h" + +// Default device IDs + +enum { + DEVICE_ID_ANY = -1, // Represents any device ID + DEVICE_ID_DEFAULT = 0, // Old Android + DEVICE_ID_KEYBOARD = 1, // PC keyboard, android keyboards + DEVICE_ID_MOUSE = 2, // PC mouse only (not touchscreen!) + DEVICE_ID_PAD_0 = 10, // Generic joypads + DEVICE_ID_PAD_1 = 11, // these should stay as contiguous numbers + DEVICE_ID_PAD_2 = 12, + DEVICE_ID_PAD_3 = 13, + DEVICE_ID_PAD_4 = 14, + DEVICE_ID_PAD_5 = 15, + DEVICE_ID_PAD_6 = 16, + DEVICE_ID_PAD_7 = 17, + DEVICE_ID_PAD_8 = 18, + DEVICE_ID_PAD_9 = 19, + DEVICE_ID_X360_0 = 20, // XInput joypads + DEVICE_ID_ACCELEROMETER = 30, +}; + +//number of contiguous generic joypad IDs +const int MAX_NUM_PADS = 10; + +const char *GetDeviceName(int deviceId); + +enum { + PAD_BUTTON_A = 1, + PAD_BUTTON_B = 2, + PAD_BUTTON_X = 4, + PAD_BUTTON_Y = 8, + PAD_BUTTON_LBUMPER = 16, + PAD_BUTTON_RBUMPER = 32, + PAD_BUTTON_START = 64, + PAD_BUTTON_SELECT = 128, + PAD_BUTTON_UP = 256, + PAD_BUTTON_DOWN = 512, + PAD_BUTTON_LEFT = 1024, + PAD_BUTTON_RIGHT = 2048, + + PAD_BUTTON_MENU = 4096, + PAD_BUTTON_BACK = 8192, + + // For Blackberry and Qt + PAD_BUTTON_JOY_UP = 1<<14, + PAD_BUTTON_JOY_DOWN = 1<<15, + PAD_BUTTON_JOY_LEFT = 1<<16, + PAD_BUTTON_JOY_RIGHT = 1<<17, + + PAD_BUTTON_LEFT_THUMB = 1 << 18, // Click left thumb stick on X360 + PAD_BUTTON_RIGHT_THUMB = 1 << 19, // Click right thumb stick on X360 + + PAD_BUTTON_LEFT_TRIGGER = 1 << 21, // Click left thumb stick on X360 + PAD_BUTTON_RIGHT_TRIGGER = 1 << 22, // Click left thumb stick on X360 + + PAD_BUTTON_UNTHROTTLE = 1 << 20, // Click Tab to unthrottle +}; + +#define MAX_POINTERS 10 + +#ifndef MAX_KEYQUEUESIZE +#define MAX_KEYQUEUESIZE 20 +#endif + +// Represents a single bindable key +class KeyDef { +public: + KeyDef() : deviceId(0), keyCode(0) {} + KeyDef(int devId, int k) : deviceId(devId), keyCode(k) {} + int deviceId; + int keyCode; + + bool operator < (const KeyDef &other) const { + if (deviceId < other.deviceId) return true; + if (deviceId > other.deviceId) return false; + if (keyCode < other.keyCode) return true; + return false; + } + bool operator == (const KeyDef &other) const { + if (deviceId != other.deviceId && deviceId != DEVICE_ID_ANY && other.deviceId != DEVICE_ID_ANY) return false; + if (keyCode != other.keyCode) return false; + return true; + } +}; + +// Represents a single bindable axis direction +struct AxisPos { + int axis; + float position; + + bool operator < (const AxisPos &other) const { + if (axis < other.axis) return true; + if (axis > other.axis) return false; + return position < other.position; + } + bool operator == (const AxisPos &other) const { + return axis == other.axis && position == other.position; + } +}; + + +// Collection of all possible inputs, and automatically computed +// deltas where applicable. +struct InputState { + // Lock this whenever you access the data in this struct. + mutable recursive_mutex lock; + InputState() + : pad_buttons(0), + pad_last_buttons(0), + pad_buttons_down(0), + pad_buttons_up(0), + mouse_valid(false), + accelerometer_valid(false) { + memset(pointer_down, 0, sizeof(pointer_down)); + } + + // Gamepad style input. For ease of use. + int pad_buttons; // bitfield + int pad_last_buttons; + int pad_buttons_down; // buttons just pressed this frame + int pad_buttons_up; // buttons just pressed last frame + float pad_lstick_x; + float pad_lstick_y; + float pad_rstick_x; + float pad_rstick_y; + float pad_ltrigger; + float pad_rtrigger; + + // Mouse/touch style input + // There are up to 8 mice / fingers. + volatile bool mouse_valid; + + int pointer_x[MAX_POINTERS]; + int pointer_y[MAX_POINTERS]; + bool pointer_down[MAX_POINTERS]; + + // Accelerometer + bool accelerometer_valid; + Vec3 acc; + +private: + DISALLOW_COPY_AND_ASSIGN(InputState); +}; + +void UpdateInputState(InputState *input, bool merge = false); +void EndInputState(InputState *input); + +enum { + TOUCH_MOVE = 1 << 0, + TOUCH_DOWN = 1 << 1, + TOUCH_UP = 1 << 2, + TOUCH_CANCEL = 1 << 3, // Sent by scrollviews to their children when they detect a scroll + TOUCH_WHEEL = 1 << 4, // Scrollwheel event. Usually only affects Y but can potentially affect X. + TOUCH_MOUSE = 1 << 5, // Identifies that this touch event came from a mouse + TOUCH_RELEASE_ALL = 1 << 6, // Useful for app focus switches when events may be lost. + + // These are the Android getToolType() codes, shifted by 10. + TOUCH_TOOL_MASK = 7 << 10, + TOUCH_TOOL_UNKNOWN = 0 << 10, + TOUCH_TOOL_FINGER = 1 << 10, + TOUCH_TOOL_STYLUS = 2 << 10, + TOUCH_TOOL_MOUSE = 3 << 10, + TOUCH_TOOL_ERASER = 4 << 10, +}; + +// Used for asynchronous touch input. +// DOWN is always on its own. +// MOVE and UP can be combined. +struct TouchInput { + float x; + float y; + int id; // can be relied upon to be 0...MAX_POINTERS + int flags; + double timestamp; +}; + +#undef KEY_DOWN +#undef KEY_UP + +enum { + KEY_DOWN = 1 << 0, + KEY_UP = 1 << 1, + KEY_HASWHEELDELTA = 1 << 2, + KEY_IS_REPEAT = 1 << 3, + KEY_CHAR = 1 << 4, // Unicode character input. Cannot detect keyups of these so KEY_DOWN and KEY_UP are zero when this is set. +}; + +struct KeyInput { + KeyInput() {} + KeyInput(int devId, int code, int fl) : deviceId(devId), keyCode(code), flags(fl) {} + int deviceId; + int keyCode; // Android keycodes are the canonical keycodes, everyone else map to them. + int flags; +}; + +struct AxisInput { + int deviceId; + int axisId; // Android axis Ids are the canonical ones. + float value; + int flags; +}; + + +class ButtonTracker { +public: + ButtonTracker() { Reset(); } + void Reset() { + pad_buttons_ = 0; + pad_buttons_async_set = 0; + pad_buttons_async_clear = 0; + } + void Process(const KeyInput &input); + uint32_t Update(); + uint32_t GetPadButtons() const { return pad_buttons_; } + +private: + uint32_t pad_buttons_; + uint32_t pad_buttons_async_set; + uint32_t pad_buttons_async_clear; +}; + +// Platforms should call g_buttonTracker.Process(). +extern ButtonTracker g_buttonTracker; + +// Is there a nicer place for this stuff? It's here to avoid dozens of linking errors in UnitTest.. +extern std::vector dpadKeys; +extern std::vector confirmKeys; +extern std::vector cancelKeys; +extern std::vector tabLeftKeys; +extern std::vector tabRightKeys; +void SetDPadKeys(const std::vector &leftKey, const std::vector &rightKey, + const std::vector &upKey, const std::vector &downKey); +void SetConfirmCancelKeys(const std::vector &confirm, const std::vector &cancel); +void SetTabLeftRightKeys(const std::vector &tabLeft, const std::vector &tabRight); diff --git a/ext/native/input/keycodes.h b/ext/native/input/keycodes.h new file mode 100644 index 0000000000..22c9b417a7 --- /dev/null +++ b/ext/native/input/keycodes.h @@ -0,0 +1,313 @@ +#pragma once + +typedef enum _keycode_t { + NKCODE_BUTTON_CROSS = 23, // trackpad or X button(Xperia Play) is pressed + NKCODE_BUTTON_CROSS_PS3 = 96, // PS3 X button is pressed + NKCODE_BUTTON_CIRCLE = 1004, // Special custom keycode generated from 'O' button by our java code. Or 'O' button if Alt is pressed (TODO) + NKCODE_BUTTON_CIRCLE_PS3 = 97, // PS3 O button is pressed + NKCODE_BUTTON_SQUARE = 99, // Square button(Xperia Play) is pressed + NKCODE_BUTTON_TRIANGLE = 100, // 'Triangle button(Xperia Play) is pressed + NKCODE_DPAD_UP = 19, + NKCODE_DPAD_DOWN = 20, + NKCODE_DPAD_LEFT = 21, + NKCODE_DPAD_RIGHT = 22, + NKCODE_DPAD_CENTER = 23, + NKCODE_UNKNOWN = 0, + NKCODE_SOFT_LEFT = 1, + NKCODE_SOFT_RIGHT = 2, + NKCODE_HOME = 3, + NKCODE_BACK = 4, + NKCODE_CALL = 5, + NKCODE_ENDCALL = 6, + NKCODE_0 = 7, + NKCODE_1 = 8, + NKCODE_2 = 9, + NKCODE_3 = 10, + NKCODE_4 = 11, + NKCODE_5 = 12, + NKCODE_6 = 13, + NKCODE_7 = 14, + NKCODE_8 = 15, + NKCODE_9 = 16, + NKCODE_STAR = 17, + NKCODE_POUND = 18, + NKCODE_VOLUME_UP = 24, + NKCODE_VOLUME_DOWN = 25, + NKCODE_POWER = 26, + NKCODE_CAMERA = 27, + NKCODE_CLEAR = 28, + NKCODE_A = 29, + NKCODE_B = 30, + NKCODE_C = 31, + NKCODE_D = 32, + NKCODE_E = 33, + NKCODE_F = 34, + NKCODE_G = 35, + NKCODE_H = 36, + NKCODE_I = 37, + NKCODE_J = 38, + NKCODE_K = 39, + NKCODE_L = 40, + NKCODE_M = 41, + NKCODE_N = 42, + NKCODE_O = 43, + NKCODE_P = 44, + NKCODE_Q = 45, + NKCODE_R = 46, + NKCODE_S = 47, + NKCODE_T = 48, + NKCODE_U = 49, + NKCODE_V = 50, + NKCODE_W = 51, + NKCODE_X = 52, + NKCODE_Y = 53, + NKCODE_Z = 54, + NKCODE_COMMA = 55, + NKCODE_PERIOD = 56, + NKCODE_ALT_LEFT = 57, + NKCODE_ALT_RIGHT = 58, + NKCODE_SHIFT_LEFT = 59, + NKCODE_SHIFT_RIGHT = 60, + NKCODE_TAB = 61, + NKCODE_SPACE = 62, + NKCODE_SYM = 63, + NKCODE_EXPLORER = 64, + NKCODE_ENVELOPE = 65, + NKCODE_ENTER = 66, + NKCODE_DEL = 67, + NKCODE_GRAVE = 68, + NKCODE_MINUS = 69, + NKCODE_EQUALS = 70, + NKCODE_LEFT_BRACKET = 71, + NKCODE_RIGHT_BRACKET = 72, + NKCODE_BACKSLASH = 73, + NKCODE_SEMICOLON = 74, + NKCODE_APOSTROPHE = 75, + NKCODE_SLASH = 76, + NKCODE_AT = 77, + NKCODE_NUM = 78, + NKCODE_HEADSETHOOK = 79, + NKCODE_FOCUS = 80, + NKCODE_PLUS = 81, + NKCODE_MENU = 82, + NKCODE_NOTIFICATION = 83, + NKCODE_SEARCH = 84, + NKCODE_MEDIA_PLAY_PAUSE = 85, + NKCODE_MEDIA_STOP = 86, + NKCODE_MEDIA_NEXT = 87, + NKCODE_MEDIA_PREVIOUS = 88, + NKCODE_MEDIA_REWIND = 89, + NKCODE_MEDIA_FAST_FORWARD = 90, + NKCODE_MUTE = 91, + NKCODE_PAGE_UP = 92, + NKCODE_PAGE_DOWN = 93, + NKCODE_PICTSYMBOLS = 94, + NKCODE_SWITCH_CHARSET = 95, + NKCODE_BUTTON_A = 96, + NKCODE_BUTTON_B = 97, + NKCODE_BUTTON_C = 98, + NKCODE_BUTTON_X = 99, + NKCODE_BUTTON_Y = 100, + NKCODE_BUTTON_Z = 101, + NKCODE_BUTTON_L1 = 102, + NKCODE_BUTTON_R1 = 103, + NKCODE_BUTTON_L2 = 104, + NKCODE_BUTTON_R2 = 105, + NKCODE_BUTTON_THUMBL = 106, + NKCODE_BUTTON_THUMBR = 107, + NKCODE_BUTTON_START = 108, + NKCODE_BUTTON_SELECT = 109, + NKCODE_BUTTON_MODE = 110, + NKCODE_ESCAPE = 111, + NKCODE_FORWARD_DEL = 112, + NKCODE_CTRL_LEFT = 113, + NKCODE_CTRL_RIGHT = 114, + NKCODE_CAPS_LOCK = 115, + NKCODE_SCROLL_LOCK = 116, + NKCODE_META_LEFT = 117, + NKCODE_META_RIGHT = 118, + NKCODE_FUNCTION = 119, + NKCODE_SYSRQ = 120, + NKCODE_BREAK = 121, + NKCODE_MOVE_HOME = 122, + NKCODE_MOVE_END = 123, + NKCODE_INSERT = 124, + NKCODE_FORWARD = 125, + NKCODE_MEDIA_PLAY = 126, + NKCODE_MEDIA_PAUSE = 127, + NKCODE_MEDIA_CLOSE = 128, + NKCODE_MEDIA_EJECT = 129, + NKCODE_MEDIA_RECORD = 130, + NKCODE_F1 = 131, + NKCODE_F2 = 132, + NKCODE_F3 = 133, + NKCODE_F4 = 134, + NKCODE_F5 = 135, + NKCODE_F6 = 136, + NKCODE_F7 = 137, + NKCODE_F8 = 138, + NKCODE_F9 = 139, + NKCODE_F10 = 140, + NKCODE_F11 = 141, + NKCODE_F12 = 142, + NKCODE_NUM_LOCK = 143, + NKCODE_NUMPAD_0 = 144, + NKCODE_NUMPAD_1 = 145, + NKCODE_NUMPAD_2 = 146, + NKCODE_NUMPAD_3 = 147, + NKCODE_NUMPAD_4 = 148, + NKCODE_NUMPAD_5 = 149, + NKCODE_NUMPAD_6 = 150, + NKCODE_NUMPAD_7 = 151, + NKCODE_NUMPAD_8 = 152, + NKCODE_NUMPAD_9 = 153, + NKCODE_NUMPAD_DIVIDE = 154, + NKCODE_NUMPAD_MULTIPLY = 155, + NKCODE_NUMPAD_SUBTRACT = 156, + NKCODE_NUMPAD_ADD = 157, + NKCODE_NUMPAD_DOT = 158, + NKCODE_NUMPAD_COMMA = 159, + NKCODE_NUMPAD_ENTER = 160, + NKCODE_NUMPAD_EQUALS = 161, + NKCODE_NUMPAD_LEFT_PAREN = 162, + NKCODE_NUMPAD_RIGHT_PAREN = 163, + NKCODE_VOLUME_MUTE = 164, + NKCODE_INFO = 165, + NKCODE_CHANNEL_UP = 166, + NKCODE_CHANNEL_DOWN = 167, + NKCODE_ZOOM_IN = 168, + NKCODE_ZOOM_OUT = 169, + NKCODE_TV = 170, + NKCODE_WINDOW = 171, + NKCODE_GUIDE = 172, + NKCODE_DVR = 173, + NKCODE_BOOKMARK = 174, + NKCODE_CAPTIONS = 175, + NKCODE_SETTINGS = 176, + NKCODE_TV_POWER = 177, + NKCODE_TV_INPUT = 178, + NKCODE_STB_POWER = 179, + NKCODE_STB_INPUT = 180, + NKCODE_AVR_POWER = 181, + NKCODE_AVR_INPUT = 182, + NKCODE_PROG_RED = 183, + NKCODE_PROG_GREEN = 184, + NKCODE_PROG_YELLOW = 185, + NKCODE_PROG_BLUE = 186, + NKCODE_APP_SWITCH = 187, + NKCODE_BUTTON_1 = 188, + NKCODE_BUTTON_2 = 189, + NKCODE_BUTTON_3 = 190, + NKCODE_BUTTON_4 = 191, + NKCODE_BUTTON_5 = 192, + NKCODE_BUTTON_6 = 193, + NKCODE_BUTTON_7 = 194, + NKCODE_BUTTON_8 = 195, + NKCODE_BUTTON_9 = 196, + NKCODE_BUTTON_10 = 197, + NKCODE_BUTTON_11 = 198, + NKCODE_BUTTON_12 = 199, + NKCODE_BUTTON_13 = 200, + NKCODE_BUTTON_14 = 201, + NKCODE_BUTTON_15 = 202, + NKCODE_BUTTON_16 = 203, + NKCODE_LANGUAGE_SWITCH = 204, + NKCODE_MANNER_MODE = 205, + NKCODE_3D_MODE = 206, + NKCODE_CONTACTS = 207, + NKCODE_CALENDAR = 208, + NKCODE_MUSIC = 209, + NKCODE_CALCULATOR = 210, + NKCODE_ZENKAKU_HANKAKU = 211, + NKCODE_EISU = 212, + NKCODE_MUHENKAN = 213, + NKCODE_HENKAN = 214, + NKCODE_KATAKANA_HIRAGANA = 215, + NKCODE_YEN = 216, + NKCODE_RO = 217, + NKCODE_KANA = 218, + NKCODE_ASSIST = 219, + + // Ouya buttons. Just here for reference, they map straight to regular android buttons + // and will be mapped the same way. + NKCODE_OUYA_BUTTON_A = 97, + NKCODE_OUYA_BUTTON_DPAD_DOWN = 20, + NKCODE_OUYA_BUTTON_DPAD_LEFT = 21, + NKCODE_OUYA_BUTTON_DPAD_RIGHT = 22, + NKCODE_OUYA_BUTTON_DPAD_UP = 19, + NKCODE_OUYA_BUTTON_L1 = 102, + NKCODE_OUYA_BUTTON_L2 = 104, + NKCODE_OUYA_BUTTON_L3 = 106, + NKCODE_OUYA_BUTTON_MENU = 82, + NKCODE_OUYA_BUTTON_O = 96, + NKCODE_OUYA_BUTTON_R1 = 103, + NKCODE_OUYA_BUTTON_R2 = 105, + NKCODE_OUYA_BUTTON_R3 = 107, + NKCODE_OUYA_BUTTON_U = 99, + NKCODE_OUYA_BUTTON_Y = 100, + + // Extended keycodes, not available on Android + NKCODE_EXT_PIPE = 1001, // The key next to Z on euro 102-key keyboards. + + NKCODE_EXT_MOUSEBUTTON_1 = 1002, + NKCODE_EXT_MOUSEBUTTON_2 = 1003, + NKCODE_EXT_MOUSEBUTTON_3 = 1004, + NKCODE_EXT_MOUSEWHEEL_UP = 1008, + NKCODE_EXT_MOUSEWHEEL_DOWN = 1009 +} keycode_t; + +enum AndroidJoystickAxis { + // Field descriptor #15 I + JOYSTICK_AXIS_X = 0, + JOYSTICK_AXIS_Y = 1, + JOYSTICK_AXIS_PRESSURE = 2, + JOYSTICK_AXIS_SIZE = 3, + JOYSTICK_AXIS_TOUCH_MAJOR = 4, + JOYSTICK_AXIS_TOUCH_MINOR = 5, + JOYSTICK_AXIS_TOOL_MAJOR = 6, + JOYSTICK_AXIS_TOOL_MINOR = 7, + JOYSTICK_AXIS_ORIENTATION = 8, + JOYSTICK_AXIS_VSCROLL = 9, + JOYSTICK_AXIS_HSCROLL = 10, + JOYSTICK_AXIS_Z = 11, + JOYSTICK_AXIS_RX = 12, + JOYSTICK_AXIS_RY = 13, + JOYSTICK_AXIS_RZ = 14, + JOYSTICK_AXIS_HAT_X = 15, + JOYSTICK_AXIS_HAT_Y = 16, + JOYSTICK_AXIS_LTRIGGER = 17, + JOYSTICK_AXIS_RTRIGGER = 18, + JOYSTICK_AXIS_THROTTLE = 19, + JOYSTICK_AXIS_RUDDER = 20, + JOYSTICK_AXIS_WHEEL = 21, + JOYSTICK_AXIS_GAS = 22, + JOYSTICK_AXIS_BRAKE = 23, + JOYSTICK_AXIS_DISTANCE = 24, + JOYSTICK_AXIS_TILT = 25, + + // Ouya axises. Just here for reference, they map straight to regular android axises + // and will be mapped the same way. + JOYSTICK_OUYA_AXIS_L2 = 17, + JOYSTICK_OUYA_AXIS_LS_X = 0, + JOYSTICK_OUYA_AXIS_LS_Y = 1, + JOYSTICK_OUYA_AXIS_R2 = 18, + JOYSTICK_OUYA_AXIS_RS_X = 11, + JOYSTICK_OUYA_AXIS_RS_Y = 14, + + // Relative mouse axis for PC. + JOYSTICK_AXIS_MOUSE_REL_X = 26, + JOYSTICK_AXIS_MOUSE_REL_Y = 27, + + // Getting these on Ouya, no clue what they are. + JOYSTICK_AXIS_OUYA_UNKNOWN1 = 32, + JOYSTICK_AXIS_OUYA_UNKNOWN2 = 33, + JOYSTICK_AXIS_OUYA_UNKNOWN3 = 34, + JOYSTICK_AXIS_OUYA_UNKNOWN4 = 35, + + // Mobile device accelerometer/gyro + JOYSTICK_AXIS_ACCELEROMETER_X = 40, + JOYSTICK_AXIS_ACCELEROMETER_Y = 41, + JOYSTICK_AXIS_ACCELEROMETER_Z = 42, + + JOYSTICK_AXIS_MAX = 44 +}; diff --git a/ext/native/json/CMakeLists.txt b/ext/native/json/CMakeLists.txt new file mode 100644 index 0000000000..9c3ec2f57f --- /dev/null +++ b/ext/native/json/CMakeLists.txt @@ -0,0 +1,15 @@ +set(SRCS + json_writer.cpp) + +set(SRCS ${SRCS}) + +add_library(jsonwriter STATIC ${SRCS}) + + + +add_executable(json_writer_test json_writer_test.cpp) +target_link_libraries(json_writer_test jsonwriter) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/json/json_writer.cpp b/ext/native/json/json_writer.cpp new file mode 100644 index 0000000000..ec9019c50d --- /dev/null +++ b/ext/native/json/json_writer.cpp @@ -0,0 +1,115 @@ +#include "json/json_writer.h" + +JsonWriter::JsonWriter() { +} + +JsonWriter::~JsonWriter() { +} + +void JsonWriter::begin() { + str_ << "{"; + stack_.push_back(StackEntry(DICT)); +} + +void JsonWriter::end() { + pop(); + str_ << "\n"; +} + +const char *JsonWriter::indent(int n) const { + static const char * const whitespace = " "; + return whitespace + (32 - n); +} + +const char *JsonWriter::indent() const { + int amount = (int)stack_.size() + 1; + amount *= 2; // 2-space indent. + return indent(amount); +} + +const char *JsonWriter::arrayIndent() const { + int amount = (int)stack_.size() + 1; + amount *= 2; // 2-space indent. + return stack_.back().first ? indent(amount) : ""; +} + +const char *JsonWriter::comma() const { + if (stack_.back().first) { + return ""; + } else { + return ","; + } +} + +const char *JsonWriter::arrayComma() const { + if (stack_.back().first) { + return "\n"; + } else { + return ", "; + } +} + +void JsonWriter::pushDict(const char *name) { + str_ << comma() << "\n" << indent() << "\"" << name << "\": {"; + stack_.push_back(StackEntry(DICT)); +} + +void JsonWriter::pushArray(const char *name) { + str_ << comma() << "\n" << indent() << "\"" << name << "\": ["; + stack_.push_back(StackEntry(ARRAY)); +} + +void JsonWriter::writeBool(bool value) { + str_ << arrayComma() << arrayIndent() << (value ? "true" : "false"); + stack_.back().first = false; +} + +void JsonWriter::writeBool(const char *name, bool value) { + str_ << comma() << "\n" << indent() << "\"" << name << "\": " << (value ? "true" : "false"); + stack_.back().first = false; +} + +void JsonWriter::writeInt(int value) { + str_ << arrayComma() << arrayIndent() << value; + stack_.back().first = false; +} + +void JsonWriter::writeInt(const char *name, int value) { + str_ << comma() << "\n" << indent() << "\"" << name << "\": " << value; + stack_.back().first = false; +} + +void JsonWriter::writeFloat(double value) { + str_ << arrayComma() << arrayIndent() << value; + stack_.back().first = false; +} + +void JsonWriter::writeFloat(const char *name, double value) { + str_ << comma() << "\n" << indent() << "\"" << name << "\": " << value; + stack_.back().first = false; +} + +void JsonWriter::writeString(const char *value) { + str_ << arrayComma() << arrayIndent() << "\"" << value << "\""; + stack_.back().first = false; +} + +void JsonWriter::writeString(const char *name, const char *value) { + str_ << comma() << "\n" << indent() << "\"" << name << "\": \"" << value << "\""; + stack_.back().first = false; +} + +void JsonWriter::pop() { + BlockType type = stack_.back().type; + stack_.pop_back(); + switch (type) { + case ARRAY: + str_ << "\n" << indent() << "]"; + break; + case DICT: + str_ << "\n" << indent() << "}"; + break; + } + if (stack_.size() > 0) + stack_.back().first = false; +} diff --git a/ext/native/json/json_writer.h b/ext/native/json/json_writer.h new file mode 100644 index 0000000000..b58ca37f6d --- /dev/null +++ b/ext/native/json/json_writer.h @@ -0,0 +1,56 @@ +// Minimal-state JSON writer. Consumes almost no memory +// apart from the string being built-up, which could easily be replaced +// with a file stream (although I've chosen not to do that just yet). +// +// Writes nicely 2-space indented output with correct comma-placement +// in arrays and dictionaries. +// +// Does not deal with encodings in any way. +// +// Zero dependencies apart from stdlib. +// See json_writer_test.cpp for usage. + +#include +#include +#include + +class JsonWriter { +public: + JsonWriter(); + ~JsonWriter(); + void begin(); + void end(); + void pushDict(const char *name); + void pushArray(const char *name); + void pop(); + void writeBool(bool value); + void writeBool(const char *name, bool value); + void writeInt(int value); + void writeInt(const char *name, int value); + void writeFloat(double value); + void writeFloat(const char *name, double value); + void writeString(const char *value); + void writeString(const char *name, const char *value); + + std::string str() const { + return str_.str(); + } + +private: + const char *indent(int n) const; + const char *comma() const; + const char *arrayComma() const; + const char *indent() const; + const char *arrayIndent() const; + enum BlockType { + ARRAY, + DICT, + }; + struct StackEntry { + StackEntry(BlockType t) : type(t), first(true) {} + BlockType type; + bool first; + }; + std::vector stack_; + std::ostringstream str_; +}; diff --git a/ext/native/json/json_writer_test.cpp b/ext/native/json/json_writer_test.cpp new file mode 100644 index 0000000000..46875ac12b --- /dev/null +++ b/ext/native/json/json_writer_test.cpp @@ -0,0 +1,25 @@ +#include "json/json_writer.h" +#include + +int main() { + JsonWriter j; + j.begin(); + j.pushDict("settings"); + j.writeInt("volume", 50); + j.writeInt("sound", 60); + j.pop(); + j.pushDict("user"); + j.writeFloat("level", 1.5); + j.writeString("name", "hello"); + j.pop(); + j.writeInt("outer", 3); + j.pushArray("ints"); + j.writeInt(3); + j.writeInt(4); + j.writeInt(6); + j.pop(); + j.writeString("yo!", "yo"); + j.end(); + std::cout << j.str(); + return 0; +} diff --git a/ext/native/math/CMakeLists.txt b/ext/native/math/CMakeLists.txt new file mode 100644 index 0000000000..c582f3ad9c --- /dev/null +++ b/ext/native/math/CMakeLists.txt @@ -0,0 +1,16 @@ +set(SRCS + lin/matrix4x4.cpp + lin/vec3.cpp + lin/quat.cpp + lin/aabb.cpp + curves.cpp + math_util.cpp + ) + +set(SRCS ${SRCS}) + +add_library(lin STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/math/curves.cpp b/ext/native/math/curves.cpp new file mode 100644 index 0000000000..be737cab29 --- /dev/null +++ b/ext/native/math/curves.cpp @@ -0,0 +1,66 @@ + +#include + +#include "math/math_util.h" +#include "curves.h" + +float linearInOut(int t, int fadeInLength, int solidLength, int fadeOutLength) { + if (t < 0) return 0; + if (t < fadeInLength) { + return (float)t / fadeInLength; + } + t -= fadeInLength; + if (t < solidLength) { + return 1.0f; + } + t -= solidLength; + if (t < fadeOutLength) { + return 1.0f - (float)t / fadeOutLength; + } + return 0.0f; +} + +float linearIn(int t, int fadeInLength) { + if (t < 0) return 0; + if (t < fadeInLength) { + return (float)t / fadeInLength; + } + return 1.0f; +} + +float linearOut(int t, int fadeOutLength) { + return 1.0f - linearIn(t, fadeOutLength); +} + +float ease(float val) { + if (val > 1.0f) return 1.0f; + if (val < 0.0f) return 0.0f; + return ((-cosf(val * PI)) + 1.0f) * 0.5; +} + +float ease(int t, int fadeLength) +{ + if (t < 0) return 0.0f; + if (t >= fadeLength) return 1.0f; + return ease((float)t / (float)fadeLength); +} + +float sawtooth(int t, int period) { + return (t % period) * (1.0f / (period - 1)); +} + +float passWithPause(int t, int fadeInLength, int pauseLength, int fadeOutLength) +{ + if (t < fadeInLength) { + return -1.0f + (float)t / fadeInLength; + } + t -= fadeInLength; + if (t < pauseLength) { + return 0.0f; + } + t -= pauseLength; + if (t < fadeOutLength) { + return (float)t / fadeOutLength; + } + return 1.0f; +} diff --git a/ext/native/math/curves.h b/ext/native/math/curves.h new file mode 100644 index 0000000000..3ed6683c38 --- /dev/null +++ b/ext/native/math/curves.h @@ -0,0 +1,23 @@ +#pragma once + +#include "base/basictypes.h" + +// Easy curve computation for fades etc. + + +// output range: [0.0, 1.0] +float linearInOut(int t, int fadeInLength, int solidLength, int fadeOutLength); +float linearIn(int t, int fadeInLength); +float linearOut(int t, int fadeInLength); + +// smooth operator [0, 1] -> [0, 1] +float ease(float val); +float ease(int t, int fadeLength); + +// need a bouncy ease + +// waveforms [0, 1] +float sawtooth(int t, int period); + +// output range: -1.0 to 1.0 +float passWithPause(int t, int fadeInLength, int pauseLength, int fadeOutLength); diff --git a/ext/native/math/expression_parser.cpp b/ext/native/math/expression_parser.cpp new file mode 100644 index 0000000000..f4aa82ff56 --- /dev/null +++ b/ext/native/math/expression_parser.cpp @@ -0,0 +1,593 @@ +#include "expression_parser.h" +#include +#include +#include + +typedef enum { + EXOP_BRACKETL, EXOP_BRACKETR, EXOP_MEML, EXOP_MEMR, EXOP_MEMSIZE, EXOP_SIGNPLUS, EXOP_SIGNMINUS, + EXOP_BITNOT, EXOP_LOGNOT, EXOP_MUL, EXOP_DIV, EXOP_MOD, EXOP_ADD, EXOP_SUB, + EXOP_SHL, EXOP_SHR, EXOP_GREATEREQUAL, EXOP_GREATER, EXOP_LOWEREQUAL, EXOP_LOWER, + EXOP_EQUAL, EXOP_NOTEQUAL, EXOP_BITAND, EXOP_XOR, EXOP_BITOR, EXOP_LOGAND, + EXOP_LOGOR, EXOP_TERTIF, EXOP_TERTELSE, EXOP_NUMBER, EXOP_MEM, EXOP_NONE, EXOP_COUNT +} ExpressionOpcodeType; + +typedef enum { EXCOMM_CONST, EXCOMM_CONST_FLOAT, EXCOMM_REF, EXCOMM_OP } ExpressionCommand; + +static char expressionError[256]; + +typedef struct { + char Name[4]; + unsigned char Priority; + unsigned char len; + unsigned char args; + bool sign; +} ExpressionOpcode; + +const ExpressionOpcode ExpressionOpcodes[] = { + { "(", 25, 1, 0, false }, // EXOP_BRACKETL + { ")", 25, 1, 0, false }, // EXOP_BRACKETR + { "[", 4, 1, 0, false }, // EXOP_MEML + { "]", 4, 1, 0, false }, // EXOP_MEMR + { ",", 5, 1, 2, false }, // EXOP_MEMSIZE + { "+", 22, 1, 1, true }, // EXOP_SIGNPLUS + { "-", 22, 1, 1, true }, // EXOP_SIGNMINUS + { "~", 22, 1, 1, false }, // EXOP_BITNOT + { "!", 22, 1, 1, false }, // EXOP_LOGNOT + { "*", 21, 1, 2, false }, // EXOP_MUL + { "/", 21, 1, 2, false }, // EXOP_DIV + { "%", 21, 1, 2, false }, // EXOP_MOD + { "+", 20, 1, 2, false }, // EXOP_ADD + { "-", 20, 1, 2, false }, // EXOP_SUB + { "<<", 19, 2, 2, false }, // EXOP_SHL + { ">>", 19, 2, 2, false }, // EXOP_SHR + { ">=", 18, 2, 2, false }, // EXOP_GREATEREQUAL + { ">", 18, 1, 2, false }, // EXOP_GREATER + { "<=", 18, 2, 2, false }, // EXOP_LOWEREQUAL + { "<", 18, 1, 2, false }, // EXOP_LOWER + { "==", 17, 2, 2, false }, // EXOP_EQUAL + { "!=", 17, 2, 2, false }, // EXOP_NOTEQUAL + { "&", 16, 1, 2, false }, // EXOP_BITAND + { "^", 15, 1, 2, false }, // EXOP_XOR + { "|", 14, 1, 2, false }, // EXOP_BITOR + { "&&", 13, 2, 2, false }, // EXOP_LOGAND + { "||", 12, 2, 2, false }, // EXOP_LOGOR + { "?", 10, 1, 0, false }, // EXOP_TERTIF + { ":", 11, 1, 3, false }, // EXOP_TERTELSE + { "", 0, 0, 0, false }, // EXOP_NUMBER + { "[]", 0, 0, 1, false }, // EXOP_MEM + { "", 0, 0, 0, false } // EXOP_NONE +}; + +bool parseNumber(char* str, int defaultrad, int len, uint32_t& result) +{ + int val = 0; + int r = 0; + if (len == 0) len = (int) strlen(str); + + if (str[0] == '0' && tolower(str[1]) == 'x') + { + r = 16; + str+=2; + len-=2; + } else if (str[0] == '$') + { + r = 16; + str++; + len--; + } else if (str[0] == '0' && tolower(str[1]) == 'o') + { + r = 8; + str+=2; + len-=2; + } else { + if (!(str[0] >= '0' && str[0] <= '9')) return false; + + if (tolower(str[len-1]) == 'b' && defaultrad != 16) + { + r = 2; + len--; + } else if (tolower(str[len-1]) == 'o') + { + r = 8; + len--; + } else if (tolower(str[len-1]) == 'h') + { + r = 16; + len--; + } else { + r = defaultrad; + } + } + + switch (r) + { + case 2: // bin + while (len--) + { + if (*str != '0' && *str != '1') return false; + val = val << 1; + if (*str++ == '1') + { + val++; + } + } + break; + case 8: // oct + while (len--) + { + if (*str < '0' || *str > '7') return false; + val = val << 3; + val+=(*str++-'0'); + } + break; + case 10: // dec + while (len--) + { + if (*str < '0' || *str > '9') return false; + val = val * 10; + val += (*str++ - '0'); + } + break; + case 16: // hex + while (len--) + { + char c = tolower(*str++); + if ((c < '0' || c > '9') && (c < 'a' || c > 'f')) return false; + val = val << 4; + + if (c >= 'a') val += c-'a'+10; + else val += c-'0'; + } + break; + default: + return false; + } + + result = val; + return true; +} + +// Parse only a float, and return as float bits. +static bool parseFloat(const char *str, int len, uint32_t &result) +{ + bool foundDecimal = false; + for (int i = 0; i < len; ++i) + { + if (str[i] == '.') + { + if (foundDecimal) + return false; + foundDecimal = true; + continue; + } + if (str[i] < '0' || str[i] > '9') + return false; + } + + float f = (float)atof(str); + memcpy(&result, &f, sizeof(result)); + return foundDecimal; +} + +ExpressionOpcodeType getExpressionOpcode(const char* str, int& ReturnLen, ExpressionOpcodeType LastOpcode) +{ + int longestlen = 0; + ExpressionOpcodeType result = EXOP_NONE; + + for (int i = 0; i < EXOP_NUMBER; i++) + { + if (ExpressionOpcodes[i].sign == true && + (LastOpcode == EXOP_NUMBER || LastOpcode == EXOP_BRACKETR)) continue; + + int len = ExpressionOpcodes[i].len; + if (len > longestlen) + { + if (strncmp(ExpressionOpcodes[i].Name,str,len) == 0) + { + result = (ExpressionOpcodeType) i; + longestlen = len; + } + } + } + + ReturnLen = longestlen; + return result; +} + +bool isAlphaNum(char c) +{ + if ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + c == '@' || c == '_' || c == '$' || c == '.') + { + return true; + } else { + return false; + } +} + +bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest) +{ + expressionError[0] = 0; + + int infixPos = 0; + int infixLen = (int)strlen(infix); + ExpressionOpcodeType lastOpcode = EXOP_NONE; + std::vector opcodeStack; + dest.clear(); + + while (infixPos < infixLen) + { + char first = tolower(infix[infixPos]); + char subStr[256]; + int subPos = 0; + + if (first == ' ' || first == '\t') + { + infixPos++; + continue; + } + + if (first >= '0' && first <= '9') + { + while (isAlphaNum(infix[infixPos])) + { + subStr[subPos++] = infix[infixPos++]; + } + subStr[subPos] = 0; + + uint32_t value; + bool isFloat = false; + if (parseFloat(subStr,subPos,value) == true) + isFloat = true; + else if (parseNumber(subStr,16,subPos,value) == false) + { + sprintf(expressionError,"Invalid number \"%s\"",subStr); + return false; + } + + dest.push_back(ExpressionPair(isFloat?EXCOMM_CONST_FLOAT:EXCOMM_CONST,value)); + lastOpcode = EXOP_NUMBER; + } else if ((first >= 'a' && first <= 'z') || first == '@') + { + while (isAlphaNum(infix[infixPos])) + { + subStr[subPos++] = infix[infixPos++]; + } + subStr[subPos] = 0; + + uint32_t value; + if (funcs->parseReference(subStr,value) == true) + { + dest.push_back(ExpressionPair(EXCOMM_REF,value)); + lastOpcode = EXOP_NUMBER; + continue; + } + + if (funcs->parseSymbol(subStr,value) == true) + { + dest.push_back(ExpressionPair(EXCOMM_CONST,value)); + lastOpcode = EXOP_NUMBER; + continue; + } + + sprintf(expressionError,"Invalid symbol \"%s\"",subStr); + return false; + } else { + int len; + ExpressionOpcodeType type = getExpressionOpcode(&infix[infixPos],len,lastOpcode); + if (type == EXOP_NONE) + { + sprintf(expressionError,"Invalid operator at \"%s\"",&infix[infixPos]); + return false; + } + + switch (type) + { + case EXOP_BRACKETL: + case EXOP_MEML: + opcodeStack.push_back(type); + break; + case EXOP_BRACKETR: + while (true) + { + if (opcodeStack.empty()) + { + sprintf(expressionError,"Closing parenthesis without opening one"); + return false; + } + ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; + opcodeStack.pop_back(); + if (t == EXOP_BRACKETL) break; + dest.push_back(ExpressionPair(EXCOMM_OP,t)); + } + break; + case EXOP_MEMR: + while (true) + { + if (opcodeStack.empty()) + { + sprintf(expressionError,"Closing bracket without opening one"); + return false; + } + ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; + opcodeStack.pop_back(); + if (t == EXOP_MEML) + { + dest.push_back(ExpressionPair(EXCOMM_OP,EXOP_MEM)); + break; + } + dest.push_back(ExpressionPair(EXCOMM_OP,t)); + } + type = EXOP_NUMBER; + break; + default: + if (opcodeStack.empty() == false) + { + int CurrentPriority = ExpressionOpcodes[type].Priority; + while (!opcodeStack.empty()) + { + ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; + opcodeStack.pop_back(); + + if (t == EXOP_BRACKETL || t == EXOP_MEML) + { + opcodeStack.push_back(t); + break; + } + + if (ExpressionOpcodes[t].Priority >= CurrentPriority) + { + dest.push_back(ExpressionPair(EXCOMM_OP,t)); + } else { + opcodeStack.push_back(t); + break; + } + } + } + opcodeStack.push_back(type); + break; + } + infixPos += len; + lastOpcode = type; + } + } + + while (!opcodeStack.empty()) + { + ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; + opcodeStack.pop_back(); + + if (t == EXOP_BRACKETL) // opening bracket without closing one + { + sprintf(expressionError,"Parenthesis not closed"); + return false; + } + dest.push_back(ExpressionPair(EXCOMM_OP,t)); + } + +#if 0 // only for testing + char test[1024]; + int testPos = 0; + for (int i = 0; i < dest.size(); i++) + { + switch (dest[i].first) + { + case EXCOMM_CONST: + case EXCOMM_CONST_FLOAT: + testPos += sprintf(&test[testPos],"0x%04X ",dest[i].second); + break; + case EXCOMM_REF: + testPos += sprintf(&test[testPos],"r%d ",dest[i].second); + break; + case EXCOMM_OP: + testPos += sprintf(&test[testPos],"%s ",ExpressionOpcodes[dest[i].second].Name); + break; + }; + } +#endif + + return true; +} + +bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, uint32_t& dest) +{ + size_t num = 0; + uint32_t opcode; + std::vector valueStack; + unsigned int arg[5]; + float fArg[5]; + bool useFloat = false; + + while (num < exp.size()) + { + switch (exp[num].first) + { + case EXCOMM_CONST: // konstante zahl + valueStack.push_back(exp[num++].second); + break; + case EXCOMM_CONST_FLOAT: + useFloat = true; + valueStack.push_back(exp[num++].second); + break; + case EXCOMM_REF: + useFloat = useFloat || funcs->getReferenceType(exp[num].second) == EXPR_TYPE_FLOAT; + opcode = funcs->getReferenceValue(exp[num++].second); + valueStack.push_back(opcode); + break; + case EXCOMM_OP: // opcode + opcode = exp[num++].second; + if (valueStack.size() < ExpressionOpcodes[opcode].args) + { + sprintf(expressionError,"Not enough arguments"); + return false; + } + for (int l = 0; l < ExpressionOpcodes[opcode].args; l++) + { + arg[l] = valueStack[valueStack.size()-1]; + valueStack.pop_back(); + } + // In case of float representation. + memcpy(fArg, arg, sizeof(fArg)); + + switch (opcode) + { + case EXOP_MEMSIZE: // must be followed by EXOP_MEM + if (exp[num++].second != EXOP_MEM) + { + sprintf(expressionError,"Invalid memsize operator"); + return false; + } + + uint32_t val; + if(funcs->getMemoryValue(arg[1],arg[0],val,expressionError) == false) + { + return false; + } + valueStack.push_back(val); + break; + case EXOP_MEM: + { + uint32_t val; + if (funcs->getMemoryValue(arg[0],4,val,expressionError) == false) + { + return false; + } + valueStack.push_back(val); + } + break; + case EXOP_SIGNPLUS: // keine aktion nötig + break; + case EXOP_SIGNMINUS: // -0 + if (useFloat) + valueStack.push_back(0.0-fArg[0]); + else + valueStack.push_back(0-arg[0]); + break; + case EXOP_BITNOT: // ~b + valueStack.push_back(~arg[0]); + break; + case EXOP_LOGNOT: // !b + valueStack.push_back(!arg[0]); + break; + case EXOP_MUL: // a*b + if (useFloat) + valueStack.push_back(fArg[1]*fArg[0]); + else + valueStack.push_back(arg[1]*arg[0]); + break; + case EXOP_DIV: // a/b + if (arg[0] == 0) + { + sprintf(expressionError,"Division by zero"); + return false; + } + if (useFloat) + valueStack.push_back(fArg[1]/fArg[0]); + else + valueStack.push_back(arg[1]/arg[0]); + break; + case EXOP_MOD: // a%b + if (arg[0] == 0) + { + sprintf(expressionError,"Modulo by zero"); + return false; + } + valueStack.push_back(arg[1]%arg[0]); + break; + case EXOP_ADD: // a+b + if (useFloat) + valueStack.push_back(fArg[1]+fArg[0]); + else + valueStack.push_back(arg[1]+arg[0]); + break; + case EXOP_SUB: // a-b + if (useFloat) + valueStack.push_back(fArg[1]-fArg[0]); + else + valueStack.push_back(arg[1]-arg[0]); + break; + case EXOP_SHL: // a<>b + valueStack.push_back(arg[1]>>arg[0]); + break; + case EXOP_GREATEREQUAL: // a >= b + if (useFloat) + valueStack.push_back(fArg[1]>=fArg[0]); + else + valueStack.push_back(arg[1]>=arg[0]); + break; + case EXOP_GREATER: // a > b + if (useFloat) + valueStack.push_back(fArg[1]>fArg[0]); + else + valueStack.push_back(arg[1]>arg[0]); + break; + case EXOP_LOWEREQUAL: // a <= b + if (useFloat) + valueStack.push_back(fArg[1]<=fArg[0]); + else + valueStack.push_back(arg[1]<=arg[0]); + break; + case EXOP_LOWER: // a < b + if (useFloat) + valueStack.push_back(fArg[1] + +typedef std::pair ExpressionPair; +typedef std::vector PostfixExpression; + +enum ExpressionType +{ + EXPR_TYPE_UINT = 0, + EXPR_TYPE_FLOAT = 2, +}; + +class IExpressionFunctions +{ +public: + virtual bool parseReference(char* str, uint32_t& referenceIndex) = 0; + virtual bool parseSymbol(char* str, uint32_t& symbolValue) = 0; + virtual uint32_t getReferenceValue(uint32_t referenceIndex) = 0; + virtual ExpressionType getReferenceType(uint32_t referenceIndex) = 0; + virtual bool getMemoryValue(uint32_t address, int size, uint32_t& dest, char* error) = 0; +}; + +bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest); +bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, uint32_t& dest); +bool parseExpression(const char* exp, IExpressionFunctions* funcs, uint32_t& dest); +const char* getExpressionError(); diff --git a/ext/native/math/fast/fast_math.c b/ext/native/math/fast/fast_math.c new file mode 100644 index 0000000000..67506a1823 --- /dev/null +++ b/ext/native/math/fast/fast_math.c @@ -0,0 +1,12 @@ +#include "base/arch.h" +#include "fast_math.h" +#include "fast_matrix.h" + +void InitFastMath(int enableNEON) { + // Every architecture has its own define. This needs to be added to. + if (enableNEON) { +#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) + fast_matrix_mul_4x4 = &fast_matrix_mul_4x4_neon; +#endif + } +} diff --git a/ext/native/math/fast/fast_math.h b/ext/native/math/fast/fast_math.h new file mode 100644 index 0000000000..905c7e84f7 --- /dev/null +++ b/ext/native/math/fast/fast_math.h @@ -0,0 +1,21 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// Fast Math +// A mini library of math kernels. These should be large enough to be worth calling +// as functions, and generic enough to fit in the "native" library (not PSP specific stuff). + +// NEON versions are dynamically selected at runtime, when you call InitFastMath. + +// SSE versions are hard linked at compile time. + +// See fast_matrix.h for the first set of functions. + +void InitFastMath(int enableNEON); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/ext/native/math/fast/fast_matrix.c b/ext/native/math/fast/fast_matrix.c new file mode 100644 index 0000000000..b62404d75a --- /dev/null +++ b/ext/native/math/fast/fast_matrix.c @@ -0,0 +1,45 @@ +#include "fast_math.h" +#include "fast_matrix.h" + +#define xx 0 +#define xy 1 +#define xz 2 +#define xw 3 +#define yx 4 +#define yy 5 +#define yz 6 +#define yw 7 +#define zx 8 +#define zy 9 +#define zz 10 +#define zw 11 +#define wx 12 +#define wy 13 +#define wz 14 +#define ww 15 + +void fast_matrix_mul_4x4_c(float *dest, const float *a, const float *b) { + dest[xx] = b[xx] * a[xx] + b[xy] * a[yx] + b[xz] * a[zx] + b[xw] * a[wx]; + dest[xy] = b[xx] * a[xy] + b[xy] * a[yy] + b[xz] * a[zy] + b[xw] * a[wy]; + dest[xz] = b[xx] * a[xz] + b[xy] * a[yz] + b[xz] * a[zz] + b[xw] * a[wz]; + dest[xw] = b[xx] * a[xw] + b[xy] * a[yw] + b[xz] * a[zw] + b[xw] * a[ww]; + + dest[yx] = b[yx] * a[xx] + b[yy] * a[yx] + b[yz] * a[zx] + b[yw] * a[wx]; + dest[yy] = b[yx] * a[xy] + b[yy] * a[yy] + b[yz] * a[zy] + b[yw] * a[wy]; + dest[yz] = b[yx] * a[xz] + b[yy] * a[yz] + b[yz] * a[zz] + b[yw] * a[wz]; + dest[yw] = b[yx] * a[xw] + b[yy] * a[yw] + b[yz] * a[zw] + b[yw] * a[ww]; + + dest[zx] = b[zx] * a[xx] + b[zy] * a[yx] + b[zz] * a[zx] + b[zw] * a[wx]; + dest[zy] = b[zx] * a[xy] + b[zy] * a[yy] + b[zz] * a[zy] + b[zw] * a[wy]; + dest[zz] = b[zx] * a[xz] + b[zy] * a[yz] + b[zz] * a[zz] + b[zw] * a[wz]; + dest[zw] = b[zx] * a[xw] + b[zy] * a[yw] + b[zz] * a[zw] + b[zw] * a[ww]; + + dest[wx] = b[wx] * a[xx] + b[wy] * a[yx] + b[wz] * a[zx] + b[ww] * a[wx]; + dest[wy] = b[wx] * a[xy] + b[wy] * a[yy] + b[wz] * a[zy] + b[ww] * a[wy]; + dest[wz] = b[wx] * a[xz] + b[wy] * a[yz] + b[wz] * a[zz] + b[ww] * a[wz]; + dest[ww] = b[wx] * a[xw] + b[wy] * a[yw] + b[wz] * a[zw] + b[ww] * a[ww]; +} + +#ifndef fast_matrix_mul_4x4 +fptr_fast_matrix_mul_4x4 fast_matrix_mul_4x4 = &fast_matrix_mul_4x4_c; +#endif \ No newline at end of file diff --git a/ext/native/math/fast/fast_matrix.h b/ext/native/math/fast/fast_matrix.h new file mode 100644 index 0000000000..968739ba0b --- /dev/null +++ b/ext/native/math/fast/fast_matrix.h @@ -0,0 +1,25 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// A mini library of matrix math kernels. + +// TODO: Really need to wrap this block in a macro or something, will get repetitive. + +typedef void(*fptr_fast_matrix_mul_4x4)(float *dest, const float *a, const float *b); +extern void fast_matrix_mul_4x4_c(float *dest, const float *a, const float *b); +extern void fast_matrix_mul_4x4_neon(float *dest, const float *a, const float *b); +extern void fast_matrix_mul_4x4_sse(float *dest, const float *a, const float *b); + +#if defined(_M_IX86) || defined(_M_X64) // Hard link to SSE implementations on x86 +#define fast_matrix_mul_4x4 fast_matrix_mul_4x4_sse +#else +extern fptr_fast_matrix_mul_4x4 fast_matrix_mul_4x4; +#endif + + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/ext/native/math/fast/fast_matrix_neon.S b/ext/native/math/fast/fast_matrix_neon.S new file mode 100644 index 0000000000..3b5d930849 --- /dev/null +++ b/ext/native/math/fast/fast_matrix_neon.S @@ -0,0 +1,50 @@ + .syntax unified // Allow both ARM and Thumb-2 instructions + .text + .align 2 // Align the function code to a 4-byte (2^n) word boundary. + .arm // Use ARM instructions instead of Thumb. + +@ From ARM samples +@ +@ matrix_mul_float: +@ Calculate 4x4 (matrix 0) * (matrix 1) and store to result 4x4 matrix. +@ matrix 0, matrix 1 and result pointers can be the same, +@ ie. my_matrix = my_matrix * my_matrix is possible. +@ +@ r0 = pointer to 4x4 result matrix, single precision floats, column major order +@ r1 = pointer to 4x4 matrix 0, single precision floats, column major order +@ r2 = pointer to 4x4 matrix 1, single precision floats, column major order +@ + + .globl _fast_matrix_mul_4x4_neon +_fast_matrix_mul_4x4_neon: + .globl fast_matrix_mul_4x4_neon +fast_matrix_mul_4x4_neon: + vld1.32 {d16-d19}, [r1]! @ load first eight elements of matrix 0 + vld1.32 {d20-d23}, [r1]! @ load second eight elements of matrix 0 + vld1.32 {d0-d3}, [r2]! @ load first eight elements of matrix 1 + vld1.32 {d4-d7}, [r2]! @ load second eight elements of matrix 1 + + vmul.f32 q12, q8, d0[0] @ rslt col0 = (mat0 col0) * (mat1 col0 elt0) + vmul.f32 q13, q8, d2[0] @ rslt col1 = (mat0 col0) * (mat1 col1 elt0) + vmul.f32 q14, q8, d4[0] @ rslt col2 = (mat0 col0) * (mat1 col2 elt0) + vmul.f32 q15, q8, d6[0] @ rslt col3 = (mat0 col0) * (mat1 col3 elt0) + + vmla.f32 q12, q9, d0[1] @ rslt col0 += (mat0 col1) * (mat1 col0 elt1) + vmla.f32 q13, q9, d2[1] @ rslt col1 += (mat0 col1) * (mat1 col1 elt1) + vmla.f32 q14, q9, d4[1] @ rslt col2 += (mat0 col1) * (mat1 col2 elt1) + vmla.f32 q15, q9, d6[1] @ rslt col3 += (mat0 col1) * (mat1 col3 elt1) + + vmla.f32 q12, q10, d1[0] @ rslt col0 += (mat0 col2) * (mat1 col0 elt2) + vmla.f32 q13, q10, d3[0] @ rslt col1 += (mat0 col2) * (mat1 col1 elt2) + vmla.f32 q14, q10, d5[0] @ rslt col2 += (mat0 col2) * (mat1 col2 elt2) + vmla.f32 q15, q10, d7[0] @ rslt col3 += (mat0 col2) * (mat1 col2 elt2) + + vmla.f32 q12, q11, d1[1] @ rslt col0 += (mat0 col3) * (mat1 col0 elt3) + vmla.f32 q13, q11, d3[1] @ rslt col1 += (mat0 col3) * (mat1 col1 elt3) + vmla.f32 q14, q11, d5[1] @ rslt col2 += (mat0 col3) * (mat1 col2 elt3) + vmla.f32 q15, q11, d7[1] @ rslt col3 += (mat0 col3) * (mat1 col3 elt3) + + vst1.32 {d24-d27}, [r0]! @ store first eight elements of result + vst1.32 {d28-d31}, [r0]! @ store second eight elements of result + bx lr + diff --git a/ext/native/math/fast/fast_matrix_sse.c b/ext/native/math/fast/fast_matrix_sse.c new file mode 100644 index 0000000000..9de79ce760 --- /dev/null +++ b/ext/native/math/fast/fast_matrix_sse.c @@ -0,0 +1,25 @@ +#include "base/arch.h" + +#if defined(_M_IX86) || defined(_M_X64) + +#include + +#include "fast_matrix.h" + +void fast_matrix_mul_4x4_sse(float *dest, const float *a, const float *b) { + int i; + __m128 a_col_1 = _mm_loadu_ps(a); + __m128 a_col_2 = _mm_loadu_ps(&a[4]); + __m128 a_col_3 = _mm_loadu_ps(&a[8]); + __m128 a_col_4 = _mm_loadu_ps(&a[12]); + + for (i = 0; i < 16; i += 4) { + __m128 r_col = _mm_mul_ps(a_col_1, _mm_set1_ps(b[i])); + r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_2, _mm_set1_ps(b[i + 1]))); + r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_3, _mm_set1_ps(b[i + 2]))); + r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_4, _mm_set1_ps(b[i + 3]))); + _mm_storeu_ps(&dest[i], r_col); + } +} + +#endif diff --git a/ext/native/math/geom2d.h b/ext/native/math/geom2d.h new file mode 100644 index 0000000000..e937acafbc --- /dev/null +++ b/ext/native/math/geom2d.h @@ -0,0 +1,75 @@ +#pragma once + +#include + +struct Point { + Point() {} + Point(float x_, float y_) : x(x_), y(y_) {} + + float x; + float y; + + float distanceTo(const Point &other) const { + float dx = other.x - x, dy = other.y - y; + return sqrtf(dx*dx + dy*dy); + } + + /* + FocusDirection directionTo(const Point &other) const { + int angle = atan2f(other.y - y, other.x - x) / (2 * M_PI) - 0.125; + + }*/ +}; + + +// Resolved bounds on screen after layout. +struct Bounds { + Bounds() : x(0), y(0), w(0), h(0) {} + Bounds(float x_, float y_, float w_, float h_) : x(x_), y(y_), w(w_), h(h_) {} + + bool Contains(float px, float py) const { + return (px >= x && py >= y && px < x + w && py < y + h); + } + + bool Intersects(const Bounds &other) const { + return !(x > other.x2() || x2() < other.x || y > other.y2() || y2() < other.y); + } + + void Clip(const Bounds &clipTo) { + if (x < clipTo.x) { + w -= clipTo.x - x; + x = clipTo.x; + } + if (y < clipTo.y) { + h -= clipTo.y - y; + y = clipTo.y; + } + if (x2() > clipTo.x2()) { + w = clipTo.x2() - x; + } + if (y2() > clipTo.y2()) { + h = clipTo.y2() - y; + } + } + + float x2() const { return x + w; } + float y2() const { return y + h; } + float centerX() const { return x + w * 0.5f; } + float centerY() const { return y + h * 0.5f; } + Point Center() const { + return Point(centerX(), centerY()); + } + Bounds Expand(float amount) const { + return Bounds(x - amount, y - amount, w + amount * 2, h + amount * 2); + } + Bounds Offset(float xAmount, float yAmount) const { + return Bounds(x + xAmount, y + yAmount, w, h); + } + + float x; + float y; + float w; + float h; +}; + + diff --git a/ext/native/math/lin/aabb.cpp b/ext/native/math/lin/aabb.cpp new file mode 100644 index 0000000000..7d620528a3 --- /dev/null +++ b/ext/native/math/lin/aabb.cpp @@ -0,0 +1,268 @@ +#include "math/lin/aabb.h" +#include "math/lin/ray.h" +#include "math/lin/plane.h" + +#define NUMDIM 3 +#define RIGHT 0 +#define LEFT 1 +#define MIDDLE 2 + +static const float flt_plus_inf = -logf(0); // let's keep C and C++ compilers happy. + +AABB::AABB() : minB(0,0,0),maxB(0,0,0) { + +} + +void AABB::Add(const Vec3 &pt) { + for (int i=0; i<3; i++) + { + if (pt[i] < minB[i]) + minB[i] = pt[i]; + if (pt[i] > maxB[i]) + maxB[i] = pt[i]; + } +} + +bool AABB::Contains(const Vec3 &pt) const { + for (int i=0; i<3; i++) + { + if (pt[i] < minB[i]) + return false; + if (pt[i] > maxB[i]) + return false; + } + return true; +} + + +bool AABB::IntersectRay(const Ray &ray, float &tnear, float &tfar) const { + float tNear=-flt_plus_inf, tFar=flt_plus_inf; +//For each pair of planes P associated with X, Y, and Z do: +//(example using X planes) + for (int i=0; i<3; i++) + { + float min = minB[i]; + float max = maxB[i]; + + if (ray.dir[i] == 0.0f) //parallell! ARGH! + if (ray.origin[i] < min || ray.origin[i] > max) + return false; + //Intersect with slab + float T1 = (min - ray.origin[i]) * ray.invdir[i]; + float T2 = (max - ray.origin[i]) * ray.invdir[i]; + //Swap if necessary + if (T1 > T2) + { + float temp=T1; T1=T2; T2=temp; + } + //Save closest/farthest hits + if (T1 > tNear) tNear = T1; + if (T2 < tFar) tFar = T2; + } + + if (tNear > tFar) + return false; //missed the box + else + { + if (tFar < 0) + return false; //behind camera + tnear = tNear; + tfar = tFar; + } + return true; +} + + +// Possible orientation of the splitting plane in the interior node of the kd-tree, +// "No axis" denotes a leaf. +enum Axes +{ + Xaxis, + Yaxis, + Zaxis, + Noaxis +}; + + + +int AABB::GetShortestAxis() const +{ + Vec3 delta = maxB-minB; + if (delta.y fabsf(delta.x)) + { + if (fabsf(delta.z) > fabsf(delta.y)) + return 2; + else + return 1; + } + else + { + if (fabsf(delta.z) > fabsf(delta.x)) + return 2; + else + return 0; + } +} + + + +inline void FINDMINMAX(float x0, float x1, float x2, float &min, float &max ) +{ + min = max = x0; + if(x1max) + max=x1; + if(x2max) + max=x2; +} + +// X-tests +#define AXISTEST_X01( a, b, fa, fb ) \ + p0 = a * v0[1] - b * v0[2], p2 = a * v2[1] - b * v2[2]; \ + if (p0 < p2) { min = p0; max = p2;} else { min = p2; max = p0; } \ + rad = fa * a_BoxHalfsize[1] + fb * a_BoxHalfsize[2]; \ + if (min > rad || max < -rad) return 0; + +#define AXISTEST_X2( a, b, fa, fb ) \ + p0 = a * v0[1] - b * v0[2], p1 = a * v1[1] - b * v1[2]; \ + if (p0 < p1) { min = p0; max = p1; } else { min = p1; max = p0;} \ + rad = fa * a_BoxHalfsize[1] + fb * a_BoxHalfsize[2]; \ + if(min>rad || max<-rad) return 0; +// Y-tests +#define AXISTEST_Y02( a, b, fa, fb ) \ + p0 = -a * v0[0] + b * v0[2], p2 = -a * v2[0] + b * v2[2]; \ + if(p0 < p2) { min = p0; max = p2; } else { min = p2; max = p0; } \ + rad = fa * a_BoxHalfsize[0] + fb * a_BoxHalfsize[2]; \ + if (min > rad || max < -rad) return 0; +#define AXISTEST_Y1( a, b, fa, fb ) \ + p0 = -a * v0[0] + b * v0[2], p1 = -a * v1[0] + b * v1[2]; \ + if (p0 < p1) { min = p0; max = p1; } else { min = p1; max = p0; } \ + rad = fa * a_BoxHalfsize[0] + fb * a_BoxHalfsize[2]; \ + if (min > rad || max < -rad) return 0; +// Z-tests +#define AXISTEST_Z12( a, b, fa, fb ) \ + p1 = a * v1[0] - b * v1[1], p2 = a * v2[0] - b * v2[1]; \ + if(p2 < p1) { min = p2; max = p1; } else { min = p1; max = p2; } \ + rad = fa * a_BoxHalfsize[0] + fb * a_BoxHalfsize[1]; \ + if (min > rad || max < -rad) return 0; +#define AXISTEST_Z0( a, b, fa, fb ) \ + p0 = a * v0[0] - b * v0[1], p1 = a * v1[0] - b * v1[1]; \ + if(p0 < p1) { min = p0; max = p1; } else { min = p1; max = p0; } \ + rad = fa * a_BoxHalfsize[0] + fb * a_BoxHalfsize[1]; \ + if (min > rad || max < -rad) return 0; + +bool PlaneBoxOverlap(const Vec3& a_Normal, const Vec3& a_Vert, const Vec3& a_MaxBox ) +{ + Vec3 vmin, vmax; + for (int q = 0; q < 3; q++) + { + float v = a_Vert[q]; + if (a_Normal[q] > 0.0f) + { + vmin[q] = -a_MaxBox[q] - v; + vmax[q] = a_MaxBox[q] - v; + } + else + { + vmin[q] = a_MaxBox[q] - v; + vmax[q] = -a_MaxBox[q] - v; + } + } + if (( a_Normal * vmin) > 0.0f) + return false; + if (( a_Normal * vmax) >= 0.0f) + return true; + + return false; +} + + +bool AABB::IntersectsTriangle(const Vec3& a_V0, const Vec3& a_V1, const Vec3& a_V2 ) const +{ + Vec3 a_BoxCentre = GetMidpoint(); + Vec3 a_BoxHalfsize = GetExtents() / 2.0f; + Vec3 v0, v1, v2, normal, e0, e1, e2; + float min, max, p0, p1, p2, rad, fex, fey, fez; + v0 = a_V0 - a_BoxCentre; + v1 = a_V1 - a_BoxCentre; + v2 = a_V2 - a_BoxCentre; + e0 = v1 - v0, e1 = v2 - v1, e2 = v0 - v2; + fex = fabsf(e0[0]); + fey = fabsf(e0[1]); + fez = fabsf(e0[2]); + AXISTEST_X01( e0[2], e0[1], fez, fey ); + AXISTEST_Y02( e0[2], e0[0], fez, fex ); + AXISTEST_Z12( e0[1], e0[0], fey, fex ); + fex = fabsf(e1[0]); + fey = fabsf(e1[1]); + fez = fabsf(e1[2]); + AXISTEST_X01( e1[2], e1[1], fez, fey ); + AXISTEST_Y02( e1[2], e1[0], fez, fex ); + AXISTEST_Z0 ( e1[1], e1[0], fey, fex ); + fex = fabsf(e2[0]); + fey = fabsf(e2[1]); + fez = fabsf(e2[2]); + AXISTEST_X2 ( e2[2], e2[1], fez, fey ); + AXISTEST_Y1 ( e2[2], e2[0], fez, fex ); + AXISTEST_Z12( e2[1], e2[0], fey, fex ); + FINDMINMAX( v0[0], v1[0], v2[0], min, max ); + if (min > a_BoxHalfsize[0] || max < -a_BoxHalfsize[0]) + return false; + FINDMINMAX( v0[1], v1[1], v2[1], min, max ); + if (min > a_BoxHalfsize[1] || max < -a_BoxHalfsize[1]) + return false; + FINDMINMAX( v0[2], v1[2], v2[2], min, max ); + if (min > a_BoxHalfsize[2] || max < -a_BoxHalfsize[2]) + return false; + normal = e0 % e1; + if (!PlaneBoxOverlap( normal, v0, a_BoxHalfsize )) + return false; + return true; +} + + +bool AABB::BehindPlane(const Plane &plane) const { + if (plane.Distance(minB) > 0) + return false; + if (plane.Distance(maxB) > 0) + return false; + + if (plane.Distance(maxB.x, minB.y, minB.z) > 0) + return false; + if (plane.Distance(maxB.x, maxB.y, minB.z) > 0) + return false; + if (plane.Distance(maxB.x, minB.y, maxB.z) > 0) + return false; + + if (plane.Distance(minB.x, maxB.y, minB.z) > 0) + return false; + if (plane.Distance(minB.x, minB.y, maxB.z) > 0) + return false; + if (plane.Distance(minB.x, maxB.y, maxB.z) > 0) + return false; + + return true; +} diff --git a/ext/native/math/lin/aabb.h b/ext/native/math/lin/aabb.h new file mode 100644 index 0000000000..cf7cf963be --- /dev/null +++ b/ext/native/math/lin/aabb.h @@ -0,0 +1,40 @@ +#pragma once + +#include "math/lin/vec3.h" + +struct Ray; +class Plane; + +struct AABB { + Vec3 minB; + int pad; + Vec3 maxB; + int pad2; + + AABB(); + bool Contains(const Vec3 &pt) const; + bool IntersectRay(const Ray &ray, float &tnear, float &tfar) const; + + // Doesn't currently work. + bool IntersectRay2(const Ray &ray, float &tnear, float &tfar) const; + + bool IntersectsTriangle(const Vec3& a_V0, const Vec3& a_V1, const Vec3& a_V2) const; + void Add(const Vec3 &pt); + int GetShortestAxis() const; + int GetLongestAxis() const; + + float GetSize(int axis) const { + return maxB[axis] - minB[axis]; + } + float GetMidpoint(int axis) const { + return (minB[axis] + maxB[axis]) / 2; + } + Vec3 GetMidpoint() const { + return (minB + maxB) / 2; + } + Vec3 GetExtents() const { + return maxB - minB; + } + + bool BehindPlane(const Plane &plane) const; +}; diff --git a/ext/native/math/lin/matrix4x4.cpp b/ext/native/math/lin/matrix4x4.cpp new file mode 100644 index 0000000000..d90dc957ab --- /dev/null +++ b/ext/native/math/lin/matrix4x4.cpp @@ -0,0 +1,268 @@ +#include "math/lin/matrix4x4.h" + +#include + +#include "base/compat.h" +#include "math/lin/vec3.h" +#include "math/lin/quat.h" +#include "math/fast/fast_matrix.h" + +#ifdef _WIN32 +#undef far +#undef near +#endif + +// See http://code.google.com/p/oolongengine/source/browse/trunk/Oolong+Engine2/Math/neonmath/neon_matrix_impl.cpp?spec=svn143&r=143 when we need speed +// no wait. http://code.google.com/p/math-neon/ + +Matrix4x4 Matrix4x4::simpleInverse() const { + Matrix4x4 out; + out.xx = xx; + out.xy = yx; + out.xz = zx; + + out.yx = xy; + out.yy = yy; + out.yz = zy; + + out.zx = xz; + out.zy = yz; + out.zz = zz; + + out.wx = -(xx * wx + xy * wy + xz * wz); + out.wy = -(yx * wx + yy * wy + yz * wz); + out.wz = -(zx * wx + zy * wy + zz * wz); + + out.xw = 0.0f; + out.yw = 0.0f; + out.zw = 0.0f; + out.ww = 1.0f; + + return out; +} + +Matrix4x4 Matrix4x4::transpose() const +{ + Matrix4x4 out; + out.xx = xx;out.xy = yx;out.xz = zx;out.xw = wx; + out.yx = xy;out.yy = yy;out.yz = zy;out.yw = wy; + out.zx = xz;out.zy = yz;out.zz = zz;out.zw = wz; + out.wx = xw;out.wy = yw;out.wz = zw;out.ww = ww; + return out; +} + +Matrix4x4 Matrix4x4::operator * (const Matrix4x4 &other) const +{ + Matrix4x4 temp; + fast_matrix_mul_4x4(temp.m, other.m, this->m); + return temp; +} + +Matrix4x4 Matrix4x4::inverse() const { + Matrix4x4 temp; + float dW = 1.0f / (xx*(yy*zz - yz*zy) - xy*(yx*zz - yz*zx) - xz*(yy*zx - yx*zy)); + + temp.xx = (yy*zz - yz*zy) * dW; + temp.xy = (xz*zy - xy*zz) * dW; + temp.xz = (xy*yz - xz*yy) * dW; + temp.xw = xw; + + temp.yx = (yz*zx - yx*zz) * dW; + temp.yy = (xx*zz - xz*zx) * dW; + temp.yz = (xz*yx - xx*zx) * dW; + temp.yw = yw; + + temp.zx = (yx*zy - yy*zx) * dW; + temp.zy = (xy*zx - xx*zy) * dW; + temp.zz = (xx*yy - xy*yx) * dW; + temp.zw = zw; + + temp.wx = (yy*(zx*wz - zz*wx) + yz*(zy*wx - zx*wy) - yx*(zy*wz - zz*wy)) * dW; + temp.wy = (xx*(zy*wz - zz*wy) + xy*(zz*wx - zx*wz) + xz*(zx*wy - zy*wx)) * dW; + temp.wz = (xy*(yx*wz - yz*wx) + xz*(yy*wx - yx*wy) - xx*(yy*wz - yz*wy)) * dW; + temp.ww = ww; + + return temp; +} + +void Matrix4x4::setViewLookAt(const Vec3 &vFrom, const Vec3 &vAt, const Vec3 &vWorldUp) { + Vec3 vView = vFrom - vAt; // OpenGL, sigh... + vView.normalize(); + float DotProduct = vWorldUp * vView; + Vec3 vUp = vWorldUp - vView * DotProduct; + float Length = vUp.length(); + + if (1e-6f > Length) { + // EMERGENCY + vUp = Vec3(0.0f, 1.0f, 0.0f) - vView * vView.y; + // If we still have near-zero length, resort to a different axis. + Length = vUp.length(); + if (1e-6f > Length) + { + vUp = Vec3(0.0f, 0.0f, 1.0f) - vView * vView.z; + Length = vUp.length(); + if (1e-6f > Length) + return; + } + } + vUp.normalize(); + Vec3 vRight = vUp % vView; + empty(); + + xx = vRight.x; xy = vUp.x; xz=vView.x; + yx = vRight.y; yy = vUp.y; yz=vView.y; + zx = vRight.z; zy = vUp.z; zz=vView.z; + + wx = -vFrom * vRight; + wy = -vFrom * vUp; + wz = -vFrom * vView; + ww = 1.0f; +} + +void Matrix4x4::setViewLookAtD3D(const Vec3 &vFrom, const Vec3 &vAt, const Vec3 &vWorldUp) { + Vec3 vView = vAt - vFrom; + vView.normalize(); + float DotProduct = vWorldUp * vView; + Vec3 vUp = vWorldUp - vView * DotProduct; + float Length = vUp.length(); + + if (1e-6f > Length) { + vUp = Vec3(0.0f, 1.0f, 0.0f) - vView * vView.y; + // If we still have near-zero length, resort to a different axis. + Length = vUp.length(); + if (1e-6f > Length) + { + vUp = Vec3(0.0f, 0.0f, 1.0f) - vView * vView.z; + Length = vUp.length(); + if (1e-6f > Length) + return; + } + } + vUp.normalize(); + Vec3 vRight = vUp % vView; + empty(); + + xx = vRight.x; xy = vUp.x; xz=vView.x; + yx = vRight.y; yy = vUp.y; yz=vView.y; + zx = vRight.z; zy = vUp.z; zz=vView.z; + + wx = -vFrom * vRight; + wy = -vFrom * vUp; + wz = -vFrom * vView; + ww = 1.0f; +} + + +void Matrix4x4::setViewFrame(const Vec3 &pos, const Vec3 &vRight, const Vec3 &vView, const Vec3 &vUp) { + xx = vRight.x; xy = vUp.x; xz=vView.x; xw = 0.0f; + yx = vRight.y; yy = vUp.y; yz=vView.y; yw = 0.0f; + zx = vRight.z; zy = vUp.z; zz=vView.z; zw = 0.0f; + + wx = -pos * vRight; + wy = -pos * vUp; + wz = -pos * vView; + ww = 1.0f; +} + +//YXZ euler angles +void Matrix4x4::setRotation(float x,float y, float z) +{ + setRotationY(y); + Matrix4x4 temp; + temp.setRotationX(x); + *this *= temp; + temp.setRotationZ(z); + *this *= temp; +} + +void Matrix4x4::setProjection(float near, float far, float fov_horiz, float aspect) { + // Now OpenGL style. + empty(); + + float xFac = tanf(fov_horiz * 3.14f/360); + float yFac = xFac * aspect; + xx = 1.0f / xFac; + yy = 1.0f / yFac; + zz = -(far+near)/(far-near); + zw = -1.0f; + wz = -(2*far*near)/(far-near); +} + +void Matrix4x4::setProjectionD3D(float near_plane, float far_plane, float fov_horiz, float aspect) { + empty(); + float Q, f; + + f = fov_horiz*0.5f; + Q = far_plane / (far_plane - near_plane); + + xx = (float)(1.0f / tanf(f));; + yy = (float)(1.0f / tanf(f*aspect)); + zz = Q; + wz = -Q * near_plane; + zw = 1.0f; +} + +void Matrix4x4::setOrtho(float left, float right, float bottom, float top, float near, float far) { + setIdentity(); + xx = 2.0f / (right - left); + yy = 2.0f / (top - bottom); + zz = 2.0f / (far - near); + wx = -(right + left) / (right - left); + wy = -(top + bottom) / (top - bottom); + wz = -(far + near) / (far - near); +} + +void Matrix4x4::setOrthoD3D(float left, float right, float bottom, float top, float near, float far) { + setIdentity(); + xx = 2.0f / (right - left); + yy = 2.0f / (top - bottom); + zz = 1.0f / (far - near); + wx = -(right + left) / (right - left); + wy = -(top + bottom) / (top - bottom); + wz = -near / (far - near); +} + +void Matrix4x4::setProjectionInf(const float near_plane, const float fov_horiz, const float aspect) { + empty(); + float f = fov_horiz*0.5f; + xx = 1.0f / tanf(f); + yy = 1.0f / tanf(f*aspect); + zz = 1; + wz = -near_plane; + zw = 1.0f; +} + +void Matrix4x4::setRotationAxisAngle(const Vec3 &axis, float angle) { + Quaternion quat; + quat.setRotation(axis, angle); + quat.toMatrix(this); +} + +// from a (Position, Rotation, Scale) vec3 quat vec3 tuple +Matrix4x4 Matrix4x4::fromPRS(const Vec3 &positionv, const Quaternion &rotv, const Vec3 &scalev) { + Matrix4x4 newM; + newM.setIdentity(); + Matrix4x4 rot, scale; + rotv.toMatrix(&rot); + scale.setScaling(scalev); + newM = rot * scale; + newM.wx = positionv.x; + newM.wy = positionv.y; + newM.wz = positionv.z; + return newM; +} + +void Matrix4x4::toText(char *buffer, int len) const { + snprintf(buffer, len, "%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n", + xx,xy,xz,xw, + yx,yy,yz,yw, + zx,zy,zz,zw, + wx,wy,wz,ww); + buffer[len - 1] = '\0'; +} + +void Matrix4x4::print() const { + char buffer[256]; + toText(buffer, 256); + puts(buffer); +} diff --git a/ext/native/math/lin/matrix4x4.h b/ext/native/math/lin/matrix4x4.h new file mode 100644 index 0000000000..d56906d1f2 --- /dev/null +++ b/ext/native/math/lin/matrix4x4.h @@ -0,0 +1,172 @@ +#ifndef _MATH_LIN_MATRIX4X4_H +#define _MATH_LIN_MATRIX4X4_H + +#include "math/lin/vec3.h" + +class Quaternion; + +class Matrix4x4 { +public: + union { + struct { + float xx, xy, xz, xw; + float yx, yy, yz, yw; + float zx, zy, zz, zw; + float wx, wy, wz, ww; + }; + float m[16]; + }; + + const Vec3 right() const {return Vec3(xx, xy, xz);} + const Vec3 up() const {return Vec3(yx, yy, yz);} + const Vec3 front() const {return Vec3(zx, zy, zz);} + const Vec3 move() const {return Vec3(wx, wy, wz);} + + void setRight(const Vec3 &v) { + xx = v.x; xy = v.y; xz = v.z; + } + void setUp(const Vec3 &v) { + yx = v.x; yy = v.y; yz = v.z; + } + void setFront(const Vec3 &v) { + zx = v.x; zy = v.y; zz = v.z; + } + void setMove(const Vec3 &v) { + wx = v.x; wy = v.y; wz = v.z; + } + + + const float &operator[](int i) const { + return *(((const float *)this) + i); + } + float &operator[](int i) { + return *(((float *)this) + i); + } + Matrix4x4 operator * (const Matrix4x4 &other) const ; + void operator *= (const Matrix4x4 &other) { + *this = *this * other; + } + const float *getReadPtr() const { + return (const float *)this; + } + void empty() { + memset(this, 0, 16 * sizeof(float)); + } + void setScaling(const float f) { + empty(); + xx=yy=zz=f; ww=1.0f; + } + void setScaling(const Vec3 f) { + empty(); + xx=f.x; + yy=f.y; + zz=f.z; + ww=1.0f; + } + + void setIdentity() { + setScaling(1.0f); + } + void setTranslation(const Vec3 &trans) { + setIdentity(); + wx = trans.x; + wy = trans.y; + wz = trans.z; + } + void setTranslationAndScaling(const Vec3 &trans, const Vec3 &scale) { + setScaling(scale); + wx = trans.x; + wy = trans.y; + wz = trans.z; + } + + Matrix4x4 inverse() const; + Matrix4x4 simpleInverse() const; + Matrix4x4 transpose() const; + + void setRotationX(const float a) { + empty(); + float c=cosf(a); + float s=sinf(a); + xx = 1.0f; + yy = c; yz = s; + zy = -s; zz = c; + ww = 1.0f; + } + void setRotationY(const float a) { + empty(); + float c=cosf(a); + float s=sinf(a); + xx = c; xz = -s; + yy = 1.0f; + zx = s; zz = c ; + ww = 1.0f; + } + void setRotationZ(const float a) { + empty(); + float c=cosf(a); + float s=sinf(a); + xx = c; xy = s; + yx = -s; yy = c; + zz = 1.0f; + ww = 1.0f; + } + void setRotationAxisAngle(const Vec3 &axis, float angle); + + + void setRotation(float x,float y, float z); + void setProjection(float near_plane, float far_plane, float fov_horiz, float aspect = 0.75f); + void setProjectionD3D(float near_plane, float far_plane, float fov_horiz, float aspect = 0.75f); + void setProjectionInf(float near_plane, float fov_horiz, float aspect = 0.75f); + void setOrtho(float left, float right, float bottom, float top, float near, float far); + void setOrthoD3D(float left, float right, float bottom, float top, float near, float far); + void setShadow(float Lx, float Ly, float Lz, float Lw) { + float Pa=0; + float Pb=1; + float Pc=0; + float Pd=0; + //P = normalize(Plane); + float d = (Pa*Lx + Pb*Ly + Pc*Lz + Pd*Lw); + + xx=Pa * Lx + d; xy=Pa * Ly; xz=Pa * Lz; xw=Pa * Lw; + yx=Pb * Lx; yy=Pb * Ly + d; yz=Pb * Lz; yw=Pb * Lw; + zx=Pc * Lx; zy=Pc * Ly; zz=Pc * Lz + d; zw=Pc * Lw; + wx=Pd * Lx; wy=Pd * Ly; wz=Pd * Lz; ww=Pd * Lw + d; + } + + void setViewLookAt(const Vec3 &from, const Vec3 &at, const Vec3 &worldup); + void setViewLookAtD3D(const Vec3 &from, const Vec3 &at, const Vec3 &worldup); + void setViewFrame(const Vec3 &pos, const Vec3 &right, const Vec3 &forward, const Vec3 &up); + void stabilizeOrtho() { + /* + front().normalize(); + right().normalize(); + up() = front() % right(); + right() = up() % front(); + */ + } + void toText(char *buffer, int len) const; + void print() const; + static Matrix4x4 fromPRS(const Vec3 &position, const Quaternion &normal, const Vec3 &scale); + + void translateAndScale(const Vec3 &trans, const Vec3 &scale) { + xx = xx * scale.x + xw * trans.x; + xy = xy * scale.y + xw * trans.y; + xz = xz * scale.z + xw * trans.z; + + yx = yx * scale.x + yw * trans.x; + yy = yy * scale.y + yw * trans.y; + yz = yz * scale.z + yw * trans.z; + + zx = zx * scale.x + zw * trans.x; + zy = zy * scale.y + zw * trans.y; + zz = zz * scale.z + zw * trans.z; + + wx = wx * scale.x + ww * trans.x; + wy = wy * scale.y + ww * trans.y; + wz = wz * scale.z + ww * trans.z; + } +}; + +#endif // _MATH_LIN_MATRIX4X4_H + diff --git a/ext/native/math/lin/matrix_neon.s b/ext/native/math/lin/matrix_neon.s new file mode 100644 index 0000000000..a663ffe956 --- /dev/null +++ b/ext/native/math/lin/matrix_neon.s @@ -0,0 +1,106 @@ +@ +@ NEON matrix multiplication examples +@ + +.syntax unified + +@ +@ matrix_mul_float: +@ Calculate 4x4 (matrix 0) * (matrix 1) and store to result 4x4 matrix. +@ matrix 0, matrix 1 and result pointers can be the same, +@ ie. my_matrix = my_matrix * my_matrix is possible. +@ +@ r0 = pointer to 4x4 result matrix, single precision floats, column major order +@ r1 = pointer to 4x4 matrix 0, single precision floats, column major order +@ r2 = pointer to 4x4 matrix 1, single precision floats, column major order +@ + + .global matrix_mul_float +matrix_mul_float: + vld1.32 {d16-d19}, [r1]! @ load first eight elements of matrix 0 + vld1.32 {d20-d23}, [r1]! @ load second eight elements of matrix 0 + vld1.32 {d0-d3}, [r2]! @ load first eight elements of matrix 1 + vld1.32 {d4-d7}, [r2]! @ load second eight elements of matrix 1 + + vmul.f32 q12, q8, d0[0] @ rslt col0 = (mat0 col0) * (mat1 col0 elt0) + vmul.f32 q13, q8, d2[0] @ rslt col1 = (mat0 col0) * (mat1 col1 elt0) + vmul.f32 q14, q8, d4[0] @ rslt col2 = (mat0 col0) * (mat1 col2 elt0) + vmul.f32 q15, q8, d6[0] @ rslt col3 = (mat0 col0) * (mat1 col3 elt0) + + vmla.f32 q12, q9, d0[1] @ rslt col0 += (mat0 col1) * (mat1 col0 elt1) + vmla.f32 q13, q9, d2[1] @ rslt col1 += (mat0 col1) * (mat1 col1 elt1) + vmla.f32 q14, q9, d4[1] @ rslt col2 += (mat0 col1) * (mat1 col2 elt1) + vmla.f32 q15, q9, d6[1] @ rslt col3 += (mat0 col1) * (mat1 col3 elt1) + + vmla.f32 q12, q10, d1[0] @ rslt col0 += (mat0 col2) * (mat1 col0 elt2) + vmla.f32 q13, q10, d3[0] @ rslt col1 += (mat0 col2) * (mat1 col1 elt2) + vmla.f32 q14, q10, d5[0] @ rslt col2 += (mat0 col2) * (mat1 col2 elt2) + vmla.f32 q15, q10, d7[0] @ rslt col3 += (mat0 col2) * (mat1 col2 elt2) + + vmla.f32 q12, q11, d1[1] @ rslt col0 += (mat0 col3) * (mat1 col0 elt3) + vmla.f32 q13, q11, d3[1] @ rslt col1 += (mat0 col3) * (mat1 col1 elt3) + vmla.f32 q14, q11, d5[1] @ rslt col2 += (mat0 col3) * (mat1 col2 elt3) + vmla.f32 q15, q11, d7[1] @ rslt col3 += (mat0 col3) * (mat1 col3 elt3) + + vst1.32 {d24-d27}, [r0]! @ store first eight elements of result + vst1.32 {d28-d31}, [r0]! @ store second eight elements of result + + mov pc, lr @ return to caller + + + + + +@ Macro: mul_col_s16 +@ +@ Multiply a four s16 element column of a matrix by the columns of a second matrix +@ to give a column of results. Elements are assumed to be in Q1.14 format. +@ Inputs: col_d - d register containing a column of the matrix +@ Outputs: res_d - d register containing the column of results +@ Corrupts: register q12 +@ Assumes: the second matrix columns are in registers d16-d19 in column major order +@ + + .macro mul_col_s16 res_d, col_d + vmull.s16 q12, d16, \col_d[0] @ multiply col element 0 by matrix col 0 + vmlal.s16 q12, d17, \col_d[1] @ multiply-acc col element 1 by matrix col 1 + vmlal.s16 q12, d18, \col_d[2] @ multiply-acc col element 2 by matrix col 2 + vmlal.s16 q12, d19, \col_d[3] @ multiply-acc col element 3 by matrix col 3 + vqrshrn.s32 \res_d, q12, #14 @ shift right and narrow accumulator into + @ Q1.14 fixed point format, with saturation + .endm + +@ +@ matrix_mul_fixed: +@ Calculate 4x4 (matrix 0) * (matrix 1) and store to result 4x4 matrix. +@ matrix 0, matrix 1 and result pointers can be the same, +@ ie. my_matrix = my_matrix * my_matrix is possible +@ +@ r0 = pointer to 4x4 result matrix, Q1.14 fixed point, column major order +@ r1 = pointer to 4x4 matrix 0, Q1.14 fixed point, column major order +@ r2 = pointer to 4x4 matrix 1, Q1.14 fixed point, column major order +@ + + .global matrix_mul_fixed +matrix_mul_fixed: + vld1.16 {d16-d19}, [r1] @ load sixteen elements of matrix 0 + vld1.16 {d0-d3}, [r2] @ load sixteen elements of matrix 1 + + mul_col_s16 d4, d0 @ matrix 0 * matrix 1 col 0 + mul_col_s16 d5, d1 @ matrix 0 * matrix 1 col 1 + mul_col_s16 d6, d2 @ matrix 0 * matrix 1 col 2 + mul_col_s16 d7, d3 @ matrix 0 * matrix 1 col 3 + + vst1.16 {d4-d7}, [r0] @ store sixteen elements of result + + mov pc, lr @ return to caller + + + + + + + + + + diff --git a/ext/native/math/lin/plane.cpp b/ext/native/math/lin/plane.cpp new file mode 100644 index 0000000000..2b14c3420d --- /dev/null +++ b/ext/native/math/lin/plane.cpp @@ -0,0 +1,10 @@ +#include "math/lin/matrix4x4.h" +#include "math/lin/plane.h" + + +void Plane::TransformByIT(const Matrix4x4 &m, Plane *out) { + out->x = x * m.xx + y * m.yx + z * m.zx + d * m.wx; + out->y = x * m.xy + y * m.yy + z * m.zy + d * m.wy; + out->z = x * m.xz + y * m.yz + z * m.zz + d * m.wz; + out->d = x * m.xw + y * m.yw + z * m.zw + d * m.ww; +} diff --git a/ext/native/math/lin/plane.h b/ext/native/math/lin/plane.h new file mode 100644 index 0000000000..f369ef1259 --- /dev/null +++ b/ext/native/math/lin/plane.h @@ -0,0 +1,37 @@ +#ifndef _PLANE_H +#define _PLANE_H + +#include "math/lin/vec3.h" + +class Matrix4x4; + +class Plane { +public: + float x, y, z, d; + Plane() {} + Plane(float x_, float y_, float z_, float d_) + : x(x_), y(y_), z(z_), d(d_) { } + ~Plane() {} + + float Distance(const Vec3 &v) const { + return x * v.x + y * v.y + z * v.z + d; + } + + float Distance(float px, float py, float pz) const { + return x * px + y * py + z * pz + d; + } + + void Normalize() { + float inv_length = sqrtf(x * x + y * y + z * z); + x *= inv_length; + y *= inv_length; + z *= inv_length; + d *= inv_length; + } + + // Matrix is the inverse transpose of the wanted transform. + // out cannot be equal to this. + void TransformByIT(const Matrix4x4 &matrix, Plane *out); +}; + +#endif diff --git a/ext/native/math/lin/quat.cpp b/ext/native/math/lin/quat.cpp new file mode 100644 index 0000000000..87ce1a94c3 --- /dev/null +++ b/ext/native/math/lin/quat.cpp @@ -0,0 +1,125 @@ +#include "math/lin/quat.h" +#include "math/lin/matrix4x4.h" + +void Quaternion::toMatrix(Matrix4x4 *out) const { + Matrix4x4 temp; + temp.setIdentity(); + float ww, xx, yy, zz, wx, wy, wz, xy, xz, yz; + ww = w*w; xx = x*x; yy = y*y; zz = z*z; + wx = w*x*2; wy = w*y*2; wz = w*z*2; + xy = x*y*2; xz = x*z*2; yz = y*z*2; + + temp.xx = ww + xx - yy - zz; + temp.xy = xy + wz; + temp.xz = xz - wy; + + temp.yx = xy - wz; + temp.yy = ww - xx + yy - zz; + temp.yz = yz + wx; + + temp.zx = xz + wy; + temp.zy = yz - wx; + temp.zz = ww - xx - yy + zz; + + *out = temp; +} + +Quaternion Quaternion::fromMatrix(Matrix4x4 &m) +{ + // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + // article "Quaternion Calculus and Fast Animation". + Quaternion q(0,0,0,1); + /* + float fTrace = m[0][0] + m[1][1] + m[2][2]; + float fRoot; + + if( fTrace > 0.0 ) + { + fRoot = sqrtf( fTrace + 1.0f ); + + q.w = 0.5f * fRoot; + + fRoot = 0.5f / fRoot; + + q.x = ( m[2][1] - m[1][2] ) * fRoot; + q.y = ( m[0][2] - m[2][0] ) * fRoot; + q.z = ( m[1][0] - m[0][1] ) * fRoot; + } + else + { + int iNext[3] = { 1, 2, 0 }; + + int i = 0; + if( m[1][1] > m[0][0] ) + i = 1; + + if( m[2][2] > m[i][i] ) + i = 2; + + int j = iNext[i]; + int k = iNext[j]; + + fRoot = sqrtf( m[i][i] - m[j][j] - m[k][k] + 1.0f ); + + float *apfQuat = &q.x; + + apfQuat[i] = 0.5f * fRoot; + + fRoot = 0.5f / fRoot; + + q.w = ( m[k][j] - m[j][k] ) * fRoot; + + apfQuat[j] = ( m[j][i] + m[i][j] ) * fRoot; + apfQuat[k] = ( m[k][i] + m[i][k] ) * fRoot; + } + q.normalize(); */ + return q; +}; + +// TODO: Allegedly, lerp + normalize can achieve almost as good results. +Quaternion Quaternion::slerp(const Quaternion &to, const float a) const { + Quaternion to2; + float angle, cos_angle, scale_from, scale_to, sin_angle; + + cos_angle = (x * to.x) + (y * to.y) + (z * to.z) + (w * to.w); //4D dot product + + if (cos_angle < 0.0f) + { + cos_angle = -cos_angle; + to2.w = -to.w; to2.x = -to.x; to2.y = -to.y; to2.z = -to.z; + } + else + { + to2 = to; + } + + if ((1.0f - fabsf(cos_angle)) > 0.00001f) + { + /* spherical linear interpolation (SLERP) */ + angle = acosf(cos_angle); + sin_angle = sinf(angle); + scale_from = sinf((1.0f - a) * angle) / sin_angle; + scale_to = sinf(a * angle) / sin_angle; + } + else + { + /* to prevent divide-by-zero, resort to linear interpolation */ + // This is okay in 99% of cases anyway, maybe should be the default? + scale_from = 1.0f - a; + scale_to = a; + } + + return Quaternion( + scale_from*x + scale_to*to2.x, + scale_from*y + scale_to*to2.y, + scale_from*z + scale_to*to2.z, + scale_from*w + scale_to*to2.w + ); +} + +Quaternion Quaternion::multiply(const Quaternion &q) const { + return Quaternion((w * q.x) + (x * q.w) + (y * q.z) - (z * q.y), + (w * q.y) + (y * q.w) + (z * q.x) - (x * q.z), + (w * q.z) + (z * q.w) + (x * q.y) - (y * q.x), + (w * q.w) - (x * q.x) - (y * q.y) - (z * q.z)); +} diff --git a/ext/native/math/lin/quat.h b/ext/native/math/lin/quat.h new file mode 100644 index 0000000000..85b4d94c94 --- /dev/null +++ b/ext/native/math/lin/quat.h @@ -0,0 +1,92 @@ +#ifndef _MATH_LIN_QUAT_H +#define _MATH_LIN_QUAT_H + +#include "math/lin/vec3.h" + +class Matrix4x4; + +class Quaternion +{ +public: + float x,y,z,w; + + Quaternion() { } + Quaternion(const float _x, const float _y, const float _z, const float _w) { + x=_x; y=_y; z=_z; w=_w; + } + void setIdentity() + { + x=y=z=0; w=1.0f; + } + void setXRotation(const float r) { w = cosf(r / 2); x = sinf(r / 2); y = z = 0; } + void setYRotation(const float r) { w = cosf(r / 2); y = sinf(r / 2); x = z = 0; } + void setZRotation(const float r) { w = cosf(r / 2); z = sinf(r / 2); x = y = 0; } + void toMatrix(Matrix4x4 *out) const; + static Quaternion fromMatrix(Matrix4x4 &m); + + Quaternion operator *(Quaternion &q) const + { + return Quaternion( + (w * q.w) - (x * q.x) - (y * q.y) - (z * q.z), + (w * q.x) + (x * q.w) + (y * q.z) - (z * q.y), + (w * q.y) + (y * q.w) + (z * q.x) - (x * q.z), + (w * q.z) + (z * q.w) + (x * q.y) - (y * q.x) + ); + } + Quaternion operator -() + { + return Quaternion(-x,-y,-z,-w); + } + void setRotation(Vec3 axis, float angle) + { + axis /= axis.length(); + angle *= .5f; + float sine = sinf(angle); + w = cosf(angle); + x = sine * axis.x; + y = sine * axis.y; + z = sine * axis.z; + } + void toAxisAngle(Vec3 &v, float &angle) + { + normalize(); + if (w==1.0f && x==0.0f && y==0.0f && z==0.0f) + { + v = Vec3(0,1,0); + angle = 0.0f; + return; + } + float cos_a = w; + angle = acosf(cos_a) * 2; + float sin_a = sqrtf( 1.0f - cos_a * cos_a ); + if (fabsf(sin_a) < 0.00005f) sin_a = 1; + float inv_sin_a=1.0f/sin_a; + v.x = x * inv_sin_a; + v.y = y * inv_sin_a; + v.z = z * inv_sin_a; + } + enum { + QUAT_SHORT, + QUAT_LONG, + QUAT_CW, + QUAT_CCW + }; + Quaternion slerp(const Quaternion &to, const float a) const; + Quaternion multiply(const Quaternion &q) const; + float &operator [] (int i) { + return *((&x) + i); + } + float operator [] (int i) const { + return *((&x) + i); + } + //not sure about this, maybe mag is supposed to sqrt + float magnitude() const { + return x*x + y*y + z*z + w*w; + } + void normalize() { + float f = 1.0f/sqrtf(magnitude()); + x*=f; y*=f; z*=f; w*=f; + } +}; + +#endif // _MATH_LIN_QUAT_H diff --git a/ext/native/math/lin/ray.h b/ext/native/math/lin/ray.h new file mode 100644 index 0000000000..2287460fbb --- /dev/null +++ b/ext/native/math/lin/ray.h @@ -0,0 +1,14 @@ +#pragma once + +#include "vec3.h" + +/* __declspec(align(16)) */ struct Ray +{ + Vec3 origin; + int pad; + Vec3 dir; + int pad2; + Vec3 invdir; + int pad3; +}; + diff --git a/ext/native/math/lin/vec3.cpp b/ext/native/math/lin/vec3.cpp new file mode 100644 index 0000000000..aaebfc7d02 --- /dev/null +++ b/ext/native/math/lin/vec3.cpp @@ -0,0 +1,28 @@ +#include + +#include "math/lin/vec3.h" +#include "math/lin/matrix4x4.h" + +Vec3 Vec3::operator *(const Matrix4x4 &m) const { + return Vec3(x*m.xx + y*m.yx + z*m.zx + m.wx, + x*m.xy + y*m.yy + z*m.zy + m.wy, + x*m.xz + y*m.yz + z*m.zz + m.wz); +} +Vec4 Vec3::multiply4D(const Matrix4x4 &m) const { + return Vec4(x*m.xx + y*m.yx + z*m.zx + m.wx, + x*m.xy + y*m.yy + z*m.zy + m.wy, + x*m.xz + y*m.yz + z*m.zz + m.wz, + x*m.xw + y*m.yw + z*m.zw + m.ww); +} +Vec4 Vec4::multiply4D(Matrix4x4 &m) const { + return Vec4(x*m.xx + y*m.yx + z*m.zx + w*m.wx, + x*m.xy + y*m.yy + z*m.zy + w*m.wy, + x*m.xz + y*m.yz + z*m.zz + w*m.wz, + x*m.xw + y*m.yw + z*m.zw + w*m.ww); +} + +Vec3 Vec3::rotatedBy(const Matrix4x4 &m) const { + return Vec3(x*m.xx + y*m.yx + z*m.zx, + x*m.xy + y*m.yy + z*m.zy, + x*m.xz + y*m.yz + z*m.zz); +} diff --git a/ext/native/math/lin/vec3.h b/ext/native/math/lin/vec3.h new file mode 100644 index 0000000000..cfc7d2eb89 --- /dev/null +++ b/ext/native/math/lin/vec3.h @@ -0,0 +1,145 @@ +#ifndef _MATH_LIN_VEC3 +#define _MATH_LIN_VEC3 + +#include +#include // memset + +class Matrix4x4; + +// Hm, doesn't belong in this file. +class Vec4 { +public: + float x,y,z,w; + Vec4(){} + Vec4(float a, float b, float c, float d) {x=a;y=b;z=c;w=d;} + Vec4 multiply4D(Matrix4x4 &m) const; +}; + +class Vec3 { +public: + float x,y,z; + + Vec3() { } + explicit Vec3(float f) {x=y=z=f;} + + float operator [] (int i) const { return (&x)[i]; } + float &operator [] (int i) { return (&x)[i]; } + + Vec3(const float _x, const float _y, const float _z) { + x=_x; y=_y; z=_z; + } + void Set(float _x, float _y, float _z) { + x=_x; y=_y; z=_z; + } + Vec3 operator + (const Vec3 &other) const { + return Vec3(x+other.x, y+other.y, z+other.z); + } + void operator += (const Vec3 &other) { + x+=other.x; y+=other.y; z+=other.z; + } + Vec3 operator -(const Vec3 &v) const { + return Vec3(x-v.x,y-v.y,z-v.z); + } + void operator -= (const Vec3 &other) + { + x-=other.x; y-=other.y; z-=other.z; + } + Vec3 operator -() const { + return Vec3(-x,-y,-z); + } + + Vec3 operator * (const float f) const { + return Vec3(x*f,y*f,z*f); + } + Vec3 operator / (const float f) const { + float invf = (1.0f/f); + return Vec3(x*invf,y*invf,z*invf); + } + void operator /= (const float f) + { + *this = *this / f; + } + float operator * (const Vec3 &other) const { + return x*other.x + y*other.y + z*other.z; + } + void operator *= (const float f) { + *this = *this * f; + } + void scaleBy(const Vec3 &other) { + x *= other.x; y *= other.y; z *= other.z; + } + Vec3 scaledBy(const Vec3 &other) const { + return Vec3(x*other.x, y*other.y, z*other.z); + } + Vec3 scaledByInv(const Vec3 &other) const { + return Vec3(x/other.x, y/other.y, z/other.z); + } + Vec3 operator *(const Matrix4x4 &m) const; + void operator *=(const Matrix4x4 &m) { + *this = *this * m; + } + Vec4 multiply4D(const Matrix4x4 &m) const; + Vec3 rotatedBy(const Matrix4x4 &m) const; + Vec3 operator %(const Vec3 &v) const { + return Vec3(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); + } + float length2() const { + return x*x + y*y + z*z; + } + float length() const { + return sqrtf(length2()); + } + void setLength(const float l) { + (*this) *= l/length(); + } + Vec3 withLength(const float l) const { + return (*this) * l / length(); + } + float distance2To(const Vec3 &other) const { + return Vec3(other-(*this)).length2(); + } + Vec3 normalized() const { + return (*this) / length(); + } + float normalize() { //returns the previous length, is often useful + float len = length(); + (*this) = (*this)/len; + return len; + } + bool operator == (const Vec3 &other) const { + if (x==other.x && y==other.y && z==other.z) + return true; + else + return false; + } + Vec3 lerp(const Vec3 &other, const float t) const { + return (*this)*(1-t) + other*t; + } + void setZero() { + memset((void *)this,0,sizeof(float)*3); + } +}; + +inline Vec3 operator * (const float f, const Vec3 &v) {return v * f;} + +// In new code, prefer these to the operators. + +inline float dot(const Vec3 &a, const Vec3 &b) { + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +inline Vec3 cross(const Vec3 &a, const Vec3 &b) { + return a % b; +} + +inline float sqr(const Vec3 &v) { + return dot(v, v); +} + +class AABBox { +public: + Vec3 min; + Vec3 max; +}; + +#endif // _MATH_LIN_VEC3 diff --git a/ext/native/math/math_util.cpp b/ext/native/math/math_util.cpp new file mode 100644 index 0000000000..eb50c58426 --- /dev/null +++ b/ext/native/math/math_util.cpp @@ -0,0 +1,51 @@ +#include "math/math_util.h" +#include +#ifdef __SYMBIAN32__ +#include +#endif + +// QNX can only use RunFast mode and it is already the default. +#if defined(__ARM_ARCH_7A__) && !defined(BLACKBERRY) && !defined(__SYMBIAN32__) +// Enables 'RunFast' VFP mode. +void EnableFZ() { + int x; + asm( + "fmrx %[result],FPSCR \r\n" + "orr %[result],%[result],#16777216 \r\n" + "fmxr FPSCR,%[result]" + :[result] "=r" (x) : : + ); + //printf("ARM FPSCR: %08x\n",x); +} + +// New fastmode code from: http://pandorawiki.org/Floating_Point_Optimization +// These settings turbocharge the slow VFP unit on Cortex-A8 based chips by setting +// restrictions that permit running VFP instructions on the NEON unit. +// Denormal flush-to-zero, for example. +void FPU_SetFastMode() { + static const unsigned int x = 0x04086060; + static const unsigned int y = 0x03000000; + int r; + asm volatile ( + "fmrx %0, fpscr \n\t" //r0 = FPSCR + "and %0, %0, %1 \n\t" //r0 = r0 & 0x04086060 + "orr %0, %0, %2 \n\t" //r0 = r0 | 0x03000000 + "fmxr fpscr, %0 \n\t" //FPSCR = r0 + : "=r"(r) + : "r"(x), "r"(y) + ); +} + +#else + +void EnableFZ() { +#ifdef __SYMBIAN32__ + // Set RunFast hardware mode for Symbian VFPv2. + User::SetFloatingPointMode(EFpModeRunFast); +#endif + // TODO +} + +void FPU_SetFastMode() {} + +#endif diff --git a/ext/native/math/math_util.h b/ext/native/math/math_util.h new file mode 100644 index 0000000000..d4a299b0bd --- /dev/null +++ b/ext/native/math/math_util.h @@ -0,0 +1,212 @@ +#pragma once + +#include +#include + +#include "base/basictypes.h" + +inline float sqr(float f) {return f*f;} +inline float sqr_signed(float f) {return f<0 ? -f*f : f*f;} + +typedef unsigned short float16; + +// This ain't a 1.5.10 float16, it's a stupid hack format where we chop 16 bits off a float. +// This choice is subject to change. Don't think I'm using this for anything at all now anyway. +// DEPRECATED +inline float16 FloatToFloat16(float x) { + int ix; + memcpy(&ix, &x, sizeof(float)); + return ix >> 16; +} + +inline float Float16ToFloat(float16 ix) { + float x; + memcpy(&x, &ix, sizeof(float)); + return x; +} + +inline uint32_t RoundUpToPowerOf2(uint32_t v) { + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; +} + +#define PI 3.141592653589793f +#ifndef M_PI +#define M_PI 3.141592653589793f +#endif + +// The stuff in this file is from all over the web, esp. dspmusic.org. I think it's all public domain. +// In any case, very little of it is used anywhere at the moment. + +// Calculate pseudo-random 32 bit number based on linear congruential method. +void SetSeed(unsigned int seed); +unsigned int GenerateRandomNumber(); +inline float GenerateRandomFloat01() { + return (float)((double)GenerateRandomNumber() / 0xFFFFFFFF); +} +inline float GenerateRandomSignedFloat() { + return (float)((double)GenerateRandomNumber() / 0x80000000) - 1.0f; +} + + +inline float GaussRand() +{ + float R1 = GenerateRandomFloat01(); + float R2 = GenerateRandomFloat01(); + + float X = sqrtf(-2.0f * logf(R1)) * cosf(2.0f * PI * R2); + if (X > 4.0f) X = 4.0f; + if (X < -4.0f) X = -4.0f; + return X; +} + +// Accuracy unknown +inline double atan_fast(double x) { + return (x / (1.0 + 0.28 * (x * x))); +} + +template +inline T clamp_value(T val, T floor, T cap) { + if (val > cap) + return cap; + else if (val < floor) + return floor; + else + return val; +} + +// linear -> dB conversion +inline float lin2dB(float lin) { + const float LOG_2_DB = 8.6858896380650365530225783783321f; // 20 / ln( 10 ) + return logf(lin) * LOG_2_DB; +} + +// dB -> linear conversion +inline float dB2lin(float dB) { + const float DB_2_LOG = 0.11512925464970228420089957273422f; // ln( 10 ) / 20 + return expf(dB * DB_2_LOG); +} + +union FP32 { + uint32_t u; + float f; +}; + +struct FP16 { + uint16_t u; +}; + +inline bool my_isinf(float f) { + FP32 f2u; + f2u.f = f; + return f2u.u == 0x7f800000 || + f2u.u == 0xff800000; +} + +inline bool my_isnan(float f) { + FP32 f2u; + f2u.f = f; + // NaNs have non-zero mantissa + return ((f2u.u & 0x7F800000) == 0x7F800000) && (f2u.u & 0x7FFFFF); +} + +inline bool my_isnanorinf(float f) { + FP32 f2u; + f2u.f = f; + // NaNs have non-zero mantissa, infs have zero mantissa. That is, we just ignore the mantissa here. + return ((f2u.u & 0x7F800000) == 0x7F800000); +} + +inline int is_even(float d) { + float int_part; + modff(d / 2.0f, &int_part); + return 2.0f * int_part == d; +} + +// Rounds *.5 to closest even number +inline double round_ieee_754(double d) { + float i = floor(d); + d -= i; + if (d < 0.5f) + return i; + if (d > 0.5f) + return i + 1.0f; + if (is_even(i)) + return i; + return i + 1.0f; +} + +// magic code from ryg: http://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ +// See also SSE2 version: https://gist.github.com/rygorous/2144712 +inline FP32 half_to_float_fast5(FP16 h) +{ + static const FP32 magic = { (127 + (127 - 15)) << 23 }; + static const FP32 was_infnan = { (127 + 16) << 23 }; + FP32 o; + o.u = (h.u & 0x7fff) << 13; // exponent/mantissa bits + o.f *= magic.f; // exponent adjust + if (o.f >= was_infnan.f) // make sure Inf/NaN survive (retain the low bits) + o.u = (255 << 23) | (h.u & 0x03ff); + o.u |= (h.u & 0x8000) << 16; // sign bit + return o; +} + +inline float ExpandHalf(uint16_t half) { + FP16 fp16; + fp16.u = half; + FP32 fp = half_to_float_fast5(fp16); + return fp.f; +} + +// More magic code: https://gist.github.com/rygorous/2156668 +inline FP16 float_to_half_fast3(FP32 f) +{ + static const FP32 f32infty = { 255 << 23 }; + static const FP32 f16infty = { 31 << 23 }; + static const FP32 magic = { 15 << 23 }; + static const uint32_t sign_mask = 0x80000000u; + static const uint32_t round_mask = ~0xfffu; + FP16 o = { 0 }; + + uint32_t sign = f.u & sign_mask; + f.u ^= sign; + + if (f.u >= f32infty.u) // Inf or NaN (all exponent bits set) + o.u = (f.u > f32infty.u) ? (0x7e00 | (f.u & 0x3ff)) : 0x7c00; // NaN->qNaN and Inf->Inf + else // (De)normalized number or zero + { + f.u &= round_mask; + f.f *= magic.f; + f.u -= round_mask; + if (f.u > f16infty.u) f.u = f16infty.u; // Clamp to signed infinity if overflowed + + o.u = f.u >> 13; // Take the bits! + } + + o.u |= sign >> 16; + return o; +} + +inline uint16_t ShrinkToHalf(float full) { + FP32 fp32; + fp32.f = full; + FP16 fp = float_to_half_fast3(fp32); + return fp.u; +} + +// FPU control. +void EnableFZ(); + +// Enable both FZ and Default-NaN. Is documented to flip some ARM implementation into a "run-fast" mode +// where they can schedule VFP instructions on the NEON unit (these implementations have +// very slow VFP units). +// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0274h/Babffifj.html +void FPU_SetFastMode(); + + diff --git a/ext/native/midi/CMakeLists.txt b/ext/native/midi/CMakeLists.txt new file mode 100644 index 0000000000..22f0fde28e --- /dev/null +++ b/ext/native/midi/CMakeLists.txt @@ -0,0 +1,12 @@ +set(SRCS + midi_input.cpp +) + +set(SRCS ${SRCS}) + +add_library(midi STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) + diff --git a/ext/native/midi/midi_input.cpp b/ext/native/midi/midi_input.cpp new file mode 100644 index 0000000000..cb11625e19 --- /dev/null +++ b/ext/native/midi/midi_input.cpp @@ -0,0 +1,90 @@ +#ifdef _WIN32 +// Windows implementation. + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include +#include + +#include "base/basictypes.h" +#include "base/logging.h" +#include "midi/midi_input.h" +#include "util/text/utf8.h" + +std::vector MidiInGetDevices() { + int numDevs = midiInGetNumDevs(); + + std::vector devices; + for (int i = 0; i < numDevs; i++) { + MIDIINCAPS caps; + midiInGetDevCaps(i, &caps, sizeof(caps)); + devices.push_back(ConvertWStringToUTF8(caps.szPname)); + } + return devices; +} + +static void CALLBACK MidiCallback(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { + MidiListener *listener = (MidiListener*)dwInstance; + uint8_t cmd[3] = {0}; + + switch (wMsg) { + case MM_MIM_OPEN: + ILOG("Got MIDI Open message"); + break; + case MM_MIM_CLOSE: + ILOG("Got MIDI Close message"); + break; + case MM_MIM_DATA: + cmd[0] = dwParam1 & 0xFF; + cmd[1] = (dwParam1 >> 8) & 0xFF; + cmd[2] = (dwParam1 >> 16) & 0xFF; + // time = dwParam2 & 0xFFFF; + ILOG("Got MIDI Data: %02x %02x %02x", cmd[0], cmd[1], cmd[2]); + listener->midiEvent(cmd); + break; + default: + WLOG("Got unexpected MIDI message: %08x", (uint32_t)wMsg); + break; + } +} + +MidiDevice MidiInStart(int deviceID, MidiListener *listener) { + HMIDIIN hMidiIn; + MMRESULT result = midiInOpen(&hMidiIn, deviceID, (DWORD_PTR)(&MidiCallback), (DWORD_PTR)listener, CALLBACK_FUNCTION); + midiInStart(hMidiIn); + return (MidiDevice)hMidiIn; +} + +void MidiInStop(MidiDevice device) { + HMIDIIN hMidiIn = (HMIDIIN)device; + midiInStop(hMidiIn); + midiInClose(hMidiIn); +} + +#else + +#include +#include + +#include "base/basictypes.h" +#include "base/logging.h" +#include "midi/midi_input.h" + +// Stubs for other platforms. + +std::vector MidiInGetDevices() { + return std::vector(); +} + +MidiDevice MidiInStart(int deviceID, MidiListener *listener) { + FLOG("Invalid MIDI device"); + return 0; +} + +void MidiInStop(MidiDevice device) { + FLOG("Invalid MIDI device"); +} + +#endif \ No newline at end of file diff --git a/ext/native/midi/midi_input.h b/ext/native/midi/midi_input.h new file mode 100644 index 0000000000..acfa3a4eb6 --- /dev/null +++ b/ext/native/midi/midi_input.h @@ -0,0 +1,27 @@ +// MIDI input. +// +// Currently, this is just a platform-clean wrapper around the Win32 MIDI input facilities. +// Thus, it only supports Windows. Other platforms will get an empty list of midi in devices. + +#pragma once + +#include +#include + +#include "base/basictypes.h" + +typedef void *MidiDevice; + +// Listeners inherit from this. Pass them into MidiInStart. +class MidiListener +{ +public: + virtual ~MidiListener() {} + virtual void midiEvent(const uint8_t *cmd) = 0; +}; + +// Gets the names of the devices in a vector. The device identifier is the index in the vector. +std::vector MidiInGetDevices(); + +MidiDevice MidiInStart(int deviceID, MidiListener *listener); +void MidiInStop(MidiDevice device); \ No newline at end of file diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj new file mode 100644 index 0000000000..7fc789350a --- /dev/null +++ b/ext/native/native.vcxproj @@ -0,0 +1,799 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C4DF647E-80EA-4111-A0A8-218B1B711E18} + Win32Proj + native + 8.1 + + + + StaticLibrary + true + Unicode + v140_xp + + + StaticLibrary + true + Unicode + v140_xp + + + StaticLibrary + false + false + Unicode + v140_xp + + + StaticLibrary + false + false + Unicode + v140_xp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\dx9sdk\Include;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\native\ext\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ProgramDatabase + true + false + false + MultiThreadedDebug + + + Windows + true + + + Ws2_32.lib + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\dx9sdk\Include;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\native\ext\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + true + false + false + MultiThreadedDebug + + + Windows + true + + + Ws2_32.lib + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\dx9sdk\Include;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\native\ext\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + StreamingSIMDExtensions2 + Fast + true + false + MultiThreaded + + + Windows + true + true + true + + + Ws2_32.lib + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\dx9sdk\Include;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\native\ext\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + NotSet + Fast + true + false + MultiThreaded + + + Windows + true + true + true + + + Ws2_32.lib + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + + + true + true + true + true + + + + + + + + true + true + true + true + + + true + true + true + true + + + + + + AnySuitable + true + Speed + AnySuitable + Speed + AnySuitable + true + Speed + false + AnySuitable + Speed + false + StreamingSIMDExtensions2 + Fast + StreamingSIMDExtensions2 + Fast + MaxSpeed + MaxSpeed + Default + Default + + + + + + + + + + + + + + + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + AssemblyAndSourceCode + + + + + + + + + + + + + + + + + + + + + + + + + + + AssemblyAndSourceCode + AssemblyAndSourceCode + + + + + + + + diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters new file mode 100644 index 0000000000..c9d424be97 --- /dev/null +++ b/ext/native/native.vcxproj.filters @@ -0,0 +1,916 @@ + + + + + file + + + + base + + + + ext + + + tools + + + ui + + + + ext\libzip + + + math\fast + + + + + gfx + + + image + + + image + + + image + + + image + + + math + + + math + + + math + + + gfx + + + gfx + + + audio + + + audio + + + profiler + + + input + + + file + + + file + + + file + + + file + + + base + + + base + + + base + + + gfx + + + gfx + + + math + + + base + + + base + + + gfx + + + input + + + base + + + ext + + + base + + + gfx + + + json + + + file + + + file + + + gfx + + + base + + + base + + + ui + + + midi + + + file + + + base + + + util + + + data + + + base + + + net + + + base + + + file + + + net + + + android + + + android + + + ui + + + base + + + base + + + base + + + math + + + math + + + util + + + util + + + ui + + + math + + + ui + + + ext + + + gfx + + + util + + + ext + + + ext + + + ext + + + thread + + + thread + + + thread + + + i18n + + + file + + + thread + + + ui + + + ui + + + math + + + net + + + base + + + ui + + + data + + + + math + + + + gfx + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + util + + + ext\jpge + + + ext\jpge + + + ext\vjson + + + ext\vjson + + + gfx + + + math\fast + + + math\fast + + + util + + + util + + + thin3d + + + thin3d + + + + net + + + net + + + thread + + + + + + gfx + + + image + + + image + + + image + + + math + + + math + + + math + + + gfx + + + gfx + + + audio + + + audio + + + profiler + + + file + + + file + + + file + + + gfx + + + gfx + + + base + + + base + + + gfx + + + input + + + ext + + + base + + + gfx + + + json + + + file + + + file + + + gfx + + + base + + + ui + + + midi + + + file + + + util + + + math + + + net + + + base + + + file + + + base + + + net + + + android + + + android + + + android + + + ui + + + base + + + math + + + math + + + util + + + ui + + + math + + + ui + + + + + ext + + + base + + + gfx + + + util + + + ext + + + ext + + + thread + + + thread + + + i18n + + + file + + + thread + + + ui + + + ui + + + net + + + ui + + + data + + + math + + + input + + + gfx + + + util + + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + ext\libzip + + + util + + + ext\jpge + + + ext\jpge + + + ext\vjson + + + ext\vjson + + + gfx + + + math\fast + + + math\fast + + + math\fast + + + thin3d + + + thin3d + + + thin3d + + + thin3d + + + + net + + + net + + + thread + + + + + {9da89505-72a1-40e6-86e5-705372db1608} + + + {828bddaf-63e5-4311-985b-bf377f86ff00} + + + {f3f83007-7c3b-473f-a2f7-423c5087fbfa} + + + {5c54b5e2-1bb2-4783-9df6-de4ff7105570} + + + {4ea45f6c-de87-44a9-95b2-e1ec7e3601d0} + + + {c57b41dd-cc33-46ac-b479-19676455ae54} + + + {4ba4474c-b80f-40da-95e8-2de57eb1b327} + + + {49afd06e-eb44-41ac-b038-e109e444a834} + + + {a52d761c-4c72-4261-be17-50d071bd5cc8} + + + {95e41110-57a2-497f-a938-b4c8e9dd6a27} + + + {cda27e9f-5763-4bf2-b6bc-85a377f7020e} + + + {d738c2d1-749d-4b60-b98f-f3da0bbbf40c} + + + {4710a9a2-d1fa-4920-ba1b-a7527902be53} + + + {e36ca540-863c-496b-b0f4-b1ece3e72feb} + + + {d5fa3d62-88bf-4dc4-9814-28f3c0444e62} + + + {1e85f968-7106-483c-ae7d-77d0ef58d787} + + + {6a548b3d-3a4c-4114-aa2f-0b42bf7bf2ce} + + + {b7bc9a09-29c1-447b-9255-fe0709d10689} + + + {4515306f-4664-46bf-a89b-abfec5520a15} + + + {caa41117-1d90-47cc-9fba-f7e670e315a3} + + + {02e8ef95-82c7-4420-b029-a189a5e0fcbd} + + + {aa8b9b49-2ff8-4961-b6cc-9c33ea674130} + + + {6c47ee5b-0375-40f0-ab2a-402d001cc9c7} + + + {3721adbc-1a4a-4017-bc1d-893c7e86bc22} + + + {c6910d82-73d3-4d97-ac9c-bcc03265b1bc} + + + {5ce64c0e-98e4-4411-86cc-aacaf2f60b21} + + + {06c6305a-a646-485b-85b9-645a24dd6553} + + + diff --git a/ext/native/net/CMakeLists.txt b/ext/native/net/CMakeLists.txt new file mode 100644 index 0000000000..10d69f4d51 --- /dev/null +++ b/ext/native/net/CMakeLists.txt @@ -0,0 +1,11 @@ +set(SRCS + http_client.cpp + resolve.cpp) + +set(SRCS ${SRCS}) + +add_library(net STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp new file mode 100644 index 0000000000..aecee2ae1d --- /dev/null +++ b/ext/native/net/http_client.cpp @@ -0,0 +1,456 @@ +#include "net/http_client.h" +#include "base/timeutil.h" + +#ifndef _WIN32 +#include +#include +#include +#define closesocket close +#else +#include +#include +#include +#endif + +#include +#include + +#include "base/logging.h" +#include "base/buffer.h" +#include "base/stringutil.h" +#include "data/compression.h" +#include "net/resolve.h" +#include "net/url.h" + +namespace net { + +Connection::Connection() + : port_(-1), resolved_(NULL), sock_(-1) { +} + +Connection::~Connection() { + Disconnect(); + if (resolved_ != NULL) + DNSResolveFree(resolved_); +} + +// For whatever crazy reason, htons isn't available on android x86 on the build server. so here we go. + +// TODO: Fix for big-endian +inline unsigned short myhtons(unsigned short x) { + return (x >> 8) | (x << 8); +} + +bool Connection::Resolve(const char *host, int port) { + if ((intptr_t)sock_ != -1) { + ELOG("Resolve: Already have a socket"); + return false; + } + + host_ = host; + port_ = port; + + char port_str[10]; + snprintf(port_str, sizeof(port_str), "%d", port); + + std::string err; + if (!net::DNSResolve(host, port_str, &resolved_, err)) { + ELOG("Failed to resolve host %s: %s", host, err.c_str()); + // So that future calls fail. + port_ = 0; + return false; + } + + return true; +} + +bool Connection::Connect(int maxTries) { + if (port_ <= 0) { + ELOG("Bad port"); + return false; + } + sock_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if ((intptr_t)sock_ == -1) { + ELOG("Bad socket"); + return false; + } + + for (int tries = maxTries; tries > 0; --tries) { + for (addrinfo *possible = resolved_; possible != NULL; possible = possible->ai_next) { + // TODO: Could support ipv6 without huge difficulty... + if (possible->ai_family != AF_INET) + continue; + + int retval = connect(sock_, possible->ai_addr, (int)possible->ai_addrlen); + if (retval >= 0) + return true; + } + sleep_ms(1); + } + + // Let's not leak this socket. + closesocket(sock_); + sock_ = -1; + return false; +} + +void Connection::Disconnect() { + if ((intptr_t)sock_ != -1) { + closesocket(sock_); + sock_ = -1; + } +} + +} // net + +namespace http { + +// TODO: do something sane here +#define USERAGENT "NATIVEAPP 1.0" + +Client::Client() { + httpVersion_ = "1.1"; + userAgent_ = USERAGENT; +} + +Client::~Client() { + Disconnect(); +} + + +void DeChunk(Buffer *inbuffer, Buffer *outbuffer, int contentLength, float *progress) { + int dechunkedBytes = 0; + while (true) { + std::string line; + inbuffer->TakeLineCRLF(&line); + if (!line.size()) + return; + int chunkSize; + sscanf(line.c_str(), "%x", &chunkSize); + if (chunkSize) { + std::string data; + inbuffer->Take(chunkSize, &data); + outbuffer->Append(data); + } else { + // a zero size chunk should mean the end. + inbuffer->clear(); + return; + } + dechunkedBytes += chunkSize; + if (progress && contentLength) { + *progress = (float)dechunkedBytes / contentLength; + } + inbuffer->Skip(2); + } +} + +int Client::GET(const char *resource, Buffer *output, float *progress) { + const char *otherHeaders = + "Accept: */*\r\n" + "Accept-Encoding: gzip\r\n"; + int err = SendRequest("GET", resource, otherHeaders, progress); + if (err < 0) { + return err; + } + + Buffer readbuf; + std::vector responseHeaders; + int code = ReadResponseHeaders(&readbuf, responseHeaders, progress); + if (code < 0) { + return code; + } + + err = ReadResponseEntity(&readbuf, responseHeaders, output, progress); + if (err < 0) { + return err; + } + return code; +} + +int Client::POST(const char *resource, const std::string &data, const std::string &mime, Buffer *output, float *progress) { + char otherHeaders[2048]; + if (mime.empty()) { + snprintf(otherHeaders, sizeof(otherHeaders), "Content-Length: %lld\r\n", (long long)data.size()); + } else { + snprintf(otherHeaders, sizeof(otherHeaders), "Content-Length: %lld\r\nContent-Type: %s\r\n", (long long)data.size(), mime.c_str()); + } + int err = SendRequestWithData("POST", resource, data, otherHeaders, progress); + if (err < 0) { + return err; + } + + Buffer readbuf; + std::vector responseHeaders; + int code = ReadResponseHeaders(&readbuf, responseHeaders, progress); + if (code < 0) { + return code; + } + + err = ReadResponseEntity(&readbuf, responseHeaders, output, progress); + if (err < 0) { + return err; + } + return code; +} + +int Client::POST(const char *resource, const std::string &data, Buffer *output, float *progress) { + return POST(resource, data, "", output, progress); +} + +int Client::SendRequest(const char *method, const char *resource, const char *otherHeaders, float *progress) { + return SendRequestWithData(method, resource, "", otherHeaders, progress); +} + +int Client::SendRequestWithData(const char *method, const char *resource, const std::string &data, const char *otherHeaders, float *progress) { + if (progress) { + *progress = 0.01f; + } + + Buffer buffer; + const char *tpl = + "%s %s HTTP/%s\r\n" + "Host: %s\r\n" + "User-Agent: %s\r\n" + "Connection: close\r\n" + "%s" + "\r\n"; + + buffer.Printf(tpl, + method, resource, httpVersion_, + host_.c_str(), + userAgent_, + otherHeaders ? otherHeaders : ""); + buffer.Append(data); + bool flushed = buffer.FlushSocket(sock()); + if (!flushed) { + return -1; // TODO error code. + } + return 0; +} + +int Client::ReadResponseHeaders(Buffer *readbuf, std::vector &responseHeaders, float *progress) { + // Snarf all the data we can into RAM. A little unsafe but hey. + if (readbuf->Read(sock(), 4096) < 0) { + ELOG("Failed to read HTTP headers :("); + return -1; + } + + // Grab the first header line that contains the http code. + + std::string line; + readbuf->TakeLineCRLF(&line); + + int code; + size_t code_pos = line.find(' '); + if (code_pos != line.npos) { + code_pos = line.find_first_not_of(' ', code_pos); + } + + if (code_pos != line.npos) { + code = atoi(&line[code_pos]); + } else { + return -1; + } + + while (true) { + int sz = readbuf->TakeLineCRLF(&line); + if (!sz) + break; + responseHeaders.push_back(line); + } + + if (responseHeaders.size() == 0) { + return -1; + } + + return code; +} + +int Client::ReadResponseEntity(Buffer *readbuf, const std::vector &responseHeaders, Buffer *output, float *progress) { + bool gzip = false; + bool chunked = false; + int contentLength = 0; + for (std::string line : responseHeaders) { + if (startsWithNoCase(line, "Content-Length:")) { + size_t size_pos = line.find_first_of(' '); + if (size_pos != line.npos) { + size_pos = line.find_first_not_of(' ', size_pos); + } + if (size_pos != line.npos) { + contentLength = atoi(&line[size_pos]); + chunked = false; + } + } else if (startsWithNoCase(line, "Content-Encoding:")) { + // TODO: Case folding... + if (line.find("gzip") != std::string::npos) { + gzip = true; + } + } else if (startsWithNoCase(line, "Transfer-Encoding:")) { + // TODO: Case folding... + if (line.find("chunked") != std::string::npos) { + chunked = true; + } + } + } + + if (!contentLength && progress) { + // Content length is unknown. + // Set progress to 1% so it looks like something is happening... + *progress = 0.1f; + } + + if (!contentLength || !progress) { + // No way to know how far along we are. Let's just not update the progress counter. + if (!readbuf->ReadAll(sock(), contentLength)) + return -1; + } else { + // Let's read in chunks, updating progress between each. + if (!readbuf->ReadAllWithProgress(sock(), contentLength, progress)) + return -1; + } + + // output now contains the rest of the reply. Dechunk it. + if (chunked) { + DeChunk(readbuf, output, contentLength, progress); + } else { + output->Append(*readbuf); + } + + // If it's gzipped, we decompress it and put it back in the buffer. + if (gzip) { + std::string compressed, decompressed; + output->TakeAll(&compressed); + bool result = decompress_string(compressed, &decompressed); + if (!result) { + ELOG("Error decompressing using zlib"); + *progress = 0.0f; + return -1; + } + output->Append(decompressed); + } + + if (progress) { + *progress = 1.0f; + } + return 0; +} + +Download::Download(const std::string &url, const std::string &outfile) + : progress_(0.0f), url_(url), outfile_(outfile), resultCode_(0), completed_(false), failed_(false), cancelled_(false), hidden_(false) { +} + +Download::~Download() { + +} + +void Download::Start(std::shared_ptr self) { + std::thread th(std::bind(&Download::Do, this, self)); + th.detach(); +} + +void Download::SetFailed(int code) { + failed_ = true; + progress_ = 1.0f; + completed_ = true; +} + +void Download::Do(std::shared_ptr self) { + // as long as this is in scope, we won't get destructed. + // yeah this is ugly, I need to think about how life time should be managed for these... + std::shared_ptr self_ = self; + resultCode_ = 0; + + Url fileUrl(url_); + if (!fileUrl.Valid()) { + SetFailed(-1); + return; + } + net::AutoInit netInit; + + http::Client client; + if (!client.Resolve(fileUrl.Host().c_str(), fileUrl.Port())) { + ELOG("Failed resolving %s", url_.c_str()); + SetFailed(-1); + return; + } + + if (cancelled_) { + SetFailed(-1); + return; + } + + if (!client.Connect()) { + ELOG("Failed connecting to server."); + SetFailed(-1); + return; + } + + if (cancelled_) { + SetFailed(-1); + return; + } + + // TODO: Allow cancelling during a GET somehow... + int resultCode = client.GET(fileUrl.Resource().c_str(), &buffer_, &progress_); + if (resultCode == 200) { + ILOG("Completed downloading %s to %s", url_.c_str(), outfile_.empty() ? "memory" : outfile_.c_str()); + if (!outfile_.empty() && !buffer_.FlushToFile(outfile_.c_str())) { + ELOG("Failed writing download to %s", outfile_.c_str()); + } + } else { + ELOG("Error downloading %s to %s: %i", url_.c_str(), outfile_.c_str(), resultCode); + } + + resultCode_ = resultCode; + progress_ = 1.0f; + + // Set this last to ensure no race conditions when checking Done. Users must always check + // Done before looking at the result code. + completed_ = true; +} + +std::shared_ptr Downloader::StartDownload(const std::string &url, const std::string &outfile) { + std::shared_ptr dl(new Download(url, outfile)); + downloads_.push_back(dl); + dl->Start(dl); + return dl; +} + +std::shared_ptr Downloader::StartDownloadWithCallback( + const std::string &url, + const std::string &outfile, + std::function callback) { + std::shared_ptr dl(new Download(url, outfile)); + dl->SetCallback(callback); + downloads_.push_back(dl); + dl->Start(dl); + return dl; +} + +void Downloader::Update() { + restart: + for (size_t i = 0; i < downloads_.size(); i++) { + if (downloads_[i]->Progress() == 1.0f || downloads_[i]->Failed()) { + downloads_[i]->RunCallback(); + downloads_.erase(downloads_.begin() + i); + goto restart; + } + } +} + +std::vector Downloader::GetCurrentProgress() { + std::vector progress; + for (size_t i = 0; i < downloads_.size(); i++) { + if (!downloads_[i]->IsHidden()) + progress.push_back(downloads_[i]->Progress()); + } + return progress; +} + +void Downloader::CancelAll() { + for (size_t i = 0; i < downloads_.size(); i++) { + downloads_[i]->Cancel(); + } +} + +} // http diff --git a/ext/native/net/http_client.h b/ext/native/net/http_client.h new file mode 100644 index 0000000000..34c03c2ffa --- /dev/null +++ b/ext/native/net/http_client.h @@ -0,0 +1,167 @@ +#ifndef _NET_HTTP_HTTP_CLIENT +#define _NET_HTTP_HTTP_CLIENT + +#include +#include "base/basictypes.h" +#include "base/buffer.h" +#include "thread/thread.h" +#include "base/functional.h" + +#ifdef _WIN32 +#define NOMINMAX +#include +#else +#include +#include +#include +#include +#endif + +namespace net { + +class Connection { +public: + Connection(); + virtual ~Connection(); + + // Inits the sockaddr_in. + bool Resolve(const char *host, int port); + + bool Connect(int maxTries = 2); + void Disconnect(); + + // Only to be used for bring-up and debugging. + uintptr_t sock() const { return sock_; } + +protected: + // Store the remote host here, so we can send it along through HTTP/1.1 requests. + // TODO: Move to http::client? + std::string host_; + int port_; + + addrinfo *resolved_; + +private: + uintptr_t sock_; + +}; + +} // namespace net + +namespace http { + +class Client : public net::Connection { +public: + Client(); + ~Client(); + + // Return value is the HTTP return code. 200 means OK. < 0 means some local error. + int GET(const char *resource, Buffer *output, float *progress = nullptr); + + // Return value is the HTTP return code. + int POST(const char *resource, const std::string &data, const std::string &mime, Buffer *output, float *progress = nullptr); + int POST(const char *resource, const std::string &data, Buffer *output, float *progress = nullptr); + + // HEAD, PUT, DELETE aren't implemented yet, but can be done with SendRequest. + + int SendRequest(const char *method, const char *resource, const char *otherHeaders = nullptr, float *progress = nullptr); + int SendRequestWithData(const char *method, const char *resource, const std::string &data, const char *otherHeaders = nullptr, float *progress = nullptr); + int ReadResponseHeaders(Buffer *readbuf, std::vector &responseHeaders, float *progress = nullptr); + // If your response contains a response, you must read it. + int ReadResponseEntity(Buffer *readbuf, const std::vector &responseHeaders, Buffer *output, float *progress = nullptr); + + const char *userAgent_; + const char *httpVersion_; +}; + +// Not particularly efficient, but hey - it's a background download, that's pretty cool :P +class Download { +public: + Download(const std::string &url, const std::string &outfile); + ~Download(); + + // Keeps around an instance of the shared_ptr, so that it doesn't get destructed + // until done. + void Start(std::shared_ptr self); + + // Returns 1.0 when done. That one value can be compared exactly - or just use Done(). + float Progress() const { return progress_; } + + bool Done() const { return completed_; } + bool Failed() const { return failed_; } + + // NOTE! The value of ResultCode is INVALID until Done() returns true. + int ResultCode() const { return resultCode_; } + + std::string url() const { return url_; } + std::string outfile() const { return outfile_; } + + // If not downloading to a file, access this to get the result. + Buffer &buffer() { return buffer_; } + const Buffer &buffer() const { return buffer_; } + + void Cancel() { + cancelled_ = true; + } + + // NOTE: Callbacks are NOT executed until RunCallback is called. This is so that + // the call will end up on the thread that calls g_DownloadManager.Update(). + void SetCallback(std::function callback) { + callback_ = callback; + } + void RunCallback() { + if (callback_) { + callback_(*this); + } + } + + // Just metadata. Convenient for download managers, for example, if set, + // Downloader::GetCurrentProgress won't return it in the results. + bool IsHidden() const { return hidden_; } + void SetHidden(bool hidden) { hidden_ = hidden; } + +private: + void Do(std::shared_ptr self); // Actually does the download. Runs on thread. + void SetFailed(int code); + float progress_; + Buffer buffer_; + std::string url_; + std::string outfile_; + int resultCode_; + bool completed_; + bool failed_; + volatile bool cancelled_; + bool hidden_; + std::function callback_; +}; + +using std::shared_ptr; + +class Downloader { +public: + ~Downloader() { + CancelAll(); + } + + std::shared_ptr StartDownload(const std::string &url, const std::string &outfile); + + std::shared_ptr StartDownloadWithCallback( + const std::string &url, + const std::string &outfile, + std::function callback); + + // Drops finished downloads from the list. + void Update(); + void CancelAll(); + + std::vector GetCurrentProgress(); + +private: + std::vector> downloads_; +}; + + +} // http + +#endif // _NET_HTTP_HTTP_CLIENT + diff --git a/ext/native/net/http_headers.cpp b/ext/native/net/http_headers.cpp new file mode 100644 index 0000000000..0fdf628d3f --- /dev/null +++ b/ext/native/net/http_headers.cpp @@ -0,0 +1,154 @@ +#include "net/http_headers.h" + +#include +#include + +#include "base/logging.h" +#include "base/stringutil.h" +#include "file/fd_util.h" + +namespace http { + +RequestHeader::RequestHeader() + : status(200), referer(0), user_agent(0), + resource(0), params(0), content_length(-1), first_header_(true) { +} + +RequestHeader::~RequestHeader() { + delete [] referer; + delete [] user_agent; + delete [] resource; + delete [] params; +} + +bool RequestHeader::GetParamValue(const char *param_name, std::string *value) const { + if (!params) + return false; + std::string p(params); + std::vector v; + SplitString(p, '&', v); + for (size_t i = 0; i < v.size(); i++) { + std::vector parts; + SplitString(v[i], '=', parts); + ILOG("Param: %s Value: %s", parts[0].c_str(), parts[1].c_str()); + if (parts[0] == param_name) { + *value = parts[1]; + return true; + } + } + return false; +} + +// Intended to be a mad fast parser. It's not THAT fast currently, there's still +// things to optimize, but meh. +int RequestHeader::ParseHttpHeader(const char *buffer) { + if (first_header_) { + // Step 1: Method + first_header_ = false; + if (!memcmp(buffer, "GET ", 4)) { + method = GET; + buffer += 4; + } else if (!memcmp(buffer, "HEAD ", 5)) { + method = HEAD; + buffer += 5; + } else if (!memcmp(buffer, "POST ", 5)) { + method = POST; + buffer += 5; + } else { + method = UNSUPPORTED; + status = 501; + return -1; + } + SkipSpace(&buffer); + + // Step 2: Resource, params (what's after the ?, if any) + const char *endptr = strchr(buffer, ' '); + const char *q_ptr = strchr(buffer, '?'); + + int resource_name_len; + if (q_ptr) + resource_name_len = q_ptr - buffer; + else + resource_name_len = endptr - buffer; + if (!resource_name_len) { + status = 400; + return -1; + } + resource = new char[resource_name_len + 1]; + memcpy(resource, buffer, resource_name_len); + resource[resource_name_len] = '\0'; + if (q_ptr) { + int param_length = endptr - q_ptr - 1; + params = new char[param_length + 1]; + memcpy(params, q_ptr + 1, param_length); + params[param_length] = '\0'; + } + if (strstr(buffer, "HTTP/")) + type = FULL; + else + type = SIMPLE; + return 0; + } + + // We have a real header to parse. + const char *colon = strchr(buffer, ':'); + if (!colon) { + status = 400; + return -1; + } + + // The header is formatted as key: value. + int key_len = colon - buffer; + char *key = new char[key_len + 1]; + strncpy(key, buffer, key_len); + key[key_len] = 0; + StringUpper(key, key_len); + + // Go to after the colon to get the value. + buffer = colon + 1; + SkipSpace(&buffer); + int value_len = (int)strlen(buffer); + + if (!strcmp(key, "USER-AGENT")) { + user_agent = new char[value_len + 1]; + memcpy(user_agent, buffer, value_len + 1); + ILOG("user-agent: %s", user_agent); + } else if (!strcmp(key, "REFERER")) { + referer = new char[value_len + 1]; + memcpy(referer, buffer, value_len + 1); + } else if (!strcmp(key, "CONTENT-LENGTH")) { + content_length = atoi(buffer); + ILOG("Content-Length: %i", (int)content_length); + } + + delete [] key; + return 0; +} + +void RequestHeader::ParseHeaders(int fd) { + int line_count = 0; + // Loop through request headers. + while (true) { + if (!fd_util::WaitUntilReady(fd, 5.0)) { // Wait max 5 secs. + // Timed out or error. + ok = false; + return; + } + char buffer[1024]; + fd_util::ReadLine(fd, buffer, 1023); + StringTrimEndNonAlphaNum(buffer); + if (buffer[0] == '\0') + break; + ParseHttpHeader(buffer); + line_count++; + if (type == SIMPLE) { + // Done! + ILOG("Simple: Done parsing http request."); + break; + } + } + ILOG("finished parsing request."); + ok = line_count > 1; +} + +} // namespace http diff --git a/ext/native/net/http_headers.h b/ext/native/net/http_headers.h new file mode 100644 index 0000000000..d333e1f91a --- /dev/null +++ b/ext/native/net/http_headers.h @@ -0,0 +1,43 @@ +#ifndef _NET_HTTP_HTTP_HEADERS +#define _NET_HTTP_HTTP_HEADERS + +#include "base/buffer.h" + +namespace http { + +class RequestHeader { + public: + RequestHeader(); + ~RequestHeader(); + // Public variables since it doesn't make sense + // to bother with accessors for all these. + int status; + char *referer; + char *user_agent; + char *resource; + char *params; + int content_length; + enum RequestType { + SIMPLE, FULL, + }; + RequestType type; + enum Method { + GET, + HEAD, + POST, + UNSUPPORTED, + }; + Method method; + bool ok; + void ParseHeaders(int fd); + bool GetParamValue(const char *param_name, std::string *value) const; + private: + int ParseHttpHeader(const char *buffer); + bool first_header_; + + DISALLOW_COPY_AND_ASSIGN(RequestHeader); +}; + +} // namespace http + +#endif diff --git a/ext/native/net/http_server.cpp b/ext/native/net/http_server.cpp new file mode 100644 index 0000000000..a61c625aca --- /dev/null +++ b/ext/native/net/http_server.cpp @@ -0,0 +1,168 @@ +#include "base/timeutil.h" + +#ifdef _WIN32 + +#include +#include +#include + +#else + +#include /* socket definitions */ +#include /* socket types */ +#include /* for waitpid() */ +#include /* struct sockaddr_in */ +#include /* inet (3) funtions */ +#include /* misc. UNIX functions */ + +#endif + +#include +#include + +#include "base/functional.h" +#include "base/logging.h" +#include "base/buffer.h" +#include "file/fd_util.h" +#include "net/http_server.h" + +namespace http { + +Request::Request(int fd) + : fd_(fd) { + in_buffer_ = new Buffer; + out_buffer_ = new Buffer; + header_.ParseHeaders(fd_); + + if (header_.ok) { + // Read the rest, too. + if (header_.content_length >= 0) { + in_buffer_->Read(fd_, header_.content_length); + } + ILOG("The request carried with it %i bytes", (int)in_buffer_->size()); + } else { + Close(); + } +} + +Request::~Request() { + Close(); + + CHECK(in_buffer_->empty()); + delete in_buffer_; + CHECK(out_buffer_->empty()); + delete out_buffer_; +} + +void Request::WriteHttpResponseHeader(int status, int size) const { + Buffer *buffer = out_buffer_; + buffer->Printf("HTTP/1.0 %d OK\r\n", status); + buffer->Append("Server: SuperDuperServer v0.1\r\n"); + buffer->Append("Content-Type: text/html\r\n"); + if (size >= 0) { + buffer->Printf("Content-Length: %i\r\n", size); + } + buffer->Append("\r\n"); +} + +void Request::WritePartial() const { + CHECK(fd_); + out_buffer_->Flush(fd_); +} + +void Request::Write() { + CHECK(fd_); + WritePartial(); + Close(); +} + +void Request::Close() { + if (fd_) { + close(fd_); + fd_ = 0; + } +} + +Server::Server(threading::Executor *executor) + : port_(0), executor_(executor) { + RegisterHandler("/", std::bind(&Server::HandleListing, this, placeholder::_1)); +} + +void Server::RegisterHandler(const char *url_path, UrlHandlerFunc handler) { + handlers_[std::string(url_path)] = handler; +} + +bool Server::Run(int port) { + ILOG("HTTP server started on port %i", port); + port_ = port; + + int listener = socket(AF_INET, SOCK_STREAM, 0); + CHECK_GE(listener, 0); + + struct sockaddr_in server_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + server_addr.sin_port = htons(port); + + int opt = 1; + // Enable re-binding to avoid the pain when restarting the server quickly. + setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)); + + if (bind(listener, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + ELOG("Failed to bind to port %i. Bailing.", port); + return false; + } + + // 1024 is the max number of queued requests. + CHECK_GE(listen(listener, 1024), 0); + while (true) { + sockaddr client_addr; + socklen_t client_addr_size = sizeof(client_addr); + int conn_fd = accept(listener, &client_addr, &client_addr_size); + if (conn_fd >= 0) { + executor_->Run(std::bind(&Server::HandleConnection, this, conn_fd)); + } else { + FLOG("socket accept failed: %i", conn_fd); + } + } + + // We'll never get here. Ever. + return true; +} + +void Server::HandleConnection(int conn_fd) { + Request request(conn_fd); + if (!request.IsOK()) { + WLOG("Bad request, ignoring."); + return; + } + HandleRequestDefault(request); + request.WritePartial(); +} + +void Server::HandleRequest(const Request &request) { + HandleRequestDefault(request); +} + +void Server::HandleRequestDefault(const Request &request) { + // First, look through all handlers. If we got one, use it. + for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter) { + if (iter->first == request.resource()) { + (iter->second)(request); + return; + } + } + ILOG("No handler for '%s', falling back to 404.", request.resource()); + const char *payload = "404 not found\r\n"; + request.WriteHttpResponseHeader(404, (int)strlen(payload)); + request.out_buffer()->Append(payload); +} + +void Server::HandleListing(const Request &request) { + for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter) { + request.out_buffer()->Printf("%s", iter->first.c_str()); + } +} + +} // namespace http diff --git a/ext/native/net/http_server.h b/ext/native/net/http_server.h new file mode 100644 index 0000000000..5d45722671 --- /dev/null +++ b/ext/native/net/http_server.h @@ -0,0 +1,88 @@ +#ifndef _HTTP_SERVER_H +#define _HTTP_SERVER_H + +#include + +#include "base/functional.h" +#include "base/buffer.h" +#include "net/http_headers.h" +#include "thread/executor.h" + +namespace http { + +class Request { + public: + Request(int fd); + ~Request(); + + const char *resource() const { + return header_.resource; + } + + bool GetParamValue(const char *param_name, std::string *value) const { + return header_.GetParamValue(param_name, value); + } + + Buffer *in_buffer() const { return in_buffer_; } + Buffer *out_buffer() const { return out_buffer_; } + + // TODO: Remove, in favor of PartialWrite and friends. + int fd() const { return fd_; } + + void WritePartial() const; + void Write(); + void Close(); + + bool IsOK() const { return fd_ > 0; } + + // If size is negative, no Content-Length: line is written. + void WriteHttpResponseHeader(int status, int size = -1) const; + + private: + Buffer *in_buffer_; + Buffer *out_buffer_; + RequestHeader header_; + int fd_; +}; + +// Register handlers on this class to serve stuff. +class Server { + public: + Server(threading::Executor *executor); + + typedef std::function UrlHandlerFunc; + typedef std::map UrlHandlerMap; + + // Runs forever, serving request. If you want to do something else than serve pages, + // better put this on a thread. Returns false if failed to start serving, never + // returns if successful. + bool Run(int port); + + void RegisterHandler(const char *url_path, UrlHandlerFunc handler); + + // If you want to customize things at a lower level than just a simple path handler, + // then inherit and override this. Implementations should forward to HandleRequestDefault + // if they don't recognize the url. + virtual void HandleRequest(const Request &request); + + private: + void HandleConnection(int conn_fd); + + void GetRequest(Request *request); + + // Things like default 404, etc. + void HandleRequestDefault(const Request &request); + + // Neat built-in handlers that are tied to the server. + void HandleListing(const Request &request); + + int port_; + + UrlHandlerMap handlers_; + + threading::Executor *executor_; +}; + +} // namespace http + +#endif // _HTTP_SERVER_H diff --git a/ext/native/net/resolve.cpp b/ext/native/net/resolve.cpp new file mode 100644 index 0000000000..fd6a774c8c --- /dev/null +++ b/ext/native/net/resolve.cpp @@ -0,0 +1,196 @@ +#include "net/resolve.h" +#include "base/logging.h" +#include "base/timeutil.h" + +#include +#include +#include +#include + + +#ifdef _WIN32 +#include +#include +#undef min +#undef max +#else +#include +#include +#include +#include +#include +#endif + + +namespace net { + +void Init() +{ +#ifdef _WIN32 + // WSA does its own internal reference counting, no need to keep track of if we inited or not. + WSADATA wsaData = {0}; + WSAStartup(MAKEWORD(2, 2), &wsaData); +#endif +} + +void Shutdown() +{ +#ifdef _WIN32 + WSACleanup(); +#endif +} + +char *DNSResolveTry(const char *host, const char **err) +{ + struct hostent *hent; + if((hent = gethostbyname(host)) == NULL) + { + *err = "Can't get IP"; + return NULL; + } + int iplen = 15; //XXX.XXX.XXX.XXX + char *ip = (char *)malloc(iplen+1); + memset(ip, 0, iplen+1); + char *iptoa = inet_ntoa(*(in_addr *)hent->h_addr_list[0]); + if (iptoa == NULL) + { + *err = "Can't resolve host"; + free(ip); + return NULL; + } + strncpy(ip, iptoa, iplen); + return ip; +} + +char *DNSResolve(const char *host) +{ + const char *err; + char *ip = DNSResolveTry(host, &err); + if (ip == NULL) + { + perror(err); + exit(1); + } + return ip; +} + +bool DNSResolve(const std::string &host, const std::string &service, addrinfo **res, std::string &error) +{ + addrinfo hints = {0}; + // TODO: Might be uses to lookup other values. + hints.ai_socktype = SOCK_STREAM; +#ifdef BLACKBERRY + hints.ai_flags = 0; +#elif ANDROID + hints.ai_flags = AI_ADDRCONFIG; +#else + // AI_V4MAPPED seems to have issues on some platforms, not sure we should include it: + // http://stackoverflow.com/questions/1408030/what-is-the-purpose-of-the-ai-v4mapped-flag-in-getaddrinfo + hints.ai_flags = /*AI_V4MAPPED |*/ AI_ADDRCONFIG; +#endif + hints.ai_protocol = IPPROTO_TCP; + + const char *servicep = service.length() == 0 ? NULL : service.c_str(); + + *res = NULL; + int result = getaddrinfo(host.c_str(), servicep, &hints, res); + if (result == EAI_AGAIN) { + // Temporary failure. Since this already blocks, let's just try once more. + sleep_ms(1); + result = getaddrinfo(host.c_str(), servicep, &hints, res); + } + + if (result != 0) { +#ifdef _WIN32 + error = gai_strerrorA(result); +#else + error = gai_strerror(result); +#endif + if (*res != NULL) + freeaddrinfo(*res); + *res = NULL; + return false; + } + + return true; +} + +void DNSResolveFree(addrinfo *res) +{ + if (res != NULL) + freeaddrinfo(res); +} + +int inet_pton(int af, const char* src, void* dst) +{ + if (af == AF_INET) + { + unsigned char *ip = (unsigned char *)dst; + int k = 0, x = 0; + char ch; + for (int i = 0; (ch = src[i]) != 0; i++) + { + if (ch == '.') + { + ip[k++] = x; + if (k == 4) + return 0; + x = 0; + } + else if (ch < '0' || ch > '9') + return 0; + else + x = x * 10 + ch - '0'; + if (x > 255) + return 0; + } + ip[k++] = x; + if (k != 4) + return 0; + } + else if (af == AF_INET6) + { + unsigned short* ip = ( unsigned short* )dst; + int i; + for (i = 0; i < 8; i++) ip[i] = 0; + int k = 0; + unsigned int x = 0; + char ch; + int marknum = 0; + for (i = 0; src[i] != 0; i++) + { + if (src[i] == ':') + marknum++; + } + for (i = 0; (ch = src[i]) != 0; i++) + { + if (ch == ':') + { + x = ((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8); + ip[k++] = x; + if (k == 8) + return 0; + x = 0; + if (i > 0 && src[i - 1] == ':') + k += 7 - marknum; + } + else if (ch >= '0' && ch <= '9') + x = x * 16 + ch - '0'; + else if (ch >= 'a' && ch <= 'f') + x = x * 16 + ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + x = x * 16 + ch - 'A' + 10; + else + return 0; + if (x > 0xFFFF) + return 0; + } + x = ((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8); + ip[k++] = x; + if (k != 8) + return 0; + } + return 1; +} + +} diff --git a/ext/native/net/resolve.h b/ext/native/net/resolve.h new file mode 100644 index 0000000000..7de2c1c66f --- /dev/null +++ b/ext/native/net/resolve.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +struct addrinfo; + +namespace net { + +// Strictly only required on Win32, but all platforms should call it. +void Init(); +void Shutdown(); + +struct AutoInit { + AutoInit() { + Init(); + } + ~AutoInit() { + Shutdown(); + } +}; + +// use free() to free the returned string. +char *DNSResolveTry(const char *host, const char **err); +char *DNSResolve(const char *host); + +bool DNSResolve(const std::string &host, const std::string &service, addrinfo **res, std::string &error); +void DNSResolveFree(addrinfo *res); + +int inet_pton(int af, const char* src, void* dst); +} // namespace net diff --git a/ext/native/net/url.cpp b/ext/native/net/url.cpp new file mode 100644 index 0000000000..522adc6709 --- /dev/null +++ b/ext/native/net/url.cpp @@ -0,0 +1,157 @@ +#include "base/logging.h" +#include "net/url.h" + +const char *UrlEncoder::unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"; +const char *UrlEncoder::hexChars = "0123456789ABCDEF"; + +int MultipartFormDataEncoder::seq = 0; + +void Url::Split() { + size_t colonSlashSlash = url_.find("://"); + if (colonSlashSlash == std::string::npos) { + ELOG("Invalid URL: %s", url_.c_str()); + return; + } + + protocol_ = url_.substr(0, colonSlashSlash); + + size_t sep = url_.find('/', colonSlashSlash + 3); + + host_ = url_.substr(colonSlashSlash + 3, sep - colonSlashSlash - 3); + resource_ = url_.substr(sep); // include the slash! + + size_t portsep = host_.find(':'); + if (portsep != host_.npos) { + port_ = atoi(host_.substr(portsep + 1).c_str()); + host_ = host_.substr(0, portsep); + } else { + port_ = protocol_ == "https" ? 443 : 80; + } + + valid_ = protocol_.size() > 1 && host_.size() > 1; +} + +// UriDecode and UriEncode are from http://www.codeguru.com/cpp/cpp/string/conversions/print.php/c12759 +// by jinq0123 (November 2, 2006) + +// Uri encode and decode. +// RFC1630, RFC1738, RFC2396 + +// Some compilers don't like to assume (int)-1 will safely cast to (char)-1 as +// the MSBs aren't 0's. Workaround the issue while maintaining table spacing. +#define N1 (char)-1 +const char HEX2DEC[256] = +{ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 1 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 2 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,N1,N1, N1,N1,N1,N1, + + /* 4 */ N1,10,11,12, 13,14,15,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 5 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 6 */ N1,10,11,12, 13,14,15,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 7 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + + /* 8 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 9 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* A */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* B */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + + /* C */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* D */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* E */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* F */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1 +}; + +std::string UriDecode(const std::string & sSrc) +{ + // Note from RFC1630: "Sequences which start with a percent sign + // but are not followed by two hexadecimal characters (0-9, A-F) are reserved + // for future extension" + + const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); + const size_t SRC_LEN = sSrc.length(); + const unsigned char * const SRC_END = pSrc + SRC_LEN; + const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%' + + char * const pStart = new char[SRC_LEN]; + char * pEnd = pStart; + + while (pSrc < SRC_LAST_DEC) + { + if (*pSrc == '%') + { + char dec1, dec2; + if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)]) + && -1 != (dec2 = HEX2DEC[*(pSrc + 2)])) + { + *pEnd++ = (dec1 << 4) + dec2; + pSrc += 3; + continue; + } + } + + *pEnd++ = *pSrc++; + } + + // the last 2- chars + while (pSrc < SRC_END) + *pEnd++ = *pSrc++; + + std::string sResult(pStart, pEnd); + delete [] pStart; + return sResult; +} + +// Only alphanum is safe. +const char SAFE[256] = +{ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, + + /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, + /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, + /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, + /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, + + /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + + /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 +}; + +std::string UriEncode(const std::string & sSrc) +{ + const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; + const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); + const size_t SRC_LEN = sSrc.length(); + unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; + unsigned char * pEnd = pStart; + const unsigned char * const SRC_END = pSrc + SRC_LEN; + + for (; pSrc < SRC_END; ++pSrc) + { + if (SAFE[*pSrc]) + *pEnd++ = *pSrc; + else + { + // escape this char + *pEnd++ = '%'; + *pEnd++ = DEC2HEX[*pSrc >> 4]; + *pEnd++ = DEC2HEX[*pSrc & 0x0F]; + } + } + + std::string sResult((char *)pStart, (char *)pEnd); + delete [] pStart; + return sResult; +} diff --git a/ext/native/net/url.h b/ext/native/net/url.h new file mode 100644 index 0000000000..dedf44c7db --- /dev/null +++ b/ext/native/net/url.h @@ -0,0 +1,197 @@ +#pragma once + +#include +#include +#include +#include + +#include "base/basictypes.h" + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#undef snprintf +#define snprintf _snprintf +#endif + +struct UrlEncoder +{ + UrlEncoder() : paramCount(0) + { + data.reserve(256); + } + + virtual void Add(const std::string &key, const std::string &value) + { + if (++paramCount > 1) + data += '&'; + AppendEscaped(key); + data += '='; + AppendEscaped(value); + } + + void Add(const std::string &key, const char *value) + { + Add(key, std::string(value)); + } + + void Add(const std::string &key, const int value) + { + AddT(key, "%d", value); + } + + void Add(const std::string &key, const uint32_t value) + { + AddT(key, "%u", value); + } + + void Add(const std::string &key, const uint64_t value) + { + AddT(key, "%llu", value); + } + + void Add(const std::string &key, const double value) + { + AddT(key, "%f", value); + } + + void Add(const std::string &key, const bool value) + { + Add(key, value ? "true" : "false"); + } + + virtual void Finish() + { + } + + const std::string &ToString() const + { + return data; + } + + virtual std::string GetMimeType() const + { + return "application/x-www-form-urlencoded"; + } + +protected: + template + void AddT(const std::string &key, const char *fmt, const T value) + { + char temp[64]; + snprintf(temp, sizeof(temp), fmt, value); + temp[sizeof(temp) - 1] = '\0'; + Add(key, temp); + } + + // Percent encoding, aka application/x-www-form-urlencoded. + void AppendEscaped(const std::string &value) + { + for (size_t lastEnd = 0; lastEnd < value.length(); ) + { + size_t pos = value.find_first_not_of(unreservedChars, lastEnd); + if (pos == value.npos) + { + data += value.substr(lastEnd); + break; + } + + if (pos != lastEnd) + data += value.substr(lastEnd, pos - lastEnd); + lastEnd = pos; + + // Encode the reserved character. + char c = value[pos]; + data += '%'; + data += hexChars[(c >> 4) & 15]; + data += hexChars[(c >> 0) & 15]; + ++lastEnd; + } + } + + std::string data; + int paramCount; + static const char *unreservedChars; + static const char *hexChars; +}; + + +// Stores everything in memory, not super efficient. +// Easy to swap out for a UrlEncoder. +struct MultipartFormDataEncoder : UrlEncoder +{ + MultipartFormDataEncoder() : UrlEncoder() + { + data.reserve(8192); + int r1 = rand(); + int r2 = rand(); + char temp[256]; + snprintf(temp, sizeof(temp), "NATIVE-DATA-BOUNDARY-%08x%08x-%d", r1, r2, seq++); + boundary = temp; + } + + virtual void Add(const std::string &key, const std::string &value) + { + Add(key, value, "", ""); + } + + void Add(const std::string &key, const std::string &value, const std::string &filename, const std::string &mimeType) + { + data += "--" + boundary + "\r\n"; + data += "Content-Disposition: form-data; name=\"" + key + "\""; + if (!filename.empty()) + data += "; filename=\"" + filename + "\""; + data += "\r\n"; + if (!mimeType.empty()) + data += "Content-Type: " + mimeType + "\r\n"; + char temp[64]; + snprintf(temp, sizeof(temp), "Content-Length: %d\r\n", (int)value.size()); + data += temp; + data += "\r\n"; + + data += value; + data += "\r\n"; + } + + virtual void Finish() + { + data += "--" + boundary + "--"; + } + + virtual std::string GetMimeType() const + { + return "multipart/form-data; boundary=\"" + boundary + "\""; + } + +protected: + std::string boundary; + + static int seq; +}; + + +class Url { +public: + Url(const std::string url) : valid_(false), url_(url) { + Split(); + } + + bool Valid() const { return valid_; } + + // Host = Hostname:Port, or just Hostname. + std::string Host() const { return host_; } + int Port() const { return port_; } + std::string Protocol() const { return protocol_; } + std::string Resource() const { return resource_; } + +private: + void Split(); + bool valid_; + std::string url_; + std::string host_; + std::string resource_; + std::string protocol_; + int port_; +}; + + +std::string UriDecode(const std::string & sSrc); +std::string UriEncode(const std::string & sSrc); diff --git a/ext/native/profiler/CMakeLists.txt b/ext/native/profiler/CMakeLists.txt new file mode 100644 index 0000000000..f3f9673dac --- /dev/null +++ b/ext/native/profiler/CMakeLists.txt @@ -0,0 +1,11 @@ +set(SRCS + profiler.cpp +) + +# LGUIFileList.cpp + +add_library(profiler STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) diff --git a/ext/native/profiler/profiler.cpp b/ext/native/profiler/profiler.cpp new file mode 100644 index 0000000000..f21200a18b --- /dev/null +++ b/ext/native/profiler/profiler.cpp @@ -0,0 +1,180 @@ +// Ultra-lightweight category profiler with history. + +#include +#include +#include + +#include + +#include "base/logging.h" +#include "base/timeutil.h" +#include "gfx_es2/draw_buffer.h" +#include "profiler/profiler.h" + +#define MAX_CATEGORIES 32 // Can be any number +#define MAX_DEPTH 16 // Can be any number +#define HISTORY_SIZE 256 // Must be power of 2 + +#ifndef _DEBUG +// If the compiler can collapse identical strings, we don't even need the strcmp. +#define UNIFIED_CONST_STR +#endif + +struct Category { + const char *name; +}; + +struct CategoryFrame { + CategoryFrame() { + memset(time_taken, 0, sizeof(time_taken)); + } + float time_taken[MAX_CATEGORIES]; + int count[MAX_CATEGORIES]; +}; + +struct Profiler { + int frameCount; + int historyPos; + int depth; + int parentCategory[MAX_DEPTH]; + double eventStart[MAX_CATEGORIES]; + double curFrameStart; +}; + +static Profiler profiler; +static Category categories[MAX_CATEGORIES]; +static CategoryFrame *history; + +void internal_profiler_init() { + memset(&profiler, 0, sizeof(profiler)); + for (int i = 0; i < MAX_DEPTH; i++) { + profiler.parentCategory[i] = -1; + } + history = new CategoryFrame[HISTORY_SIZE]; +} + +int internal_profiler_find_cat(const char *category_name) { + int i; + for (i = 0; i < MAX_CATEGORIES; i++) { + const char *catname = categories[i].name; + if (!catname) + break; +#ifdef UNIFIED_CONST_STR + if (catname == category_name) { +#else + if (!strcmp(catname, category_name)) { +#endif + return i; + } + } + + if (i < MAX_CATEGORIES && category_name) { + categories[i].name = category_name; + return i; + } + + return -1; +} + +// Suspend, also used to prepare for leaving. +static void internal_profiler_suspend(int category, double now) { + double diff = now - profiler.eventStart[category]; + history[profiler.historyPos].time_taken[category] += (float)diff; + profiler.eventStart[category] = 0.0; +} + +// Resume, also used as part of entering. +static void internal_profiler_resume(int category, double now) { + profiler.eventStart[category] = now; +} + +int internal_profiler_enter(const char *category_name) { + int category = internal_profiler_find_cat(category_name); + if (category == -1 || !history) { + return category; + } + + if (profiler.eventStart[category] == 0.0f) { + double now = real_time_now(); + int parent = profiler.parentCategory[profiler.depth]; + // Temporarily suspend the parent on entering a child. + if (parent != -1) { + internal_profiler_suspend(parent, now); + } + internal_profiler_resume(category, now); + } else { + DLOG("profiler: recursive enter (%i - %s)", category, category_name); + } + + profiler.depth++; + profiler.parentCategory[profiler.depth] = category; + + return category; +} + +void internal_profiler_leave(int category) { + if (category == -1 || !history) { + return; + } + if (category < 0 || category >= MAX_CATEGORIES) { + ELOG("Bad category index %d", category); + profiler.depth--; + return; + } + + double now = real_time_now(); + + profiler.depth--; + if (profiler.depth < 0) { + FLOG("Profiler enter/leave mismatch!"); + } + + int parent = profiler.parentCategory[profiler.depth]; + // When there's recursion, we don't suspend or resume. + if (parent != category) { + internal_profiler_suspend(category, now); + history[profiler.historyPos].count[category]++; + + if (parent != -1) { + // Resume tracking the parent. + internal_profiler_resume(parent, now); + } + } +} + +void internal_profiler_end_frame() { + if (profiler.depth != 0) { + FLOG("Can't be inside a profiler scope at end of frame!"); + } + profiler.curFrameStart = real_time_now(); + profiler.historyPos++; + profiler.historyPos &= (HISTORY_SIZE - 1); + memset(&history[profiler.historyPos], 0, sizeof(history[profiler.historyPos])); +} + +const char *Profiler_GetCategoryName(int i) { + return i >= 0 ? categories[i].name : "N/A"; +} + +int Profiler_GetHistoryLength() { + return HISTORY_SIZE; +} + +int Profiler_GetNumCategories() { + for (int i = 0; i < MAX_CATEGORIES; i++) { + if (!categories[i].name) + return i; + } + return 0; +} + +void Profiler_GetHistory(int category, float *data, int count) { + for (int i = 0; i < HISTORY_SIZE; i++) { + int x = i - count + profiler.historyPos + 1; + while (x < 0) + x += HISTORY_SIZE; + while (x >= HISTORY_SIZE) + x -= HISTORY_SIZE; + data[i] = history[x].time_taken[category]; + } +} diff --git a/ext/native/profiler/profiler.h b/ext/native/profiler/profiler.h new file mode 100644 index 0000000000..9ed1a81e9f --- /dev/null +++ b/ext/native/profiler/profiler.h @@ -0,0 +1,45 @@ +#pragma once + +#include + +// #define USE_PROFILER + +#ifdef USE_PROFILER + +class DrawBuffer; + +void internal_profiler_init(); +void internal_profiler_end_frame(); + +int internal_profiler_enter(const char *category_name); // Returns the category number. +void internal_profiler_leave(int category); + + +const char *Profiler_GetCategoryName(int i); +int Profiler_GetNumCategories(); +int Profiler_GetHistoryLength(); +void Profiler_GetHistory(int i, float *data, int count); + +class ProfileThis { +public: + ProfileThis(const char *category) { + cat_ = internal_profiler_enter(category); + } + ~ProfileThis() { + internal_profiler_leave(cat_); + } +private: + int cat_; +}; + +#define PROFILE_INIT() internal_profiler_init(); +#define PROFILE_THIS_SCOPE(cat) ProfileThis _profile_scoped(cat); +#define PROFILE_END_FRAME() internal_profiler_end_frame(); + +#else + +#define PROFILE_INIT() +#define PROFILE_THIS_SCOPE(cat) +#define PROFILE_END_FRAME() + +#endif diff --git a/ext/native/thin3d/d3dx9_loader.cpp b/ext/native/thin3d/d3dx9_loader.cpp new file mode 100644 index 0000000000..51dab2ec53 --- /dev/null +++ b/ext/native/thin3d/d3dx9_loader.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include +#include + +#include "base/logging.h" +#include "thin3d/d3dx9_loader.h" + +typedef BOOL(__stdcall *TFunc_D3DXCheckVersion)(UINT D3DSDKVersion, UINT D3DXSDKVersion); +typedef HRESULT(__stdcall *TFunc_D3DXCompileShader)( + LPCSTR pSrcData, + UINT srcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE * ppConstantTable); + +typedef HRESULT(__stdcall *TFunc_D3DXAssembleShader)( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER * ppErrorMsgs + ); + +static HMODULE hm_d3dx; +static unsigned int d3dx_version; +static int failedFunctions; + +static TFunc_D3DXCheckVersion m_TFunc_D3DXCheckVersion; +static TFunc_D3DXAssembleShader m_TFunc_D3DXAssembleShader; +static TFunc_D3DXCompileShader m_TFunc_D3DXCompileShader; + +void makeD3DX9dllFilename_by_versionW(std::wstring& strOut, unsigned int versionNumber, bool debugVersion = false) { + wchar_t buf[256]; + wsprintf(buf, L"d3dx9%s_%02i.dll", debugVersion ? L"d" : L"", versionNumber); + strOut = buf; +} + +bool checkDllExistsW(const WCHAR* fname, bool bIncludeExeDir) { + return ::GetFileAttributesW(fname) != DWORD(-1); +} + +bool checkExistsDllW(const WCHAR* sDllFilename) { + std::wstring sfullpath; + WCHAR bufsysdir[MAX_PATH]; + + if (!::GetSystemDirectoryW(bufsysdir, MAX_PATH)) { + throw (std::runtime_error("system error")); + } + + sfullpath = bufsysdir; + sfullpath += L'\\'; + sfullpath += sDllFilename; + + if (checkDllExistsW(sfullpath.c_str(), true)) { + return true; + } + + return false; +} + +bool getLatestInstalledD3DXVersion(unsigned int* piOutVers, bool debugVersion) { + *piOutVers = 0; + std::wstring fname; + for (unsigned int cvers = 45; cvers > 0; cvers--) { + makeD3DX9dllFilename_by_versionW(fname, cvers, debugVersion); + if (checkExistsDllW(fname.c_str())) { + *piOutVers = cvers; + return true; + } + } + return false; +} + +HMODULE loadDllLastVersion(unsigned int* version, bool debugVersion) { + failedFunctions = 0; + + if (version) + *version = 0; + + if (!getLatestInstalledD3DXVersion(version, debugVersion)) { + return 0; + } + + std::wstring dllfname; + makeD3DX9dllFilename_by_versionW(dllfname, version ? *version : 0, debugVersion); + HMODULE hm = ::LoadLibraryW(dllfname.c_str()); + return hm; +} + +#define GB_MAKE_STR(s) # s +#define GB_MAKE_STR2(x) GB_MAKE_STR(x) + +#define __HANDLE_DLL_ENTRY(funcname) m_TFunc_##funcname = \ + ( TFunc_##funcname ) ::GetProcAddress(hm_d3dx, GB_MAKE_STR(funcname) ); \ + \ + if(!m_TFunc_##funcname) {\ + handleNotFoundAddr( GB_MAKE_STR(funcname) ); \ + } + +void handleNotFoundAddr(const char* sFuncName) { + ELOG("Failed to find D3DX function %s", sFuncName); + failedFunctions++; +} + +int LoadD3DX9Dynamic(bool debugVersion) { + if (hm_d3dx) { + // Already loaded + return d3dx_version; + } + + hm_d3dx = loadDllLastVersion(&d3dx_version, debugVersion); + if (!hm_d3dx) { + ELOG("Failed to find D3DX dll."); + return 0; + } + const int NERROR = -1; + int _begin = 0; + + __HANDLE_DLL_ENTRY(D3DXCheckVersion); + __HANDLE_DLL_ENTRY(D3DXAssembleShader); + __HANDLE_DLL_ENTRY(D3DXCompileShader); + + if (failedFunctions > 0) { + ELOG("Failed to load %i D3DX functions. This will not go well.", failedFunctions); + } + + return failedFunctions > 0 ? 0 : d3dx_version; +} + +int GetD3DXVersion() { + return d3dx_version; +} + +void UnloadD3DXDynamic() { + if (hm_d3dx) { + FreeLibrary(hm_d3dx); + hm_d3dx = NULL; + d3dx_version = 0; + } +} + +// version function + +#define GB_D3D9_D3DXDLL_LOADER_CHECK_ENTRY_NULL_PTR(funcname) assert(false && GB_MAKE_STR2(funcname) ); + + +BOOL dyn_D3DXCheckVersion(UINT D3DSDKVersion, UINT D3DXSDKVersion) { + if (!m_TFunc_D3DXCheckVersion) { + GB_D3D9_D3DXDLL_LOADER_CHECK_ENTRY_NULL_PTR(D3DXCheckVersion) + } + return m_TFunc_D3DXCheckVersion(D3DSDKVersion, D3DXSDKVersion); +} + +HRESULT dyn_D3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER * ppErrorMsgs) +{ + if (!m_TFunc_D3DXAssembleShader) { + GB_D3D9_D3DXDLL_LOADER_CHECK_ENTRY_NULL_PTR(D3DXAssembleShader); + } + return m_TFunc_D3DXAssembleShader(pSrcData, SrcDataLen, pDefines, + pInclude, Flags, ppShader, ppErrorMsgs); +} + +HRESULT dyn_D3DXCompileShader(LPCSTR pSrcData, UINT srcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, + DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE * ppConstantTable) +{ + if (!m_TFunc_D3DXCompileShader) { + GB_D3D9_D3DXDLL_LOADER_CHECK_ENTRY_NULL_PTR(D3DXCompileShader); + } + return m_TFunc_D3DXCompileShader(pSrcData, srcDataLen, pDefines, + pInclude, pFunctionName, pProfile, + Flags, ppShader, ppErrorMsgs, ppConstantTable); +} \ No newline at end of file diff --git a/ext/native/thin3d/d3dx9_loader.h b/ext/native/thin3d/d3dx9_loader.h new file mode 100644 index 0000000000..a194077a2e --- /dev/null +++ b/ext/native/thin3d/d3dx9_loader.h @@ -0,0 +1,21 @@ +// Cut-down version of https://code.google.com/p/d3dx9-dynamic-load/ +// by ksacvet777, licensed under the MIT + +#pragma once + +#include +#include + +// Returns the D3DX9 version we got. 0 if none. +int LoadD3DX9Dynamic(bool debugVersion = false); // If debugVersion is set, load d3dx9d.dll +int GetD3DXVersion(); +void UnloadD3DXDynamic(); + +// Call these instead of the real D3DX9 functions. +BOOL dyn_D3DXCheckVersion(UINT D3DSDKVersion, UINT D3DXSDKVersion); +HRESULT dyn_D3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER * ppErrorMsgs); +HRESULT dyn_D3DXCompileShader(LPCSTR pSrcData, UINT srcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, + DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE * ppConstantTable); diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp new file mode 100644 index 0000000000..afc465a0c4 --- /dev/null +++ b/ext/native/thin3d/thin3d.cpp @@ -0,0 +1,270 @@ +#include +#include + +#include "base/logging.h" +#include "image/zim_load.h" +#include "image/png_load.h" +#include "file/vfs.h" +#include "ext/jpge/jpgd.h" + +static const char * const glsl_fsTexCol = +"#ifdef GL_ES\n" +"precision lowp float;\n" +"#endif\n" +"varying vec4 oColor0;\n" +"varying vec2 oTexCoord0;\n" +"uniform sampler2D Sampler0;\n" +"void main() { gl_FragColor = texture2D(Sampler0, oTexCoord0) * oColor0; }\n"; + +static const char * const hlslFsTexCol = +"struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" +"sampler2D Sampler0 : register(s0);\n" +"float4 main(PS_INPUT input) : COLOR0 {\n" +" return input.color * tex2D(Sampler0, input.uv);\n" +"}\n"; + +static const char * const glsl_fsCol = +"#ifdef GL_ES\n" +"precision lowp float;\n" +"#endif\n" +"varying vec4 oColor0;\n" +"void main() { gl_FragColor = oColor0; }\n"; + +static const char * const hlslFsCol = +"struct PS_INPUT { float4 color : COLOR0; };\n" +"float4 main(PS_INPUT input) : COLOR0 {\n" +" return input.color;\n" +"}\n"; + +static const char * const glsl_vsCol = +"attribute vec3 Position;\n" +"attribute vec4 Color0;\n" +"varying vec4 oColor0;\n" +"uniform mat4 WorldViewProj;\n" +"void main() {\n" +" gl_Position = WorldViewProj * vec4(Position, 1.0);\n" +" oColor0 = Color0;\n" +"}"; + +static const char * const hlslVsCol = +"struct VS_INPUT { float3 Position : POSITION; float4 Color0 : COLOR0; };\n" +"struct VS_OUTPUT { float4 Position : POSITION; float4 Color0 : COLOR0; };\n" +"float4x4 WorldViewProj;\n" +"VS_OUTPUT main(VS_INPUT input) {\n" +" VS_OUTPUT output;\n" +" output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n" +" output.Color0 = input.Color0;\n" +" return output;\n" +"}\n"; + +static const char * const glsl_vsTexCol = +"attribute vec3 Position;\n" +"attribute vec4 Color0;\n" +"attribute vec2 TexCoord0;\n" +"varying vec4 oColor0;\n" +"varying vec2 oTexCoord0;\n" +"uniform mat4 WorldViewProj;\n" +"void main() {\n" +" gl_Position = WorldViewProj * vec4(Position, 1.0);\n" +" oColor0 = Color0;\n" +" oTexCoord0 = TexCoord0;\n" +"}\n"; + +static const char * const hlslVsTexCol = +"struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n" +"struct VS_OUTPUT { float4 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n" +"float4x4 WorldViewProj;\n" +"VS_OUTPUT main(VS_INPUT input) {\n" +" VS_OUTPUT output;\n" +" output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n" +" output.Texcoord0 = input.Texcoord0;\n" +" output.Color0 = input.Color0;\n" +" return output;\n" +"}\n"; + +void Thin3DContext::CreatePresets() { + // Build prebuilt objects + T3DBlendStateDesc off = { false }; + T3DBlendStateDesc additive = { true, T3DBlendEquation::ADD, T3DBlendFactor::ONE, T3DBlendFactor::ONE, T3DBlendEquation::ADD, T3DBlendFactor::ONE, T3DBlendFactor::ZERO }; + T3DBlendStateDesc standard_alpha = { true, T3DBlendEquation::ADD, T3DBlendFactor::SRC_ALPHA, T3DBlendFactor::ONE_MINUS_SRC_ALPHA, T3DBlendEquation::ADD, T3DBlendFactor::ONE, T3DBlendFactor::ZERO }; + T3DBlendStateDesc premul_alpha = { true, T3DBlendEquation::ADD, T3DBlendFactor::ONE, T3DBlendFactor::ONE_MINUS_SRC_ALPHA, T3DBlendEquation::ADD, T3DBlendFactor::ONE, T3DBlendFactor::ZERO }; + + bsPresets_[BS_OFF] = CreateBlendState(off); + bsPresets_[BS_ADDITIVE] = CreateBlendState(additive); + bsPresets_[BS_STANDARD_ALPHA] = CreateBlendState(standard_alpha); + bsPresets_[BS_PREMUL_ALPHA] = CreateBlendState(premul_alpha); + + vsPresets_[VS_TEXTURE_COLOR_2D] = CreateVertexShader(glsl_vsTexCol, hlslVsTexCol); + vsPresets_[VS_COLOR_2D] = CreateVertexShader(glsl_vsCol, hlslVsCol); + + fsPresets_[FS_TEXTURE_COLOR_2D] = CreateFragmentShader(glsl_fsTexCol, hlslFsTexCol); + fsPresets_[FS_COLOR_2D] = CreateFragmentShader(glsl_fsCol, hlslFsCol); + + ssPresets_[SS_TEXTURE_COLOR_2D] = CreateShaderSet(vsPresets_[VS_TEXTURE_COLOR_2D], fsPresets_[FS_TEXTURE_COLOR_2D]); + ssPresets_[SS_COLOR_2D] = CreateShaderSet(vsPresets_[VS_COLOR_2D], fsPresets_[FS_COLOR_2D]); +} + +Thin3DContext::~Thin3DContext() { + for (int i = 0; i < VS_MAX_PRESET; i++) { + if (vsPresets_[i]) { + vsPresets_[i]->Release(); + } + } + for (int i = 0; i < FS_MAX_PRESET; i++) { + if (fsPresets_[i]) { + fsPresets_[i]->Release(); + } + } + for (int i = 0; i < BS_MAX_PRESET; i++) { + if (bsPresets_[i]) { + bsPresets_[i]->Release(); + } + } + for (int i = 0; i < SS_MAX_PRESET; i++) { + if (ssPresets_[i]) { + ssPresets_[i]->Release(); + } + } +} + +static T3DImageFormat ZimToT3DFormat(int zim) { + switch (zim) { + case ZIM_ETC1: return T3DImageFormat::ETC1; + case ZIM_RGBA8888: return T3DImageFormat::RGBA8888; + case ZIM_LUMINANCE: return T3DImageFormat::LUMINANCE; + default: return T3DImageFormat::RGBA8888; + } +} + +static T3DImageType DetectImageFileType(const uint8_t *data, size_t size) { + if (!memcmp(data, "ZIMG", 4)) { + return ZIM; + } else if (!memcmp(data, "\x89\x50\x4E\x47", 4)) { + return PNG; + } else if (!memcmp(data, "\xff\xd8\xff\xe0", 4)) { + return JPEG; + } else { + return TYPE_UNKNOWN; + } +} + +static bool LoadTextureLevels(const uint8_t *data, size_t size, T3DImageType type, int width[16], int height[16], int *num_levels, T3DImageFormat *fmt, uint8_t *image[16], int *zim_flags) { + if (type == DETECT) { + type = DetectImageFileType(data, size); + } + if (type == TYPE_UNKNOWN) { + ELOG("File has unknown format"); + return false; + } + + *num_levels = 0; + *zim_flags = 0; + + switch (type) { + case ZIM: + { + *num_levels = LoadZIMPtr((const uint8_t *)data, size, width, height, zim_flags, image); + *fmt = ZimToT3DFormat(*zim_flags & ZIM_FORMAT_MASK); + } + break; + + case PNG: + if (1 == pngLoadPtr((const unsigned char *)data, size, &width[0], &height[0], &image[0], false)) { + *num_levels = 1; + *fmt = RGBA8888; + } + break; + + case JPEG: + { + int actual_components = 0; + unsigned char *jpegBuf = jpgd::decompress_jpeg_image_from_memory(data, (int)size, &width[0], &height[0], &actual_components, 4); + if (jpegBuf) { + *num_levels = 1; + *fmt = RGBA8888; + image[0] = (uint8_t *)jpegBuf; + } + } + break; + + default: + ELOG("Unknown image format"); + return false; + } + + return *num_levels > 0; +} + +bool Thin3DTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, T3DImageType type) { + int width[16], height[16]; + uint8_t *image[16] = { nullptr }; + + int num_levels; + int zim_flags; + T3DImageFormat fmt; + + if (!LoadTextureLevels(data, dataSize, type, width, height, &num_levels, &fmt, image, &zim_flags)) { + return false; + } + + Create(LINEAR2D, fmt, width[0], height[0], 1, num_levels); + for (int i = 0; i < num_levels; i++) { + if (image[i]) { + SetImageData(0, 0, 0, width[i], height[i], 1, i, width[i] * 4, image[i]); + free(image[i]); + } else { + ELOG("Missing image level %i", i); + } + } + + Finalize(zim_flags); + return true; +} + +bool Thin3DTexture::LoadFromFile(const std::string &filename, T3DImageType type) { + filename_ = ""; + size_t fileSize; + uint8_t *buffer = VFSReadFile(filename.c_str(), &fileSize); + if (!buffer) { + return false; + } + bool retval = LoadFromFileData(buffer, fileSize, type); + if (retval) { + filename_ = filename; + } else { + ELOG("%s: Failed to load texture %s", __FUNCTION__, filename.c_str()); + } + delete[] buffer; + return retval; +} + +Thin3DTexture *Thin3DContext::CreateTextureFromFile(const char *filename, T3DImageType type) { + Thin3DTexture *tex = CreateTexture(); + if (!tex->LoadFromFile(filename, type)) { + tex->Release(); + return NULL; + } + return tex; +} + +// TODO: Remove the code duplication between this and LoadFromFileData +Thin3DTexture *Thin3DContext::CreateTextureFromFileData(const uint8_t *data, int size, T3DImageType type) { + int width[16], height[16]; + int num_levels = 0; + int zim_flags = 0; + T3DImageFormat fmt; + uint8_t *image[16] = { nullptr }; + + if (!LoadTextureLevels(data, size, type, width, height, &num_levels, &fmt, image, &zim_flags)) { + return NULL; + } + + Thin3DTexture *tex = CreateTexture(LINEAR2D, fmt, width[0], height[0], 1, num_levels); + for (int i = 0; i < num_levels; i++) { + tex->SetImageData(0, 0, 0, width[i], height[i], 1, i, width[i] * 4, image[i]); + free(image[i]); + } + + tex->Finalize(zim_flags); + return tex; +} diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h new file mode 100644 index 0000000000..3b7d3a17d0 --- /dev/null +++ b/ext/native/thin3d/thin3d.h @@ -0,0 +1,360 @@ +// Very thin API wrapper, suitable for porting UI code (like the native/ui framework) and similar but not real rendering. +// Does not involve context creation etc, that should be handled separately - only does drawing. + +// The goals may change in the future though. +// MIT licensed, by Henrik Rydgård 2014. + +#pragma once + +#include +#include +#include +#include + +class Matrix4x4; + +enum T3DBlendEquation : int { + ADD, + SUBTRACT, + REV_SUBTRACT, + MIN, + MAX, +}; + +enum T3DComparison : int { + NEVER, + LESS, + EQUAL, + LESS_EQUAL, + GREATER, + NOT_EQUAL, + GREATER_EQUAL, + ALWAYS, +}; + +// Had to prefix with LOGIC, too many clashes +enum T3DLogicOp : int { + LOGIC_CLEAR, + LOGIC_SET, + LOGIC_COPY, + LOGIC_COPY_INVERTED, + LOGIC_NOOP, + LOGIC_INVERT, + LOGIC_AND, + LOGIC_NAND, + LOGIC_OR, + LOGIC_NOR, + LOGIC_XOR, + LOGIC_EQUIV, + LOGIC_AND_REVERSE, + LOGIC_AND_INVERTED, + LOGIC_OR_REVERSE, + LOGIC_OR_INVERTED, +}; + +enum T3DBlendFactor : int { + ZERO, + ONE, + SRC_COLOR, + SRC_ALPHA, + ONE_MINUS_SRC_COLOR, + ONE_MINUS_SRC_ALPHA, + DST_COLOR, + DST_ALPHA, + ONE_MINUS_DST_COLOR, + ONE_MINUS_DST_ALPHA, + FIXED_COLOR, +}; + +enum T3DBufferUsage : int { + VERTEXDATA = 1, + INDEXDATA = 2, + GENERIC = 4, + + DYNAMIC = 16, +}; + +enum T3DVertexDataType : uint8_t { + INVALID, + FLOATx2, + FLOATx3, + FLOATx4, + UNORM8x4, +}; + +enum T3DSemantic : int { + SEM_POSITION, + SEM_COLOR0, + SEM_TEXCOORD0, + SEM_TEXCOORD1, + SEM_NORMAL, + SEM_TANGENT, + SEM_BINORMAL, // really BITANGENT + SEM_MAX, +}; + +enum T3DPrimitive : int { + PRIM_POINTS, + PRIM_LINES, + PRIM_TRIANGLES, +}; + +enum T3DVertexShaderPreset : int { + VS_COLOR_2D, + VS_TEXTURE_COLOR_2D, + VS_MAX_PRESET, +}; + +enum T3DFragmentShaderPreset : int { + FS_COLOR_2D, + FS_TEXTURE_COLOR_2D, + FS_MAX_PRESET, +}; + +// Predefined full shader setups. +enum T3DShaderSetPreset : int { + SS_COLOR_2D, + SS_TEXTURE_COLOR_2D, + SS_MAX_PRESET, +}; + +enum T3DBlendStatePreset : int { + BS_OFF, + BS_STANDARD_ALPHA, + BS_PREMUL_ALPHA, + BS_ADDITIVE, + BS_MAX_PRESET, +}; + +enum T3DClear : int { + COLOR = 1, + DEPTH = 2, + STENCIL = 4, +}; + +enum T3DTextureType : uint8_t { + UNKNOWN, + LINEAR1D, + LINEAR2D, + LINEAR3D, + CUBE, + ARRAY1D, + ARRAY2D, +}; + +enum T3DImageFormat : uint8_t { + IMG_UNKNOWN, + LUMINANCE, + RGBA8888, + RGBA4444, + DXT1, + ETC1, // Needs simulation on many platforms + D16, + D24S8, + D24X8, +}; + +enum T3DRenderState : uint8_t { + CULL_MODE, +}; + +enum T3DCullMode : uint8_t { + NO_CULL, + CW, + CCW, +}; + +enum T3DImageType { + PNG, + JPEG, + ZIM, + DETECT, + TYPE_UNKNOWN, +}; + +enum T3DInfo { + APINAME, + APIVERSION, + VENDORSTRING, + VENDOR, + SHADELANGVERSION, + RENDERER, +}; + +// Binary compatible with D3D11 viewport. +struct T3DViewport { + float TopLeftX; + float TopLeftY; + float Width; + float Height; + float MinDepth; + float MaxDepth; +}; + +class Thin3DObject { +public: + Thin3DObject() : refcount_(1) {} + virtual ~Thin3DObject() {} + + virtual void AddRef() { refcount_++; } + virtual void Release() { refcount_--; if (!refcount_) delete this; } + +private: + int refcount_; +}; + +class Thin3DBlendState : public Thin3DObject { +public: +}; + +class Thin3DDepthStencilState : public Thin3DObject { +public: +}; + +class Thin3DBuffer : public Thin3DObject { +public: + virtual void SetData(const uint8_t *data, size_t size) = 0; + virtual void SubData(const uint8_t *data, size_t offset, size_t size) = 0; +}; + +class Thin3DTexture : public Thin3DObject { +public: + bool LoadFromFile(const std::string &filename, T3DImageType type = T3DImageType::DETECT); + bool LoadFromFileData(const uint8_t *data, size_t dataSize, T3DImageType type = T3DImageType::DETECT); + + virtual bool Create(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) = 0; + virtual void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) = 0; + virtual void AutoGenMipmaps() = 0; + virtual void Finalize(int zim_flags) = 0; // TODO: Tidy up + + int Width() { return width_; } + int Height() { return height_; } + int Depth() { return depth_; } +protected: + std::string filename_; // Textures that are loaded from files can reload themselves automatically. + int width_, height_, depth_; +}; + +struct Thin3DVertexComponent { + Thin3DVertexComponent() : name(nullptr), type(T3DVertexDataType::INVALID), semantic(255), offset(255) {} + Thin3DVertexComponent(const char *name, T3DSemantic semantic, T3DVertexDataType dataType, uint8_t offset) { + this->name = name; + this->semantic = semantic; + this->type = dataType; + this->offset = offset; + } + const char *name; + T3DVertexDataType type; + uint8_t semantic; + uint8_t offset; +}; + +class Thin3DVertexFormat : public Thin3DObject { +public: +}; + +class Thin3DShader : public Thin3DObject { +public: +}; + +class Thin3DShaderSet : public Thin3DObject { +public: + // TODO: Make some faster way of doing these. Support uniform buffers (and fake them on GL 2.0?) + virtual void SetVector(const char *name, float *value, int n) = 0; + virtual void SetMatrix4x4(const char *name, const Matrix4x4 &value) = 0; +}; + +struct T3DBlendStateDesc { + bool enabled; + T3DBlendEquation eqCol; + T3DBlendFactor srcCol; + T3DBlendFactor dstCol; + T3DBlendEquation eqAlpha; + T3DBlendFactor srcAlpha; + T3DBlendFactor dstAlpha; + bool logicEnabled; + T3DLogicOp logicOp; + // int colorMask; +}; + +class Thin3DContext : public Thin3DObject { +public: + virtual ~Thin3DContext(); + + virtual Thin3DDepthStencilState *CreateDepthStencilState(bool depthTestEnabled, bool depthWriteEnabled, T3DComparison depthCompare) = 0; + virtual Thin3DBlendState *CreateBlendState(const T3DBlendStateDesc &desc) = 0; + virtual Thin3DBuffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0; + virtual Thin3DShaderSet *CreateShaderSet(Thin3DShader *vshader, Thin3DShader *fshader) = 0; + virtual Thin3DVertexFormat *CreateVertexFormat(const std::vector &components, int stride, Thin3DShader *vshader) = 0; + + virtual Thin3DTexture *CreateTexture() = 0; // To be later filled in by ->LoadFromFile or similar. + virtual Thin3DTexture *CreateTexture(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) = 0; + + // Common Thin3D function, uses CreateTexture + Thin3DTexture *CreateTextureFromFile(const char *filename, T3DImageType fileType); + Thin3DTexture *CreateTextureFromFileData(const uint8_t *data, int size, T3DImageType fileType); + + // Note that these DO NOT AddRef so you must not ->Release presets unless you manually AddRef them. + Thin3DBlendState *GetBlendStatePreset(T3DBlendStatePreset preset) { return bsPresets_[preset]; } + Thin3DShader *GetVshaderPreset(T3DVertexShaderPreset preset) { return fsPresets_[preset]; } + Thin3DShader *GetFshaderPreset(T3DFragmentShaderPreset preset) { return vsPresets_[preset]; } + Thin3DShaderSet *GetShaderSetPreset(T3DShaderSetPreset preset) { return ssPresets_[preset]; } + + // The implementation makes the choice of which shader code to use. + virtual Thin3DShader *CreateVertexShader(const char *glsl_source, const char *hlsl_source) = 0; + virtual Thin3DShader *CreateFragmentShader(const char *glsl_source, const char *hlsl_source) = 0; + + // Bound state objects. Too cumbersome to add them all as parameters to Draw. + virtual void SetBlendState(Thin3DBlendState *state) = 0; + virtual void SetDepthStencilState(Thin3DDepthStencilState *state) = 0; + virtual void SetTextures(int start, int count, Thin3DTexture **textures) = 0; + + void SetTexture(int stage, Thin3DTexture *texture) { + SetTextures(stage, 1, &texture); + } // from sampler 0 and upwards + + // Raster state + virtual void SetScissorEnabled(bool enable) = 0; + virtual void SetScissorRect(int left, int top, int width, int height) = 0; + virtual void SetViewports(int count, T3DViewport *viewports) = 0; + + // Single render states that aren't worth state blocks. May have to convert some of these state blocks on D3D11 though... + virtual void SetRenderState(T3DRenderState rs, uint32_t value) = 0; + + // TODO: Add more sophisticated draws with buffer offsets, and multidraws. + virtual void Draw(T3DPrimitive prim, Thin3DShaderSet *pipeline, Thin3DVertexFormat *format, Thin3DBuffer *vdata, int vertexCount, int offset) = 0; + virtual void DrawIndexed(T3DPrimitive prim, Thin3DShaderSet *pipeline, Thin3DVertexFormat *format, Thin3DBuffer *vdata, Thin3DBuffer *idata, int vertexCount, int offset) = 0; + virtual void DrawUP(T3DPrimitive prim, Thin3DShaderSet *pipeline, Thin3DVertexFormat *format, const void *vdata, int vertexCount) = 0; + virtual void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) = 0; + + // Necessary to correctly flip scissor rectangles etc for OpenGL. + void SetTargetSize(int w, int h) { + targetWidth_ = w; + targetHeight_ = h; + } + + virtual const char *GetInfoString(T3DInfo info) const = 0; + +protected: + void CreatePresets(); + + Thin3DShader *vsPresets_[VS_MAX_PRESET]; + Thin3DShader *fsPresets_[FS_MAX_PRESET]; + Thin3DBlendState *bsPresets_[BS_MAX_PRESET]; + Thin3DShaderSet *ssPresets_[SS_MAX_PRESET]; + + int targetWidth_; + int targetHeight_; + +private: +}; + +Thin3DContext *T3DCreateGLContext(); + +#ifdef _WIN32 +struct IDirect3DDevice9; +struct IDirect3D9; +struct IDirect3DDevice9Ex; +struct IDirect3D9Ex; +Thin3DContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx); +#endif diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp new file mode 100644 index 0000000000..ea18919e3f --- /dev/null +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -0,0 +1,765 @@ +#include +#include +#include + +#ifdef _DEBUG +#define D3D_DEBUG_INFO +#endif + +#include +#include + +#include "base/logging.h" +#include "math/lin/matrix4x4.h" +#include "thin3d/thin3d.h" +#include "thin3d/d3dx9_loader.h" + +// Could be declared as u8 +static const D3DCMPFUNC compareToD3D9[] = { + D3DCMP_NEVER, + D3DCMP_LESS, + D3DCMP_EQUAL, + D3DCMP_LESSEQUAL, + D3DCMP_GREATER, + D3DCMP_NOTEQUAL, + D3DCMP_GREATEREQUAL, + D3DCMP_ALWAYS +}; + +// Could be declared as u8 +static const D3DBLENDOP blendEqToD3D9[] = { + D3DBLENDOP_ADD, + D3DBLENDOP_SUBTRACT, + D3DBLENDOP_REVSUBTRACT, + D3DBLENDOP_MIN, + D3DBLENDOP_MAX, +}; + +// Could be declared as u8 +static const D3DBLEND blendFactorToD3D9[] = { + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_SRCCOLOR, + D3DBLEND_SRCALPHA, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVSRCALPHA, + D3DBLEND_DESTCOLOR, + D3DBLEND_DESTALPHA, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVDESTALPHA, + D3DBLEND_BLENDFACTOR, +}; + +static const D3DPRIMITIVETYPE primToD3D9[] = { + D3DPT_POINTLIST, + D3DPT_LINELIST, + D3DPT_TRIANGLELIST, +}; + +class Thin3DDX9DepthStencilState : public Thin3DDepthStencilState { +public: + BOOL depthTestEnabled; + BOOL depthWriteEnabled; + D3DCMPFUNC depthCompare; + + void Apply(LPDIRECT3DDEVICE9 device) { + device->SetRenderState(D3DRS_ZENABLE, depthTestEnabled); + device->SetRenderState(D3DRS_ZWRITEENABLE, depthWriteEnabled); + device->SetRenderState(D3DRS_ZFUNC, depthCompare); + } +}; + +class Thin3DDX9BlendState : public Thin3DBlendState { +public: + bool enabled; + D3DBLENDOP eqCol, eqAlpha; + D3DBLEND srcCol, srcAlpha, dstCol, dstAlpha; + uint32_t fixedColor; + + void Apply(LPDIRECT3DDEVICE9 device) { + device->SetRenderState(D3DRS_ALPHABLENDENABLE, (DWORD)enabled); + device->SetRenderState(D3DRS_BLENDOP, eqCol); + device->SetRenderState(D3DRS_BLENDOPALPHA, eqAlpha); + device->SetRenderState(D3DRS_SRCBLEND, srcCol); + device->SetRenderState(D3DRS_DESTBLEND, dstCol); + device->SetRenderState(D3DRS_SRCBLENDALPHA, srcAlpha); + device->SetRenderState(D3DRS_DESTBLENDALPHA, dstAlpha); + // device->SetRenderState(, fixedColor); + } +}; + +class Thin3DDX9Buffer : public Thin3DBuffer { +public: + Thin3DDX9Buffer(LPDIRECT3DDEVICE9 device, size_t size, uint32_t flags) : vbuffer_(nullptr), ibuffer_(nullptr), maxSize_(size) { + if (flags & T3DBufferUsage::INDEXDATA) { + DWORD usage = D3DUSAGE_DYNAMIC; + device->CreateIndexBuffer((UINT)size, usage, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &ibuffer_, NULL); + } else { + DWORD usage = D3DUSAGE_DYNAMIC; + device->CreateVertexBuffer((UINT)size, usage, 0, D3DPOOL_DEFAULT, &vbuffer_, NULL); + } + } + virtual ~Thin3DDX9Buffer() override { + if (ibuffer_) { + ibuffer_->Release(); + } + if (vbuffer_) { + vbuffer_->Release(); + } + } + + void SetData(const uint8_t *data, size_t size) override { + if (!size) + return; + if (size > maxSize_) { + ELOG("Can't SetData with bigger size than buffer was created with on D3D"); + return; + } + if (vbuffer_) { + void *ptr; + vbuffer_->Lock(0, (UINT)size, &ptr, D3DLOCK_DISCARD); + memcpy(ptr, data, size); + vbuffer_->Unlock(); + } else if (ibuffer_) { + void *ptr; + ibuffer_->Lock(0, (UINT)size, &ptr, D3DLOCK_DISCARD); + memcpy(ptr, data, size); + ibuffer_->Unlock(); + } + } + void SubData(const uint8_t *data, size_t offset, size_t size) override { + if (!size) + return; + if (offset + size > maxSize_) { + ELOG("Can't SubData with bigger size than buffer was created with on D3D"); + return; + } + if (vbuffer_) { + void *ptr; + HRESULT res = vbuffer_->Lock((UINT)offset, (UINT)size, &ptr, D3DLOCK_DISCARD); + if (!FAILED(res)) { + memcpy(ptr, data, size); + vbuffer_->Unlock(); + } + } else if (ibuffer_) { + void *ptr; + HRESULT res = ibuffer_->Lock((UINT)offset, (UINT)size, &ptr, D3DLOCK_DISCARD); + if (!FAILED(res)) { + memcpy(ptr, data, size); + ibuffer_->Unlock(); + } + } + } + void BindAsVertexBuf(LPDIRECT3DDEVICE9 device, int vertexSize, int offset = 0) { + if (vbuffer_) + device->SetStreamSource(0, vbuffer_, offset, vertexSize); + } + void BindAsIndexBuf(LPDIRECT3DDEVICE9 device) { + if (ibuffer_) + device->SetIndices(ibuffer_); + } + +private: + LPDIRECT3DVERTEXBUFFER9 vbuffer_; + LPDIRECT3DINDEXBUFFER9 ibuffer_; + size_t maxSize_; +}; + + +class Thin3DDX9VertexFormat : public Thin3DVertexFormat { +public: + Thin3DDX9VertexFormat(LPDIRECT3DDEVICE9 device, const std::vector &components, int stride); + ~Thin3DDX9VertexFormat() { + if (decl_) { + decl_->Release(); + } + } + int GetStride() const { return stride_; } + void Apply(LPDIRECT3DDEVICE9 device) { + device->SetVertexDeclaration(decl_); + } +private: + LPDIRECT3DVERTEXDECLARATION9 decl_; + int stride_; +}; + +class Thin3DDX9Shader : public Thin3DShader { +public: + Thin3DDX9Shader(bool isPixelShader) : isPixelShader_(isPixelShader), vshader_(NULL), pshader_(NULL), constantTable_(NULL) {} + ~Thin3DDX9Shader() { + if (vshader_) + vshader_->Release(); + if (pshader_) + pshader_->Release(); + if (constantTable_) + constantTable_->Release(); + } + bool Compile(LPDIRECT3DDEVICE9 device, const char *source, const char *profile); + void Apply(LPDIRECT3DDEVICE9 device) { + if (isPixelShader_) { + device->SetPixelShader(pshader_); + } else { + device->SetVertexShader(vshader_); + } + } + void SetVector(LPDIRECT3DDEVICE9 device, const char *name, float *value, int n); + void SetMatrix4x4(LPDIRECT3DDEVICE9 device, const char *name, const Matrix4x4 &value); + +private: + bool isPixelShader_; + LPDIRECT3DVERTEXSHADER9 vshader_; + LPDIRECT3DPIXELSHADER9 pshader_; + LPD3DXCONSTANTTABLE constantTable_; +}; + +class Thin3DDX9ShaderSet : public Thin3DShaderSet { +public: + Thin3DDX9ShaderSet(LPDIRECT3DDEVICE9 device) : device_(device) {} + Thin3DDX9Shader *vshader; + Thin3DDX9Shader *pshader; + void Apply(LPDIRECT3DDEVICE9 device); + void SetVector(const char *name, float *value, int n) { vshader->SetVector(device_, name, value, n); pshader->SetVector(device_, name, value, n); } + void SetMatrix4x4(const char *name, const Matrix4x4 &value) { vshader->SetMatrix4x4(device_, name, value); } // pshaders don't usually have matrices +private: + LPDIRECT3DDEVICE9 device_; +}; + +class Thin3DDX9Texture : public Thin3DTexture { +public: + Thin3DDX9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx) : device_(device), deviceEx_(deviceEx), type_(T3DTextureType::UNKNOWN), fmt_(D3DFMT_UNKNOWN), tex_(NULL), volTex_(NULL), cubeTex_(NULL) { + } + Thin3DDX9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels); + ~Thin3DDX9Texture(); + bool Create(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) override; + void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override; + void AutoGenMipmaps() override {} + void SetToSampler(LPDIRECT3DDEVICE9 device, int sampler); + void Finalize(int zim_flags) override {} + +private: + LPDIRECT3DDEVICE9 device_; + LPDIRECT3DDEVICE9EX deviceEx_; + T3DTextureType type_; + D3DFORMAT fmt_; + LPDIRECT3DTEXTURE9 tex_; + LPDIRECT3DVOLUMETEXTURE9 volTex_; + LPDIRECT3DCUBETEXTURE9 cubeTex_; +}; + +D3DFORMAT FormatToD3D(T3DImageFormat fmt) { + switch (fmt) { + case RGBA8888: return D3DFMT_A8R8G8B8; + case RGBA4444: return D3DFMT_A4R4G4B4; + case D24S8: return D3DFMT_D24S8; + case D16: return D3DFMT_D16; + default: return D3DFMT_UNKNOWN; + } +} + +Thin3DDX9Texture::Thin3DDX9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) + : device_(device), deviceEx_(deviceEx), type_(type), tex_(NULL), volTex_(NULL), cubeTex_(NULL) { + Create(type, format, width, height, depth, mipLevels); +} + +Thin3DDX9Texture::~Thin3DDX9Texture() { + if (tex_) { + tex_->Release(); + } + if (volTex_) { + volTex_->Release(); + } + if (cubeTex_) { + cubeTex_->Release(); + } +} + +bool Thin3DDX9Texture::Create(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) { + width_ = width; + height_ = height; + depth_ = depth; + type_ = type; + tex_ = NULL; + fmt_ = FormatToD3D(format); + HRESULT hr = E_FAIL; + + D3DPOOL pool = D3DPOOL_MANAGED; + int usage = 0; + if (deviceEx_ != nullptr) { + pool = D3DPOOL_DEFAULT; + usage = D3DUSAGE_DYNAMIC; + } + switch (type) { + case LINEAR1D: + case LINEAR2D: + hr = device_->CreateTexture(width, height, mipLevels, usage, fmt_, pool, &tex_, NULL); + break; + case LINEAR3D: + hr = device_->CreateVolumeTexture(width, height, depth, mipLevels, usage, fmt_, pool, &volTex_, NULL); + break; + case CUBE: + hr = device_->CreateCubeTexture(width, mipLevels, usage, fmt_, pool, &cubeTex_, NULL); + break; + } + if (FAILED(hr)) { + ELOG("Texture creation failed"); + return false; + } + return true; +} + +inline uint16_t Shuffle4444(uint16_t x) { + return (x << 12) | (x >> 4); +} + +// Just switches R and G. +inline uint32_t Shuffle8888(uint32_t x) { + return (x & 0xFF00FF00) | ((x >> 16) & 0xFF) | ((x << 16) & 0xFF0000); +} + + +void Thin3DDX9Texture::SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) { + if (!tex_) { + return; + } + if (level == 0) { + width_ = width; + height_ = height; + depth_ = depth; + } + + switch (type_) { + case LINEAR2D: + { + D3DLOCKED_RECT rect; + if (x == 0 && y == 0) { + tex_->LockRect(level, &rect, NULL, 0); + + for (int i = 0; i < height; i++) { + uint8_t *dest = (uint8_t *)rect.pBits + rect.Pitch * i; + const uint8_t *source = data + stride * i; + int j; + switch (fmt_) { + case D3DFMT_A4R4G4B4: + // This is backwards from OpenGL so we need to shuffle around a bit. + for (j = 0; j < width; j++) { + ((uint16_t *)dest)[j] = Shuffle4444(((uint16_t *)source)[j]); + } + break; + + case D3DFMT_A8R8G8B8: + for (j = 0; j < width; j++) { + ((uint32_t *)dest)[j] = Shuffle8888(((uint32_t *)source)[j]); + } + break; + } + } + tex_->UnlockRect(level); + } + break; + } + + default: + ELOG("Non-LINEAR2D textures not yet supported"); + break; + } +} + +void Thin3DDX9Texture::SetToSampler(LPDIRECT3DDEVICE9 device, int sampler) { + switch (type_) { + case LINEAR1D: + case LINEAR2D: + device->SetTexture(sampler, tex_); + break; + + case LINEAR3D: + device->SetTexture(sampler, volTex_); + break; + + case CUBE: + device->SetTexture(sampler, cubeTex_); + break; + } +} + +class Thin3DDX9Context : public Thin3DContext { +public: + Thin3DDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx); + ~Thin3DDX9Context(); + + Thin3DDepthStencilState *CreateDepthStencilState(bool depthTestEnabled, bool depthWriteEnabled, T3DComparison depthCompare); + Thin3DBlendState *CreateBlendState(const T3DBlendStateDesc &desc) override; + Thin3DBuffer *CreateBuffer(size_t size, uint32_t usageFlags) override; + Thin3DShaderSet *CreateShaderSet(Thin3DShader *vshader, Thin3DShader *fshader) override; + Thin3DVertexFormat *CreateVertexFormat(const std::vector &components, int stride, Thin3DShader *vshader) override; + Thin3DTexture *CreateTexture() override; + Thin3DTexture *CreateTexture(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) override; + + Thin3DShader *CreateVertexShader(const char *glsl_source, const char *hlsl_source) override; + Thin3DShader *CreateFragmentShader(const char *glsl_source, const char *hlsl_source) override; + + // Bound state objects. Too cumbersome to add them all as parameters to Draw. + void SetBlendState(Thin3DBlendState *state) { + Thin3DDX9BlendState *bs = static_cast(state); + bs->Apply(device_); + } + void SetDepthStencilState(Thin3DDepthStencilState *state) { + Thin3DDX9DepthStencilState *bs = static_cast(state); + bs->Apply(device_); + } + + void SetTextures(int start, int count, Thin3DTexture **textures); + + // Raster state + void SetScissorEnabled(bool enable); + void SetScissorRect(int left, int top, int width, int height); + void SetViewports(int count, T3DViewport *viewports); + void SetRenderState(T3DRenderState rs, uint32_t value) override; + + void Draw(T3DPrimitive prim, Thin3DShaderSet *pipeline, Thin3DVertexFormat *format, Thin3DBuffer *vdata, int vertexCount, int offset) override; + void DrawIndexed(T3DPrimitive prim, Thin3DShaderSet *pipeline, Thin3DVertexFormat *format, Thin3DBuffer *vdata, Thin3DBuffer *idata, int vertexCount, int offset) override; + void DrawUP(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, const void *vdata, int vertexCount) override; + void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal); + + const char *GetInfoString(T3DInfo info) const override { + switch (info) { + case APIVERSION: return "DirectX 9.0"; + case VENDORSTRING: return identifier_.Description; + case VENDOR: return "-"; + case RENDERER: return identifier_.Driver; // eh, sort of + case SHADELANGVERSION: return shadeLangVersion_; + case APINAME: return "Direct3D 9"; + default: return "?"; + } + } + +private: + LPDIRECT3D9 d3d_; + LPDIRECT3D9EX d3dEx_; + LPDIRECT3DDEVICE9 device_; + LPDIRECT3DDEVICE9EX deviceEx_; + int adapterId_; + D3DADAPTER_IDENTIFIER9 identifier_; + D3DCAPS9 caps_; + char shadeLangVersion_[64]; +}; + +Thin3DDX9Context::Thin3DDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) : d3d_(d3d), d3dEx_(d3dEx), adapterId_(adapterId), device_(device), deviceEx_(deviceEx) { + CreatePresets(); + d3d->GetAdapterIdentifier(adapterId, 0, &identifier_); + if (!FAILED(device->GetDeviceCaps(&caps_))) { + sprintf(shadeLangVersion_, "PS: %04x VS: %04x", caps_.PixelShaderVersion & 0xFFFF, caps_.VertexShaderVersion & 0xFFFF); + } else { + strcpy(shadeLangVersion_, "N/A"); + } +} + +Thin3DDX9Context::~Thin3DDX9Context() { +} + +Thin3DShader *Thin3DDX9Context::CreateVertexShader(const char *glsl_source, const char *hlsl_source) { + Thin3DDX9Shader *shader = new Thin3DDX9Shader(false); + if (shader->Compile(device_, hlsl_source, "vs_2_0")) { + return shader; + } else { + delete shader; + return NULL; + } +} + +Thin3DShader *Thin3DDX9Context::CreateFragmentShader(const char *glsl_source, const char *hlsl_source) { + Thin3DDX9Shader *shader = new Thin3DDX9Shader(true); + if (shader->Compile(device_, hlsl_source, "ps_2_0")) { + return shader; + } else { + delete shader; + return NULL; + } +} + +Thin3DShaderSet *Thin3DDX9Context::CreateShaderSet(Thin3DShader *vshader, Thin3DShader *fshader) { + if (!vshader || !fshader) { + ELOG("ShaderSet requires both a valid vertex and a fragment shader: %p %p", vshader, fshader); + return NULL; + } + Thin3DDX9ShaderSet *shaderSet = new Thin3DDX9ShaderSet(device_); + shaderSet->vshader = static_cast(vshader); + shaderSet->pshader = static_cast(fshader); + return shaderSet; +} + +Thin3DDepthStencilState *Thin3DDX9Context::CreateDepthStencilState(bool depthTestEnabled, bool depthWriteEnabled, T3DComparison depthCompare) { + Thin3DDX9DepthStencilState *ds = new Thin3DDX9DepthStencilState(); + ds->depthCompare = compareToD3D9[depthCompare]; + ds->depthTestEnabled = depthTestEnabled; + ds->depthWriteEnabled = depthWriteEnabled; + return ds; +} + +Thin3DVertexFormat *Thin3DDX9Context::CreateVertexFormat(const std::vector &components, int stride, Thin3DShader *vshader) { + Thin3DDX9VertexFormat *fmt = new Thin3DDX9VertexFormat(device_, components, stride); + return fmt; +} + +Thin3DBlendState *Thin3DDX9Context::CreateBlendState(const T3DBlendStateDesc &desc) { + Thin3DDX9BlendState *bs = new Thin3DDX9BlendState(); + bs->enabled = desc.enabled; + bs->eqCol = blendEqToD3D9[desc.eqCol]; + bs->srcCol = blendFactorToD3D9[desc.srcCol]; + bs->dstCol = blendFactorToD3D9[desc.dstCol]; + bs->eqAlpha = blendEqToD3D9[desc.eqAlpha]; + bs->srcAlpha = blendFactorToD3D9[desc.srcAlpha]; + bs->dstAlpha = blendFactorToD3D9[desc.dstAlpha]; + // Ignore logic ops, we don't support them in D3D9 + return bs; +} + +Thin3DTexture *Thin3DDX9Context::CreateTexture() { + Thin3DDX9Texture *tex = new Thin3DDX9Texture(device_, deviceEx_); + return tex; +} + +Thin3DTexture *Thin3DDX9Context::CreateTexture(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) { + Thin3DDX9Texture *tex = new Thin3DDX9Texture(device_, deviceEx_, type, format, width, height, depth, mipLevels); + return tex; +} + +void Thin3DDX9Context::SetTextures(int start, int count, Thin3DTexture **textures) { + for (int i = start; i < start + count; i++) { + Thin3DDX9Texture *tex = static_cast(textures[i - start]); + tex->SetToSampler(device_, i); + } +} + +void SemanticToD3D9UsageAndIndex(int semantic, BYTE *usage, BYTE *index) { + *index = 0; + switch (semantic) { + case SEM_POSITION: + *usage = D3DDECLUSAGE_POSITION; + break; + case SEM_NORMAL: + *usage = D3DDECLUSAGE_NORMAL; + break; + case SEM_TANGENT: + *usage = D3DDECLUSAGE_TANGENT; + break; + case SEM_BINORMAL: + *usage = D3DDECLUSAGE_BINORMAL; + break; + case SEM_COLOR0: + *usage = D3DDECLUSAGE_COLOR; + break; + case SEM_TEXCOORD0: + *usage = D3DDECLUSAGE_TEXCOORD; + break; + case SEM_TEXCOORD1: + *usage = D3DDECLUSAGE_TEXCOORD; + *index = 1; + break; + } +} + +static int VertexDataTypeToD3DType(T3DVertexDataType type) { + switch (type) { + case T3DVertexDataType::FLOATx2: return D3DDECLTYPE_FLOAT2; + case T3DVertexDataType::FLOATx3: return D3DDECLTYPE_FLOAT3; + case T3DVertexDataType::FLOATx4: return D3DDECLTYPE_FLOAT4; + case T3DVertexDataType::UNORM8x4: return D3DDECLTYPE_UBYTE4N; // D3DCOLOR? + default: return D3DDECLTYPE_UNUSED; + } +} + +Thin3DDX9VertexFormat::Thin3DDX9VertexFormat(LPDIRECT3DDEVICE9 device, const std::vector &components, int stride) : decl_(NULL) { + D3DVERTEXELEMENT9 *elements = new D3DVERTEXELEMENT9[components.size() + 1]; + size_t i; + for (i = 0; i < components.size(); i++) { + elements[i].Stream = 0; + elements[i].Offset = components[i].offset; + elements[i].Method = D3DDECLMETHOD_DEFAULT; + SemanticToD3D9UsageAndIndex(components[i].semantic, &elements[i].Usage, &elements[i].UsageIndex); + elements[i].Type = VertexDataTypeToD3DType(components[i].type); + } + D3DVERTEXELEMENT9 end = D3DDECL_END(); + // Zero the last one. + memcpy(&elements[i], &end, sizeof(elements[i])); + + HRESULT hr = device->CreateVertexDeclaration(elements, &decl_); + if (FAILED(hr)) { + ELOG("Error creating vertex decl"); + } + delete[] elements; + stride_ = stride; +} + +Thin3DBuffer *Thin3DDX9Context::CreateBuffer(size_t size, uint32_t usageFlags) { + return new Thin3DDX9Buffer(device_, size, usageFlags); +} + +void Thin3DDX9ShaderSet::Apply(LPDIRECT3DDEVICE9 device) { + vshader->Apply(device); + pshader->Apply(device); +} + +void Thin3DDX9Context::SetRenderState(T3DRenderState rs, uint32_t value) { + switch (rs) { + case T3DRenderState::CULL_MODE: + switch (value) { + case T3DCullMode::CCW: device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); break; + case T3DCullMode::CW: device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); break; + case T3DCullMode::NO_CULL: device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); break; + } + break; + } +} + +void Thin3DDX9Context::Draw(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, Thin3DBuffer *vdata, int vertexCount, int offset) { + Thin3DDX9Buffer *vbuf = static_cast(vdata); + Thin3DDX9VertexFormat *fmt = static_cast(format); + Thin3DDX9ShaderSet *ss = static_cast(shaderSet); + + device_->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + device_->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + device_->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + device_->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + device_->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + + vbuf->BindAsVertexBuf(device_, fmt->GetStride(), offset); + ss->Apply(device_); + fmt->Apply(device_); + device_->DrawPrimitive(primToD3D9[prim], offset, vertexCount / 3); +} + +void Thin3DDX9Context::DrawIndexed(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, Thin3DBuffer *vdata, Thin3DBuffer *idata, int vertexCount, int offset) { + Thin3DDX9Buffer *vbuf = static_cast(vdata); + Thin3DDX9Buffer *ibuf = static_cast(idata); + Thin3DDX9VertexFormat *fmt = static_cast(format); + Thin3DDX9ShaderSet *ss = static_cast(shaderSet); + + ss->Apply(device_); + fmt->Apply(device_); + vbuf->BindAsVertexBuf(device_, fmt->GetStride(), offset); + ibuf->BindAsIndexBuf(device_); + device_->DrawIndexedPrimitive(primToD3D9[prim], 0, 0, vertexCount, 0, vertexCount / 3); +} + +void Thin3DDX9Context::DrawUP(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, const void *vdata, int vertexCount) { + Thin3DDX9VertexFormat *fmt = static_cast(format); + Thin3DDX9ShaderSet *ss = static_cast(shaderSet); + + device_->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + device_->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + device_->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + device_->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + device_->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + + ss->Apply(device_); + fmt->Apply(device_); + device_->DrawPrimitiveUP(primToD3D9[prim], vertexCount / 3, vdata, fmt->GetStride()); +} + +static uint32_t SwapRB(uint32_t c) { + return (c & 0xFF00FF00) | ((c >> 16) & 0xFF) | ((c << 16) & 0xFF0000); +} + +void Thin3DDX9Context::Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) { + UINT d3dMask = 0; + if (mask & T3DClear::COLOR) d3dMask |= D3DCLEAR_TARGET; + if (mask & T3DClear::DEPTH) d3dMask |= D3DCLEAR_ZBUFFER; + if (mask & T3DClear::STENCIL) d3dMask |= D3DCLEAR_STENCIL; + + device_->Clear(0, NULL, d3dMask, (D3DCOLOR)SwapRB(colorval), depthVal, stencilVal); +} + +void Thin3DDX9Context::SetScissorEnabled(bool enable) { + device_->SetRenderState(D3DRS_SCISSORTESTENABLE, enable); +} + +void Thin3DDX9Context::SetScissorRect(int left, int top, int width, int height) { + RECT rc; + rc.left = left; + rc.top = top; + rc.right = left + width; + rc.bottom = top + height; + device_->SetScissorRect(&rc); +} + +void Thin3DDX9Context::SetViewports(int count, T3DViewport *viewports) { + D3DVIEWPORT9 vp; + vp.X = (DWORD)viewports[0].TopLeftX; + vp.Y = (DWORD)viewports[0].TopLeftY; + vp.Width = (DWORD)viewports[0].Width; + vp.Height = (DWORD)viewports[0].Height; + vp.MinZ = viewports[0].MinDepth; + vp.MaxZ = viewports[0].MaxDepth; + device_->SetViewport(&vp); +} + +bool Thin3DDX9Shader::Compile(LPDIRECT3DDEVICE9 device, const char *source, const char *profile) { + LPD3DXMACRO defines = NULL; + LPD3DXINCLUDE includes = NULL; + DWORD flags = 0; + LPD3DXBUFFER codeBuffer; + LPD3DXBUFFER errorBuffer; + HRESULT hr = dyn_D3DXCompileShader(source, (UINT)strlen(source), defines, includes, "main", profile, flags, &codeBuffer, &errorBuffer, &constantTable_); + if (FAILED(hr)) { + const char *error = (const char *)errorBuffer->GetBufferPointer(); + OutputDebugStringA(source); + OutputDebugStringA(error); + errorBuffer->Release(); + + if (codeBuffer) + codeBuffer->Release(); + if (constantTable_) + constantTable_->Release(); + return false; + } + + bool success = false; + if (isPixelShader_) { + HRESULT result = device->CreatePixelShader((DWORD *)codeBuffer->GetBufferPointer(), &pshader_); + success = SUCCEEDED(result); + } else { + HRESULT result = device->CreateVertexShader((DWORD *)codeBuffer->GetBufferPointer(), &vshader_); + success = SUCCEEDED(result); + } + +#if 0 + // Just for testing. Will later use to pre populate uniform tables. + + D3DXCONSTANTTABLE_DESC desc; + constantTable_->GetDesc(&desc); + + for (UINT i = 0; i < desc.Constants; i++) { + D3DXHANDLE c = constantTable_->GetConstant(NULL, i); + D3DXCONSTANT_DESC cdesc; + UINT count = 1; + constantTable_->GetConstantDesc(c, &cdesc, &count); + ILOG("%s", cdesc.Name); + } +#endif + + codeBuffer->Release(); + return true; +} + +void Thin3DDX9Shader::SetVector(LPDIRECT3DDEVICE9 device, const char *name, float *value, int n) { + D3DXHANDLE handle = constantTable_->GetConstantByName(NULL, name); + if (handle) { + constantTable_->SetFloatArray(device, handle, value, n); + } +} + +void Thin3DDX9Shader::SetMatrix4x4(LPDIRECT3DDEVICE9 device, const char *name, const Matrix4x4 &value) { + D3DXHANDLE handle = constantTable_->GetConstantByName(NULL, name); + if (handle) { + constantTable_->SetFloatArray(device, handle, value.getReadPtr(), 16); + } +} + +Thin3DContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) { + int d3dx_ver = LoadD3DX9Dynamic(); + if (!d3dx_ver) { + ELOG("Failed to load D3DX9!"); + return NULL; + } + return new Thin3DDX9Context(d3d, d3dEx, adapterId, device, deviceEx); +} diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp new file mode 100644 index 0000000000..8adb4d8582 --- /dev/null +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -0,0 +1,839 @@ +#include +#include +#include +#include + +#include "base/logging.h" +#include "image/zim_load.h" +#include "math/lin/matrix4x4.h" +#include "thin3d/thin3d.h" +#include "gfx/gl_common.h" +#include "gfx_es2/gpu_features.h" +#include "gfx/gl_lost_manager.h" + +static const unsigned short compToGL[] = { + GL_NEVER, + GL_LESS, + GL_EQUAL, + GL_LEQUAL, + GL_GREATER, + GL_NOTEQUAL, + GL_GEQUAL, + GL_ALWAYS +}; + +static const unsigned short blendEqToGL[] = { + GL_FUNC_ADD, + GL_FUNC_SUBTRACT, + GL_FUNC_REVERSE_SUBTRACT, +}; + +static const unsigned short blendFactorToGL[] = { + GL_ZERO, + GL_ONE, + GL_SRC_COLOR, + GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_COLOR, + GL_ONE_MINUS_SRC_ALPHA, + GL_DST_COLOR, + GL_DST_ALPHA, + GL_ONE_MINUS_DST_COLOR, + GL_ONE_MINUS_DST_ALPHA, + GL_CONSTANT_COLOR, +}; + +#ifndef USING_GLES2 +static const unsigned short logicOpToGL[] = { + GL_CLEAR, + GL_SET, + GL_COPY, + GL_COPY_INVERTED, + GL_NOOP, + GL_INVERT, + GL_AND, + GL_NAND, + GL_OR, + GL_NOR, + GL_XOR, + GL_EQUIV, + GL_AND_REVERSE, + GL_AND_INVERTED, + GL_OR_REVERSE, + GL_OR_INVERTED, +}; +#endif + +static const unsigned short primToGL[] = { + GL_POINTS, + GL_LINES, + GL_TRIANGLES, +}; + +static const char *glsl_fragment_prelude = +"#ifdef GL_ES\n" +"precision mediump float;\n" +"#endif\n"; + +static inline void Uint32ToFloat4(uint32_t u, float f[4]) { + f[0] = ((u >> 0) & 0xFF) * (1.0f / 255.0f); + f[1] = ((u >> 8) & 0xFF) * (1.0f / 255.0f); + f[2] = ((u >> 16) & 0xFF) * (1.0f / 255.0f); + f[3] = ((u >> 24) & 0xFF) * (1.0f / 255.0f); +} + +class Thin3DGLBlendState : public Thin3DBlendState { +public: + bool enabled; + GLuint eqCol, eqAlpha; + GLuint srcCol, srcAlpha, dstCol, dstAlpha; + bool logicEnabled; + GLuint logicOp; + // int maskBits; + // uint32_t fixedColor; + + void Apply() { + if (enabled) { + glEnable(GL_BLEND); + glBlendEquationSeparate(eqCol, eqAlpha); + glBlendFuncSeparate(srcCol, dstCol, srcAlpha, dstAlpha); + } else { + glDisable(GL_BLEND); + } + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + // glColorMask(maskBits & 1, (maskBits >> 1) & 1, (maskBits >> 2) & 1, (maskBits >> 3) & 1); + // glBlendColor(fixedColor); + +#if !defined(USING_GLES2) + if (logicEnabled) { + glEnable(GL_LOGIC_OP); + glLogicOp(logicOp); + } else { + glDisable(GL_LOGIC_OP); + } +#endif + } +}; + +class Thin3DGLDepthStencilState : public Thin3DDepthStencilState { +public: + bool depthTestEnabled; + bool depthWriteEnabled; + GLuint depthComp; + // bool stencilTestEnabled; TODO + + void Apply() { + if (depthTestEnabled) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(depthComp); + glDepthMask(depthWriteEnabled); + } else { + glDisable(GL_DEPTH_TEST); + } + glDisable(GL_STENCIL_TEST); + } +}; + +class Thin3DGLBuffer : public Thin3DBuffer, GfxResourceHolder { +public: + Thin3DGLBuffer(size_t size, uint32_t flags) { + glGenBuffers(1, &buffer_); + target_ = (flags & T3DBufferUsage::INDEXDATA) ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER; + usage_ = 0; + if (flags & T3DBufferUsage::DYNAMIC) + usage_ = GL_STREAM_DRAW; + else + usage_ = GL_STATIC_DRAW; + knownSize_ = 0; + register_gl_resource_holder(this); + } + ~Thin3DGLBuffer() override { + unregister_gl_resource_holder(this); + glDeleteBuffers(1, &buffer_); + } + + void SetData(const uint8_t *data, size_t size) override { + Bind(); + glBufferData(target_, size, data, usage_); + knownSize_ = size; + } + + void SubData(const uint8_t *data, size_t offset, size_t size) override { + Bind(); + if (size > knownSize_) { + // Allocate the buffer. + glBufferData(target_, size + offset, NULL, usage_); + knownSize_ = size + offset; + } + glBufferSubData(target_, offset, size, data); + } + void Bind() { + glBindBuffer(target_, buffer_); + } + + void GLLost() override { + ILOG("Recreating vertex buffer after glLost"); + knownSize_ = 0; // Will cause a new glBufferData call. Should genBuffers again though? + glGenBuffers(1, &buffer_); + } + +private: + GLuint buffer_; + GLuint target_; + GLuint usage_; + + size_t knownSize_; +}; + +// Not registering this as a resource holder, instead ShaderSet is registered. It will +// invoke Compile again to recreate the shader then link them together. +class Thin3DGLShader : public Thin3DShader { +public: + Thin3DGLShader(bool isFragmentShader) : shader_(0), type_(0) { + type_ = isFragmentShader ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER; + } + + bool Compile(const char *source); + GLuint GetShader() const { + return shader_; + } + const std::string &GetSource() const { return source_; } + + ~Thin3DGLShader() { + glDeleteShader(shader_); + } + +private: + GLuint shader_; + GLuint type_; + bool ok_; + std::string source_; // So we can recompile in case of context loss. +}; + +bool Thin3DGLShader::Compile(const char *source) { + source_ = source; + shader_ = glCreateShader(type_); + + std::string temp; + // Add the prelude on automatically for fragment shaders. + if (type_ == GL_FRAGMENT_SHADER) { + temp = std::string(glsl_fragment_prelude) + source; + source = temp.c_str(); + } + + glShaderSource(shader_, 1, &source, 0); + glCompileShader(shader_); + GLint success = 0; + glGetShaderiv(shader_, GL_COMPILE_STATUS, &success); + if (!success) { +#define MAX_INFO_LOG_SIZE 2048 + GLchar infoLog[MAX_INFO_LOG_SIZE]; + GLsizei len = 0; + glGetShaderInfoLog(shader_, MAX_INFO_LOG_SIZE, &len, infoLog); + infoLog[len] = '\0'; + glDeleteShader(shader_); + shader_ = 0; + ILOG("%s Shader compile error:\n%s", type_ == GL_FRAGMENT_SHADER ? "Fragment" : "Vertex", infoLog); + } + ok_ = success != 0; + return ok_; +} + +class Thin3DGLVertexFormat : public Thin3DVertexFormat { +public: + void Apply(const void *base = nullptr); + void Unapply(); + void Compile(); + + std::vector components_; + int semanticsMask_; // Fast way to check what semantics to enable/disable. + int stride_; +}; + +struct UniformInfo { + int loc_; +}; + +// TODO: Fold BlendState into this? Seems likely to be right for DX12 etc. +// TODO: Add Uniform Buffer support. +class Thin3DGLShaderSet : public Thin3DShaderSet, GfxResourceHolder { +public: + Thin3DGLShaderSet() { + program_ = 0; + register_gl_resource_holder(this); + } + ~Thin3DGLShaderSet() { + unregister_gl_resource_holder(this); + vshader->Release(); + fshader->Release(); + glDeleteProgram(program_); + } + bool Link(); + + void Apply(); + void Unapply(); + + int GetUniformLoc(const char *name); + + void SetVector(const char *name, float *value, int n); + void SetMatrix4x4(const char *name, const Matrix4x4 &value) override; + + void GLLost() { + vshader->Compile(vshader->GetSource().c_str()); + fshader->Compile(fshader->GetSource().c_str()); + Link(); + } + + Thin3DGLShader *vshader; + Thin3DGLShader *fshader; + +private: + GLuint program_; + std::map uniforms_; +}; + +class Thin3DGLContext : public Thin3DContext { +public: + Thin3DGLContext(); + virtual ~Thin3DGLContext(); + + Thin3DDepthStencilState *CreateDepthStencilState(bool depthTestEnabled, bool depthWriteEnabled, T3DComparison depthCompare) override; + Thin3DBlendState *CreateBlendState(const T3DBlendStateDesc &desc) override; + Thin3DBuffer *CreateBuffer(size_t size, uint32_t usageFlags) override; + Thin3DShaderSet *CreateShaderSet(Thin3DShader *vshader, Thin3DShader *fshader) override; + Thin3DVertexFormat *CreateVertexFormat(const std::vector &components, int stride, Thin3DShader *vshader) override; + Thin3DTexture *CreateTexture(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) override; + Thin3DTexture *CreateTexture() override; + + // Bound state objects + void SetBlendState(Thin3DBlendState *state) override { + Thin3DGLBlendState *s = static_cast(state); + s->Apply(); + } + + // Bound state objects + void SetDepthStencilState(Thin3DDepthStencilState *state) override { + Thin3DGLDepthStencilState *s = static_cast(state); + s->Apply(); + } + + // The implementation makes the choice of which shader code to use. + Thin3DShader *CreateVertexShader(const char *glsl_source, const char *hlsl_source); + Thin3DShader *CreateFragmentShader(const char *glsl_source, const char *hlsl_source); + + void SetScissorEnabled(bool enable) override { + if (enable) { + glEnable(GL_SCISSOR_TEST); + } else { + glDisable(GL_SCISSOR_TEST); + } + } + + void SetScissorRect(int left, int top, int width, int height) override { + glScissor(left, targetHeight_ - (top + height), width, height); + } + + void SetViewports(int count, T3DViewport *viewports) override { + // TODO: Add support for multiple viewports. + glViewport(viewports[0].TopLeftX, viewports[0].TopLeftY, viewports[0].Width, viewports[0].Height); +#if defined(USING_GLES2) + glDepthRangef(viewports[0].MinDepth, viewports[0].MaxDepth); +#else + glDepthRange(viewports[0].MinDepth, viewports[0].MaxDepth); +#endif + } + + void SetTextures(int start, int count, Thin3DTexture **textures) override; + + void SetRenderState(T3DRenderState rs, uint32_t value) override; + + // TODO: Add more sophisticated draws. + void Draw(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, Thin3DBuffer *vdata, int vertexCount, int offset) override; + void DrawIndexed(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, Thin3DBuffer *vdata, Thin3DBuffer *idata, int vertexCount, int offset) override; + void DrawUP(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, const void *vdata, int vertexCount) override; + void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override; + + const char *GetInfoString(T3DInfo info) const override { + // TODO: Make these actually query the right information + switch (info) { + case APINAME: + if (gl_extensions.IsGLES) { + return "OpenGL ES"; + } else { + return "OpenGL"; + } + case VENDORSTRING: return (const char *)glGetString(GL_VENDOR); + case VENDOR: + switch (gl_extensions.gpuVendor) { + case GPU_VENDOR_AMD: return "VENDOR_AMD"; + case GPU_VENDOR_POWERVR: return "VENDOR_POWERVR"; + case GPU_VENDOR_NVIDIA: return "VENDOR_NVIDIA"; + case GPU_VENDOR_INTEL: return "VENDOR_INTEL"; + case GPU_VENDOR_ADRENO: return "VENDOR_ADRENO"; + case GPU_VENDOR_ARM: return "VENDOR_ARM"; + case GPU_VENDOR_BROADCOM: return "VENDOR_BROADCOM"; + case GPU_VENDOR_UNKNOWN: + default: + return "VENDOR_UNKNOWN"; + } + break; + case RENDERER: return (const char *)glGetString(GL_RENDERER); + case SHADELANGVERSION: return (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); + case APIVERSION: return (const char *)glGetString(GL_VERSION); + default: return "?"; + } + } +}; + +Thin3DGLContext::Thin3DGLContext() { + CreatePresets(); +} + +Thin3DGLContext::~Thin3DGLContext() { +} + +Thin3DVertexFormat *Thin3DGLContext::CreateVertexFormat(const std::vector &components, int stride, Thin3DShader *vshader) { + Thin3DGLVertexFormat *fmt = new Thin3DGLVertexFormat(); + fmt->components_ = components; + fmt->stride_ = stride; + fmt->Compile(); + return fmt; +} + +GLuint TypeToTarget(T3DTextureType type) { + switch (type) { +#ifndef USING_GLES2 + case LINEAR1D: return GL_TEXTURE_1D; +#endif + case LINEAR2D: return GL_TEXTURE_2D; + case LINEAR3D: return GL_TEXTURE_3D; + case CUBE: return GL_TEXTURE_CUBE_MAP; +#ifndef USING_GLES2 + case ARRAY1D: return GL_TEXTURE_1D_ARRAY; +#endif + case ARRAY2D: return GL_TEXTURE_2D_ARRAY; + default: return GL_NONE; + } +} + +class Thin3DGLTexture : public Thin3DTexture, GfxResourceHolder { +public: + Thin3DGLTexture() : tex_(0), target_(0) { + width_ = 0; + height_ = 0; + depth_ = 0; + glGenTextures(1, &tex_); + register_gl_resource_holder(this); + } + Thin3DGLTexture(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) : format_(format), tex_(0), target_(TypeToTarget(type)), mipLevels_(mipLevels) { + width_ = width; + height_ = height; + depth_ = depth; + glGenTextures(1, &tex_); + register_gl_resource_holder(this); + } + ~Thin3DGLTexture() { + unregister_gl_resource_holder(this); + Destroy(); + } + + bool Create(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) { + format_ = format; + target_ = TypeToTarget(type); + mipLevels_ = mipLevels; + width_ = width; + height_ = height; + depth_ = depth; + return true; + } + + void Destroy() { + if (tex_) { + glDeleteTextures(1, &tex_); + tex_ = 0; + } + } + void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override; + void AutoGenMipmaps() override; + + void Bind() { + glBindTexture(target_, tex_); + } + + void GLLost() { + if (!filename_.empty()) { + if (LoadFromFile(filename_.c_str())) { + ILOG("Reloaded lost texture %s", filename_.c_str()); + } else { + ELOG("Failed to reload lost texture %s", filename_.c_str()); + } + } else { + WLOG("Texture %p cannot be restored - has no filename", this); + tex_ = 0; + } + } + void Finalize(int zim_flags); + +private: + GLuint tex_; + GLuint target_; + + T3DImageFormat format_; + int mipLevels_; +}; + +Thin3DTexture *Thin3DGLContext::CreateTexture() { + return new Thin3DGLTexture(); +} + +Thin3DTexture *Thin3DGLContext::CreateTexture(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) { + return new Thin3DGLTexture(type, format, width, height, depth, mipLevels); +} + +void Thin3DGLTexture::AutoGenMipmaps() { + Bind(); + glGenerateMipmap(target_); +} + +void Thin3DGLTexture::SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) { + int internalFormat; + int format; + int type; + switch (format_) { + case RGBA8888: + internalFormat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + break; + case RGBA4444: + internalFormat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_SHORT_4_4_4_4; + break; + default: + return; + } + + Bind(); + switch (target_) { + case GL_TEXTURE_2D: + glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width_, height_, 0, format, type, data); + break; + default: + ELOG("Thin3D GL: Targets other than GL_TEXTURE_2D not yet supported"); + break; + } +} + +bool isPowerOf2(int n) { + return n == 1 || (n & (n - 1)) == 0; +} + +void Thin3DGLTexture::Finalize(int zim_flags) { + GLenum wrap = GL_REPEAT; + if ((zim_flags & ZIM_CLAMP) || !isPowerOf2(width_) || !isPowerOf2(height_)) + wrap = GL_CLAMP_TO_EDGE; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if ((zim_flags & (ZIM_HAS_MIPS | ZIM_GEN_MIPS))) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } +} + + +void Thin3DGLVertexFormat::Compile() { + int sem = 0; + for (int i = 0; i < (int)components_.size(); i++) { + sem |= 1 << components_[i].semantic; + } + semanticsMask_ = sem; + // TODO : Compute stride as well? +} + +Thin3DDepthStencilState *Thin3DGLContext::CreateDepthStencilState(bool depthTestEnabled, bool depthWriteEnabled, T3DComparison depthCompare) { + Thin3DGLDepthStencilState *ds = new Thin3DGLDepthStencilState(); + ds->depthTestEnabled = depthTestEnabled; + ds->depthWriteEnabled = depthWriteEnabled; + ds->depthComp = compToGL[depthCompare]; + return ds; +} + +Thin3DBlendState *Thin3DGLContext::CreateBlendState(const T3DBlendStateDesc &desc) { + Thin3DGLBlendState *bs = new Thin3DGLBlendState(); + bs->enabled = desc.enabled; + bs->eqCol = blendEqToGL[desc.eqCol]; + bs->srcCol = blendFactorToGL[desc.srcCol]; + bs->dstCol = blendFactorToGL[desc.dstCol]; + bs->eqAlpha = blendEqToGL[desc.eqAlpha]; + bs->srcAlpha = blendFactorToGL[desc.srcAlpha]; + bs->dstAlpha = blendFactorToGL[desc.dstAlpha]; +#ifndef USING_GLES2 + bs->logicEnabled = desc.logicEnabled; + bs->logicOp = logicOpToGL[desc.logicOp]; +#endif + return bs; +} + +Thin3DBuffer *Thin3DGLContext::CreateBuffer(size_t size, uint32_t usageFlags) { + return new Thin3DGLBuffer(size, usageFlags); +} + +Thin3DShaderSet *Thin3DGLContext::CreateShaderSet(Thin3DShader *vshader, Thin3DShader *fshader) { + if (!vshader || !fshader) { + ELOG("ShaderSet requires both a valid vertex and a fragment shader: %p %p", vshader, fshader); + return NULL; + } + Thin3DGLShaderSet *shaderSet = new Thin3DGLShaderSet(); + vshader->AddRef(); + fshader->AddRef(); + shaderSet->vshader = static_cast(vshader); + shaderSet->fshader = static_cast(fshader); + if (shaderSet->Link()) { + return shaderSet; + } else { + delete shaderSet; + return NULL; + } +} + +void Thin3DGLContext::SetTextures(int start, int count, Thin3DTexture **textures) { + for (int i = start; i < start + count; i++) { + Thin3DGLTexture *glTex = static_cast(textures[i]); + glActiveTexture(GL_TEXTURE0 + i); + glTex->Bind(); + } + glActiveTexture(GL_TEXTURE0); +} + + +Thin3DShader *Thin3DGLContext::CreateVertexShader(const char *glsl_source, const char *hlsl_source) { + Thin3DGLShader *shader = new Thin3DGLShader(false); + if (shader->Compile(glsl_source)) { + return shader; + } else { + shader->Release(); + return nullptr; + } +} + +Thin3DShader *Thin3DGLContext::CreateFragmentShader(const char *glsl_source, const char *hlsl_source) { + Thin3DGLShader *shader = new Thin3DGLShader(true); + if (shader->Compile(glsl_source)) { + return shader; + } else { + shader->Release(); + return nullptr; + } +} + +bool Thin3DGLShaderSet::Link() { + program_ = glCreateProgram(); + glAttachShader(program_, vshader->GetShader()); + glAttachShader(program_, fshader->GetShader()); + + // Bind all the common vertex data points. Mismatching ones will be ignored. + glBindAttribLocation(program_, SEM_POSITION, "Position"); + glBindAttribLocation(program_, SEM_COLOR0, "Color0"); + glBindAttribLocation(program_, SEM_TEXCOORD0, "TexCoord0"); + glBindAttribLocation(program_, SEM_NORMAL, "Normal"); + glBindAttribLocation(program_, SEM_TANGENT, "Tangent"); + glBindAttribLocation(program_, SEM_BINORMAL, "Binormal"); + glLinkProgram(program_); + + GLint linkStatus = GL_FALSE; + glGetProgramiv(program_, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = new char[bufLength]; + glGetProgramInfoLog(program_, bufLength, NULL, buf); + ELOG("Could not link program:\n %s", buf); + // We've thrown out the source at this point. Might want to do something about that. +#ifdef _WIN32 + OutputDebugStringUTF8(buf); +#endif + delete[] buf; + } + return false; + } + + // Auto-initialize samplers. + glUseProgram(program_); + for (int i = 0; i < 4; i++) { + char temp[256]; + sprintf(temp, "Sampler%i", i); + int samplerLoc = GetUniformLoc(temp); + if (samplerLoc != -1) { + glUniform1i(samplerLoc, i); + } + } + + // Here we could (using glGetAttribLocation) save a bitmask about which pieces of vertex data are used in the shader + // and then AND it with the vertex format bitmask later... + return true; +} + +int Thin3DGLShaderSet::GetUniformLoc(const char *name) { + auto iter = uniforms_.find(name); + int loc = -1; + if (iter != uniforms_.end()) { + loc = iter->second.loc_; + } else { + loc = glGetUniformLocation(program_, name); + UniformInfo info; + info.loc_ = loc; + uniforms_[name] = info; + } + return loc; +} + +void Thin3DGLShaderSet::SetVector(const char *name, float *value, int n) { + glUseProgram(program_); + int loc = GetUniformLoc(name); + if (loc != -1) { + switch (n) { + case 1: glUniform1fv(loc, 1, value); break; + case 2: glUniform1fv(loc, 2, value); break; + case 3: glUniform1fv(loc, 3, value); break; + case 4: glUniform1fv(loc, 4, value); break; + } + } +} + +void Thin3DGLShaderSet::SetMatrix4x4(const char *name, const Matrix4x4 &value) { + glUseProgram(program_); + int loc = GetUniformLoc(name); + if (loc != -1) { + glUniformMatrix4fv(loc, 1, false, value.getReadPtr()); + } +} + +void Thin3DGLShaderSet::Apply() { + glUseProgram(program_); +} + +void Thin3DGLShaderSet::Unapply() { + glUseProgram(0); +} + +void Thin3DGLContext::SetRenderState(T3DRenderState rs, uint32_t value) { + switch (rs) { + case T3DRenderState::CULL_MODE: + switch (value) { + case T3DCullMode::NO_CULL: glDisable(GL_CULL_FACE); break; + case T3DCullMode::CCW: glEnable(GL_CULL_FACE); glCullFace(GL_CCW); break; // TODO: Should be GL_FRONT + case T3DCullMode::CW: glEnable(GL_CULL_FACE); glCullFace(GL_CW); break; + } + break; + } +} + +void Thin3DGLContext::Draw(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, Thin3DBuffer *vdata, int vertexCount, int offset) { + Thin3DGLShaderSet *ss = static_cast(shaderSet); + Thin3DGLBuffer *vbuf = static_cast(vdata); + Thin3DGLVertexFormat *fmt = static_cast(format); + + vbuf->Bind(); + fmt->Apply(); + ss->Apply(); + + glDrawArrays(primToGL[prim], offset, vertexCount); + + ss->Unapply(); + fmt->Unapply(); +} + +void Thin3DGLContext::DrawIndexed(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, Thin3DBuffer *vdata, Thin3DBuffer *idata, int vertexCount, int offset) { + Thin3DGLShaderSet *ss = static_cast(shaderSet); + Thin3DGLBuffer *vbuf = static_cast(vdata); + Thin3DGLBuffer *ibuf = static_cast(idata); + Thin3DGLVertexFormat *fmt = static_cast(format); + + vbuf->Bind(); + ibuf->Bind(); + fmt->Apply(); + ss->Apply(); + + glDrawElements(primToGL[prim], offset, GL_INT, 0); + + ss->Unapply(); + fmt->Unapply(); +} + +void Thin3DGLContext::DrawUP(T3DPrimitive prim, Thin3DShaderSet *shaderSet, Thin3DVertexFormat *format, const void *vdata, int vertexCount) { + Thin3DGLShaderSet *ss = static_cast(shaderSet); + Thin3DGLVertexFormat *fmt = static_cast(format); + + fmt->Apply(vdata); + ss->Apply(); + + glDrawArrays(primToGL[prim], 0, vertexCount); + + ss->Unapply(); + fmt->Unapply(); +} + +void Thin3DGLContext::Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) { + float col[4]; + Uint32ToFloat4(colorval, col); + GLuint glMask = 0; + if (mask & T3DClear::COLOR) { + glClearColor(col[0], col[1], col[2], col[3]); + glMask |= GL_COLOR_BUFFER_BIT; + } + if (mask & T3DClear::DEPTH) { +#if defined(USING_GLES2) + glClearDepthf(depthVal); +#else + glClearDepth(depthVal); +#endif + glMask |= GL_DEPTH_BUFFER_BIT; + } + if (mask & T3DClear::STENCIL) { + glClearStencil(stencilVal); + glMask |= GL_STENCIL_BUFFER_BIT; + } + glClear(glMask); +} + +Thin3DContext *T3DCreateGLContext() { + return new Thin3DGLContext(); +} + +void Thin3DGLVertexFormat::Apply(const void *base) { + for (int i = 0; i < SEM_MAX; i++) { + if (semanticsMask_ & (1 << i)) { + glEnableVertexAttribArray(i); + } + } + intptr_t b = (intptr_t)base; + for (size_t i = 0; i < components_.size(); i++) { + switch (components_[i].type) { + case FLOATx2: + glVertexAttribPointer(components_[i].semantic, 2, GL_FLOAT, GL_FALSE, stride_, (void *)(b + (intptr_t)components_[i].offset)); + break; + case FLOATx3: + glVertexAttribPointer(components_[i].semantic, 3, GL_FLOAT, GL_FALSE, stride_, (void *)(b + (intptr_t)components_[i].offset)); + break; + case FLOATx4: + glVertexAttribPointer(components_[i].semantic, 4, GL_FLOAT, GL_FALSE, stride_, (void *)(b + (intptr_t)components_[i].offset)); + break; + case UNORM8x4: + glVertexAttribPointer(components_[i].semantic, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride_, (void *)(b + (intptr_t)components_[i].offset)); + break; + case INVALID: + ELOG("Thin3DGLVertexFormat: Invalid component type applied."); + } + } +} + +void Thin3DGLVertexFormat::Unapply() { + for (int i = 0; i < SEM_MAX; i++) { + if (semanticsMask_ & (1 << i)) { + glDisableVertexAttribArray(i); + } + } +} diff --git a/ext/native/thread/executor.cpp b/ext/native/thread/executor.cpp new file mode 100644 index 0000000000..abba1fb809 --- /dev/null +++ b/ext/native/thread/executor.cpp @@ -0,0 +1,10 @@ +#include "thread/executor.h" +#include "base/functional.h" + +namespace threading { + +void SameThreadExecutor::Run(std::function func) { + func(); +} + +} // namespace threading diff --git a/ext/native/thread/executor.h b/ext/native/thread/executor.h new file mode 100644 index 0000000000..dcc7cd8175 --- /dev/null +++ b/ext/native/thread/executor.h @@ -0,0 +1,18 @@ +#pragma once + +#include "base/functional.h" + +namespace threading { + +// Stuff that can execute other stuff, like threadpools, should inherit from this. +class Executor { + public: + virtual void Run(std::function func) = 0; +}; + +class SameThreadExecutor : public Executor { + public: + virtual void Run(std::function func); +}; + +} // namespace threading diff --git a/ext/native/thread/prioritizedworkqueue.cpp b/ext/native/thread/prioritizedworkqueue.cpp new file mode 100644 index 0000000000..c747a36ba8 --- /dev/null +++ b/ext/native/thread/prioritizedworkqueue.cpp @@ -0,0 +1,96 @@ +#include "base/functional.h" +#include "base/logging.h" +#include "base/timeutil.h" +#include "thread/thread.h" +#include "thread/prioritizedworkqueue.h" + +PrioritizedWorkQueue::~PrioritizedWorkQueue() { + if (!done_) { + ELOG("PrioritizedWorkQueue destroyed but not done!"); + } +} + +void PrioritizedWorkQueue::Add(PrioritizedWorkQueueItem *item) { + lock_guard guard(mutex_); + queue_.push_back(item); + notEmpty_.notify_one(); +} + +void PrioritizedWorkQueue::Stop() { + lock_guard guard(mutex_); + done_ = true; + notEmpty_.notify_one(); +} + +void PrioritizedWorkQueue::Flush() { + if (queue_.empty()) + return; + lock_guard guard(mutex_); + for (auto iter = queue_.begin(); iter != queue_.end(); ++iter) { + delete *iter; + } + queue_.clear(); +} + + +// The worker should simply call this in a loop. Will block when appropriate. +PrioritizedWorkQueueItem *PrioritizedWorkQueue::Pop() { + lock_guard guard(mutex_); + if (done_) { + return 0; + } + + while (queue_.empty()) { + notEmpty_.wait(mutex_); + if (done_) { + return 0; + } + } + + // Find the top priority item (lowest value). + float best_prio = std::numeric_limits::infinity(); + std::vector::iterator best = queue_.end(); + for (auto iter = queue_.begin(); iter != queue_.end(); ++iter) { + if ((*iter)->priority() < best_prio) { + best = iter; + best_prio = (*iter)->priority(); + } + } + + if (best != queue_.end()) { + PrioritizedWorkQueueItem *poppedItem = *best; + queue_.erase(best); + return poppedItem; + } else { + // Not really sure how this can happen, but let's be safe. + return 0; + } +} + +// TODO: This feels ugly. Revisit later. + +static std::thread *workThread; + +static void threadfunc(PrioritizedWorkQueue *wq) { + while (true) { + PrioritizedWorkQueueItem *item = wq->Pop(); + if (!item) { + if (wq->Done()) + break; + } else { + item->run(); + delete item; + } + } +} + +void ProcessWorkQueueOnThreadWhile(PrioritizedWorkQueue *wq) { + workThread = new std::thread(std::bind(&threadfunc, wq)); +} + +void StopProcessingWorkQueue(PrioritizedWorkQueue *wq) { + wq->Stop(); + workThread->join(); + delete workThread; + workThread = 0; +} diff --git a/ext/native/thread/prioritizedworkqueue.h b/ext/native/thread/prioritizedworkqueue.h new file mode 100644 index 0000000000..9f5241c0e8 --- /dev/null +++ b/ext/native/thread/prioritizedworkqueue.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include + +#include "base/basictypes.h" +#include "base/mutex.h" +#include "thread/threadutil.h" + +// Priorities can change dynamically. +// Try to make priority() fast, it will be called a lot. + +class PrioritizedWorkQueueItem { +public: + PrioritizedWorkQueueItem() {} + virtual ~PrioritizedWorkQueueItem() {} + virtual void run() = 0; + virtual float priority() = 0; // Low priority value = high priority! + +private: + DISALLOW_COPY_AND_ASSIGN(PrioritizedWorkQueueItem); +}; + +class PrioritizedWorkQueue { +public: + PrioritizedWorkQueue() : done_(false) {} + ~PrioritizedWorkQueue(); + // Takes ownership. + void Add(PrioritizedWorkQueueItem *item); + + // The worker should simply call this in a loop. Will block when appropriate. + PrioritizedWorkQueueItem *Pop(); + + void Flush(); + bool Done() { return done_; } + void Stop(); + +private: + bool done_; + recursive_mutex mutex_; + condition_variable notEmpty_; + + std::vector queue_; + + DISALLOW_COPY_AND_ASSIGN(PrioritizedWorkQueue); +}; + + +// Starts up a thread that keeps trying to run this workqueue. +// TODO: This feels ugly. Revisit later. +void ProcessWorkQueueOnThreadWhile(PrioritizedWorkQueue *wq); +void StopProcessingWorkQueue(PrioritizedWorkQueue *wq); diff --git a/ext/native/thread/thread.h b/ext/native/thread/thread.h new file mode 100644 index 0000000000..1a1b37615d --- /dev/null +++ b/ext/native/thread/thread.h @@ -0,0 +1,326 @@ + +#ifndef STD_THREAD_H_ +#define STD_THREAD_H_ + +#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) +#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) + +#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ && !defined(ANDROID) && !defined(__SYMBIAN32__) +// GCC 4.4 provides +#ifndef _GLIBCXX_USE_SCHED_YIELD +#define _GLIBCXX_USE_SCHED_YIELD +#endif +#include +#else + +// partial std::thread implementation for win32/pthread + +#include + +#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__) +#define USE_RVALUE_REFERENCES +#endif + +//#ifdef __APPLE__ +//#import +//#endif + +#if defined(_WIN32) +// WIN32 + +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include + +#if defined(_MSC_VER) && defined(_MT) +// When linking with LIBCMT (the multithreaded C library), Microsoft recommends +// using _beginthreadex instead of CreateThread. +#define USE_BEGINTHREADEX +#include +#endif + +#ifdef USE_BEGINTHREADEX +#define THREAD_ID unsigned +#define THREAD_RETURN unsigned __stdcall +#else +#define THREAD_ID DWORD +#define THREAD_RETURN DWORD WINAPI +#endif +#define THREAD_HANDLE HANDLE + +#else +// PTHREAD + +#include + +#ifndef _POSIX_THREADS +#error unsupported platform (no pthreads?) +#endif + +#include + +#define THREAD_ID pthread_t +#define THREAD_HANDLE pthread_t +#define THREAD_RETURN void* + +#endif + +namespace std +{ + +class thread +{ +public: + typedef THREAD_HANDLE native_handle_type; + + class id + { + friend class thread; + public: + id() : m_thread(0) {} + id(THREAD_ID _id) : m_thread(_id) {} + + bool operator==(const id& rhs) const + { + return m_thread == rhs.m_thread; + } + + bool operator!=(const id& rhs) const + { + return !(*this == rhs); + } + + bool operator<(const id& rhs) const + { + return m_thread < rhs.m_thread; + } + + private: + THREAD_ID m_thread; + }; + + // no variadic template support in msvc + //template + //thread(C&& func, A&&... args); + + template + thread(C func) + { + StartThread(new Func(func)); + } + + template + thread(C func, A arg) + { + StartThread(new FuncArg(func, arg)); + } + + thread() /*= default;*/ {} + +#ifdef USE_RVALUE_REFERENCES + thread(const thread&) /*= delete*/; + + thread(thread&& other) + { +#else + thread(const thread& t) + { + // ugly const_cast to get around lack of rvalue references + thread& other = const_cast(t); +#endif + swap(other); + } + +#ifdef USE_RVALUE_REFERENCES + thread& operator=(const thread&) /*= delete*/; + + thread& operator=(thread&& other) + { +#else + thread& operator=(const thread& t) + { + // ugly const_cast to get around lack of rvalue references + thread& other = const_cast(t); +#endif + if (joinable()) + detach(); + swap(other); + return *this; + } + + ~thread() + { + if (joinable()) + detach(); + } + + bool joinable() const + { + return m_id != id(); + } + + id get_id() const + { + return m_id; + } + + native_handle_type native_handle() + { +#ifdef _WIN32 + return m_handle; +#else + return m_id.m_thread; +#endif + } + + void join() + { +#ifdef _WIN32 + WaitForSingleObject(m_handle, INFINITE); + detach(); +#else + pthread_join(m_id.m_thread, NULL); + m_id = id(); +#endif + } + + void detach() + { +#ifdef _WIN32 + CloseHandle(m_handle); +#else + pthread_detach(m_id.m_thread); +#endif + m_id = id(); + } + + void swap(thread& other) + { + std::swap(m_id, other.m_id); +#ifdef _WIN32 + std::swap(m_handle, other.m_handle); +#endif + } + + static unsigned hardware_concurrency() + { +#ifdef _WIN32 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return static_cast(sysinfo.dwNumberOfProcessors); +#else + return 0; +#endif + } + +private: + id m_id; + +#ifdef _WIN32 + native_handle_type m_handle; +#endif + + template + void StartThread(F* param) + { +#ifdef USE_BEGINTHREADEX + m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete, param, 0, &m_id.m_thread); +#elif defined(_WIN32) + m_handle = CreateThread(NULL, 0, &RunAndDelete, param, 0, &m_id.m_thread); +#else + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, 1024 * 1024); + if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete, param)) + m_id = id(); +#endif + } + + template + class Func + { + public: + Func(C _func) : func(_func) {} + + void Run() { func(); } + + private: +// Both Visual Studio 2012 & 2013 need the following ifdef, or else they complain about losing const-volatile qualifiers: +// Error 23 error C3848: expression having type 'const std::_Bind' would lose some const-volatile qualifiers in order to call 'void std::_Bind::operator ()<>(void)' (thread\prioritizedworkqueue.cpp) + +// Error 24 error C3848: expression having type 'const std::_Bind,WorkerThread *const >' +// would lose some const-volatile qualifiers in order to call +// 'void std::_Bind,WorkerThread *const >::operator ()<>(void)' (thread\threadpool.cpp) + +// Error 25 error C3848 : expression having type 'const std::_Bind),void,http::Download,std::shared_ptr>,http::Download *const ,std::shared_ptr &>' +// would lose some const - volatile qualifiers in order to call +// 'void std::_Bind),void,http::Download,std::shared_ptr>,http::Download *const ,std::shared_ptr &>::operator ()<>(void)' (net\http_client.cpp) +#if _MSC_VER >= 1700 + C func; +#else + C const func; +#endif + }; + + template + class FuncArg + { + public: + FuncArg(C _func, A _arg) : func(_func), arg(_arg) {} + + void Run() { func(arg); } + + private: + C const func; + A arg; + }; + + template + static THREAD_RETURN RunAndDelete(void* param) + { +#ifdef __APPLE__ + // NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; +#endif + static_cast(param)->Run(); + delete static_cast(param); +#ifdef __APPLE__ + // [pool release]; +#endif + return 0; + } +}; + +namespace this_thread +{ + +inline void yield() +{ +#ifdef _WIN32 + SwitchToThread(); +#else + sleep(0); +#endif +} + +inline thread::id get_id() +{ +#ifdef _WIN32 + return GetCurrentThreadId(); +#else + return pthread_self(); +#endif +} + +} // namespace this_thread + +} // namespace std + +#undef USE_RVALUE_REFERENCES +#undef USE_BEGINTHREADEX +#undef THREAD_ID +#undef THREAD_RETURN +#undef THREAD_HANDLE + +#endif +#endif diff --git a/ext/native/thread/threadpool.cpp b/ext/native/thread/threadpool.cpp new file mode 100644 index 0000000000..b89447d084 --- /dev/null +++ b/ext/native/thread/threadpool.cpp @@ -0,0 +1,121 @@ +#include "base/logging.h" +#include "threadpool.h" + +///////////////////////////// WorkerThread + +WorkerThread::WorkerThread() : active(true), started(false) { + thread = new std::thread(std::bind(&WorkerThread::WorkFunc, this)); + doneMutex.lock(); + while(!started) { }; +} + +WorkerThread::~WorkerThread() { + mutex.lock(); + active = false; + signal.notify_one(); + mutex.unlock(); + thread->join(); + delete thread; +} + +void WorkerThread::Process(const std::function& work) { + mutex.lock(); + work_ = work; + signal.notify_one(); + mutex.unlock(); +} + +void WorkerThread::WaitForCompletion() { + done.wait(doneMutex); +} + +void WorkerThread::WorkFunc() { + mutex.lock(); + started = true; + while (active) { + signal.wait(mutex); + if (active) { + work_(); + doneMutex.lock(); + done.notify_one(); + doneMutex.unlock(); + } + } +} + +LoopWorkerThread::LoopWorkerThread() : WorkerThread(true) { + thread = new std::thread(std::bind(&LoopWorkerThread::WorkFunc, this)); + doneMutex.lock(); + while(!started) { }; +} + +void LoopWorkerThread::Process(const std::function &work, int start, int end) { + mutex.lock(); + work_ = work; + start_ = start; + end_ = end; + signal.notify_one(); + mutex.unlock(); +} + +void LoopWorkerThread::WorkFunc() { + mutex.lock(); + started = true; + while (active) { + signal.wait(mutex); + if (active) { + work_(start_, end_); + doneMutex.lock(); + done.notify_one(); + doneMutex.unlock(); + } + } +} + +///////////////////////////// ThreadPool + +ThreadPool::ThreadPool(int numThreads) : workersStarted(false) { + if (numThreads <= 0) { + numThreads_ = 1; + ILOG("ThreadPool: Bad number of threads %i", numThreads); + } else if (numThreads > 8) { + ILOG("ThreadPool: Capping number of threads to 8 (was %i)", numThreads); + numThreads_ = 8; + } else { + numThreads_ = numThreads; + } +} + +void ThreadPool::StartWorkers() { + if (!workersStarted) { + for(int i = 0; i < numThreads_; ++i) { + workers.push_back(std::make_shared()); + } + workersStarted = true; + } +} + +void ThreadPool::ParallelLoop(const std::function &loop, int lower, int upper) { + int range = upper - lower; + if (range >= numThreads_ * 2) { // don't parallelize tiny loops (this could be better, maybe add optional parameter that estimates work per iteration) + lock_guard guard(mutex); + StartWorkers(); + + // could do slightly better load balancing for the generic case, + // but doesn't matter since all our loops are power of 2 + int chunk = range / numThreads_; + int s = lower; + for (int i = 0; i < numThreads_ - 1; ++i) { + workers[i]->Process(loop, s, s+chunk); + s+=chunk; + } + // This is the final chunk. + loop(s, upper); + for (int i = 0; i < numThreads_ - 1; ++i) { + workers[i]->WaitForCompletion(); + } + } else { + loop(lower, upper); + } +} + diff --git a/ext/native/thread/threadpool.h b/ext/native/thread/threadpool.h new file mode 100644 index 0000000000..0a2a2f9722 --- /dev/null +++ b/ext/native/thread/threadpool.h @@ -0,0 +1,73 @@ +#pragma once + +#include "thread.h" +#include "base/mutex.h" +#include "base/functional.h" + +// This is the simplest possible worker implementation I can think of +// but entirely sufficient for the given purpose. +// Only handles a single item of work at a time. +class WorkerThread { +public: + WorkerThread(); + virtual ~WorkerThread(); + + // submit a new work item + void Process(const std::function& work); + // wait for a submitted work item to be completed + void WaitForCompletion(); + +protected: + WorkerThread(bool ignored) : active(true), started(false) {} + virtual void WorkFunc(); + + std::thread *thread; // the worker thread + ::condition_variable signal; // used to signal new work + ::condition_variable done; // used to signal work completion + ::recursive_mutex mutex, doneMutex; // associated with each respective condition variable + volatile bool active, started; + +private: + std::function work_; // the work to be done by this thread + + WorkerThread(const WorkerThread& other); // prevent copies + void operator =(const WorkerThread &other); +}; + +class LoopWorkerThread : public WorkerThread { +public: + LoopWorkerThread(); + void Process(const std::function &work, int start, int end); + +protected: + virtual void WorkFunc(); + +private: + int start_; + int end_; + std::function work_; // the work to be done by this thread +}; + +// A thread pool manages a set of worker threads, and allows the execution of parallel loops on them +// individual parallel loops are fully sequentialized to simplify synchronization, which should not +// be a problem as they should each use the entire system +class ThreadPool { +public: + ThreadPool(int numThreads); + // don't need a destructor, "workers" is cleared on delete, + // leading to the stopping and joining of all worker threads (RAII and all that) + + void ParallelLoop(const std::function &loop, int lower, int upper); + +private: + int numThreads_; + std::vector> workers; + ::recursive_mutex mutex; // used to sequentialize loop execution + + bool workersStarted; + void StartWorkers(); + + ThreadPool(const ThreadPool& other); // prevent copies + void operator =(const ThreadPool &other); +}; + diff --git a/ext/native/thread/threadutil.cpp b/ext/native/thread/threadutil.cpp new file mode 100644 index 0000000000..c0ff13f044 --- /dev/null +++ b/ext/native/thread/threadutil.cpp @@ -0,0 +1,66 @@ +#ifdef _WIN32 +#include +#define TLS_SUPPORTED +#elif defined(ANDROID) +#define TLS_SUPPORTED +#endif + +#include "base/basictypes.h" +#include "base/logging.h" +#include "thread/threadutil.h" + +#ifdef ANDROID +#include +#endif + +#ifdef TLS_SUPPORTED +static __THREAD const char *curThreadName; +#endif + +void setCurrentThreadName(const char* threadName) { +#ifdef _WIN32 + // Set the debugger-visible threadname through an unholy magic hack + static const DWORD MS_VC_EXCEPTION = 0x406D1388; +#pragma pack(push,8) + struct THREADNAME_INFO { + DWORD dwType; // must be 0x1000 + LPCSTR szName; // pointer to name (in user addr space) + DWORD dwThreadID; // thread ID (-1=caller thread) + DWORD dwFlags; // reserved for future use, must be zero + } info; +#pragma pack(pop) + + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = -1; //dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } + __except(EXCEPTION_CONTINUE_EXECUTION) + {} +#else + +#if defined(ANDROID) + pthread_setname_np(pthread_self(), threadName); +// #else +// pthread_setname_np(thread_name); +#endif + + // Do nothing +#endif + // Set the locally known threadname using a thread local variable. +#ifdef TLS_SUPPORTED + curThreadName = threadName; +#endif +} + +void AssertCurrentThreadName(const char *threadName) { +#ifdef TLS_SUPPORTED + if (strcmp(curThreadName, threadName) != 0) { + ELOG("Thread name assert failed: Expected %s, was %s", threadName, curThreadName); + } +#endif +} diff --git a/ext/native/thread/threadutil.h b/ext/native/thread/threadutil.h new file mode 100644 index 0000000000..2c80ef7736 --- /dev/null +++ b/ext/native/thread/threadutil.h @@ -0,0 +1,6 @@ +#pragma once + +// Note that name must be a global string that lives until the end of the process, +// for assertThreadName to work. +void setCurrentThreadName(const char *threadName); +void AssertCurrentThreadName(const char *threadName); diff --git a/ext/native/tools/.gitignore b/ext/native/tools/.gitignore new file mode 100644 index 0000000000..bed56d701d --- /dev/null +++ b/ext/native/tools/.gitignore @@ -0,0 +1,3 @@ +Release +Debug +build diff --git a/ext/native/tools/.project b/ext/native/tools/.project new file mode 100644 index 0000000000..d48fc19492 --- /dev/null +++ b/ext/native/tools/.project @@ -0,0 +1,11 @@ + + + tools + + + + + + + + diff --git a/ext/native/tools/CMakeLists.txt b/ext/native/tools/CMakeLists.txt new file mode 100644 index 0000000000..f828fbe2a0 --- /dev/null +++ b/ext/native/tools/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 2.6) + +project (Tools) + +add_definitions(-O2) +add_definitions(-Wall) +add_definitions(-DSDL) +add_definitions(-Wno-multichar) +add_definitions(-fno-strict-aliasing) +#add_definitions(-fopenmp) + +if(IOS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++") +elseif(APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -mmacosx-version-min=10.7") +endif() + +if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7.0) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +endif() + +# add_definitions(-fstrict-aliasing) + +include_directories(..) +include_directories(../ext) +include_directories(../math/lin) +include_directories(../image) +include_directories(../ext/libzip) +include_directories(../ext/rg_etc1) +include_directories(../ext/glew) +include_directories(/usr/local/include) + +link_directories(/usr/X11R6/lib) +link_directories(/opt/local/lib) + +# Horrible horrible hack +include_directories(/usr/include/freetype2) +include_directories(/usr/local/include/freetype2) +include_directories(/opt/local/include/freetype2) +include_directories(/opt/local/include) + +add_subdirectory(../base base) +add_subdirectory(../gfx gfx) +add_subdirectory(../file file) +add_subdirectory(../image image) +add_subdirectory(../math math) +add_subdirectory(../util util) +add_subdirectory(../ext/libzip libzip) +add_subdirectory(../ext/rg_etc1 rg_etc1) +add_subdirectory(../ext/stb_image stb_image) +add_subdirectory(../ext/libpng17 png17) + + +add_executable(atlastool atlastool.cpp) +target_link_libraries(atlastool png17 freetype util image z stb_image rg_etc1 file zip base) + +add_executable(zimtool zimtool.cpp) +target_link_libraries(zimtool png17 freetype image z stb_image rg_etc1 file zip base) diff --git a/ext/native/tools/README.txt b/ext/native/tools/README.txt new file mode 100644 index 0000000000..26618711e3 --- /dev/null +++ b/ext/native/tools/README.txt @@ -0,0 +1,65 @@ +These are simple tools to create the ZIM texture format and texture atlases based on it. + +atlastool + + path to the configuration file for the atlas to be generated + description of the format is below + + the prefix of the output files, the output files will be: + _atlas.zim + _atlas.cpp + _atlas.h + + texture format of the atlas, can be: + 8888 - RGBA8 + etc1 - ETC1 compressed + - uses RGBA4444 + +Basic configuration file format look like this: + + + font [] + image + +All the blocks enclosed with "<" ">" need to be replaced with the respective options, for +example one line in one of out configuration files is: + + font UBUNTU24 C:/Windows/Fonts/KozGoPro-Medium.otf UWkhcsGR 24 + + size is the horizontal size of the atlas, should be a power of 2, the vertical size is + automatically adjusted to be smallest power of 2 that can fit the whole atlas. + + the name of the font in the generated *.h and *.cpp files + + path to the font, can use *.otf and *.ttf fonts + + defines which glyphs should be copied into the atlas, can use any combination + of the following: + U - US ASCII + W - Latin-1 extras 1 + E - Latin-1 Extended A (needed for Hungarian etc) + e - Latin-1 Extended B (for some African and latinized asian languages?) + k - Katakana + h - Hiragana + s - ShiftJIS symbols + H - Hebrew + G - Greek + R - Russian + c - All Kanji, filtered though! + T - Thai + K - Korean (hangul) + + height in pixels of the glyphs in the font atlas + + ??? no idea + + name of this symbol in the generated *.h and *.cpp files + + path to the image file that is going to be used + + can be any of: + copy - copies the image as-is + r2a - red2alpha, red channel to alpha, color is a solid while + r2i - red to intensity, full alpha + pre - premultiply alpha + p2a - pink (255,0,255) to alpha diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp new file mode 100644 index 0000000000..874a28b4f5 --- /dev/null +++ b/ext/native/tools/atlastool.cpp @@ -0,0 +1,969 @@ +// Sprite packing method borrowed from glorp engine and heavily modified. +// For license safety, just run this as a build tool, don't build it into your game/program. +// https://github.com/zorbathut/glorp + +// data we need to provide: +// sx, sy +// dx, dy +// ox, oy +// wx + +// line height +// dist-per-pixel + +#include +#include +#include FT_FREETYPE_H +#ifdef _WIN32 +// Hackery for our broken path structure +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "base/logging.h" +#include "gfx/texture_atlas.h" + +#include "image/png_load.h" +#include "image/zim_save.h" + +#include "kanjifilter.h" +// extracted only JIS Kanji on the CJK Unified Ideographs of UCS2. Cannot reading BlockAllocator. (texture size over) +//#define USE_KANJI KANJI_STANDARD | KANJI_RARELY_USED | KANJI_LEVEL4 +// daily-use character only. However, it is too enough this. +//#define USE_KANJI KANJI_STANDARD (texture size over) +// Shift-JIS filtering. (texture size over) +//#define USE_KANJI KANJI_SJIS_L1 | KANJI_SJIS_L2 +// more conpact daily-use character. but, not enough this. +// if when you find the unintelligible sequence of characters, +// add kanjiFilter Array with KANJI_LEARNING_ORDER_ADDTIONAL. +#define USE_KANJI KANJI_LEARNING_ORDER_ALL + +#include "util/text/utf8.h" + +using namespace std; +static int global_id; +static bool etc1 = false; +static bool highcolor = false; + + + + +typedef unsigned short u16; + +struct CharRange : public AtlasCharRange { + std::set filter; +}; + +enum Effect { + FX_COPY = 0, + FX_RED_TO_ALPHA_SOLID_WHITE = 1, // for alpha fonts + FX_RED_TO_INTENSITY_ALPHA_255 = 2, + FX_PREMULTIPLY_ALPHA = 3, + FX_PINK_TO_ALPHA = 4, // for alpha fonts + FX_INVALID = 5, +}; + +const char *effect_str[5] = { + "copy", "r2a", "r2i", "pre", "p2a", +}; + +Effect GetEffect(const char *text) { + for (int i = 0; i < 5; i++) { + if (!strcmp(text, effect_str[i])) { + return (Effect)i; + } + } + return FX_INVALID; +} + +struct FontReference { + FontReference(string name, string file, vector ranges, int pixheight, float vertOffset) + : name_(name), file_(file), ranges_(ranges), size_(pixheight), vertOffset_(vertOffset) { + } + + string name_; + string file_; + vector ranges_; + int size_; + float vertOffset_; +}; + +typedef vector FontReferenceList; + +template +struct Image { + vector > dat; + void resize(int x, int y) { + dat.resize(y); + for(int i = 0; i < y; i++) + dat[i].resize(x); + } + int width() const { + return (int)dat[0].size(); + } + int height() const { + return (int)dat.size(); + } + void copyfrom(const Image &img, int ox, int oy, int effect) { + CHECK(img.dat[0].size() + ox <= dat[0].size()); + CHECK(img.dat.size() + oy <= dat.size()); + for (int y = 0; y < (int)img.dat.size(); y++) { + for (int x = 0; x < (int)img.dat[y].size(); x++) { + switch (effect) { + case FX_COPY: + dat[y + oy][ox + x] = img.dat[y][x]; + break; + case FX_RED_TO_ALPHA_SOLID_WHITE: + dat[y + oy][ox + x] = 0x00FFFFFF | (img.dat[y][x] << 24); + break; + case FX_RED_TO_INTENSITY_ALPHA_255: + dat[y + oy][ox + x] = 0xFF000000 | img.dat[y][x] | (img.dat[y][x] << 8) | (img.dat[y][x] << 16); + break; + case FX_PREMULTIPLY_ALPHA: + { + unsigned int color = img.dat[y][x]; + unsigned int a = color >> 24; + unsigned int r = (color & 0xFF) * a >> 8, g = (color & 0xFF00) * a>> 8, b = (color & 0xFF0000) * a >> 8; + color = (color & 0xFF000000) | (r & 0xFF) | (g & 0xFF00) | (b & 0xFF0000); + // Simulate 4444 + color = color & 0xF0F0F0F0; + color |= color >> 4; + dat[y + oy][ox + x] = color; + break; + } + case FX_PINK_TO_ALPHA: + dat[y + oy][ox + x] = ((img.dat[y][x]&0xFFFFFF) == 0xFF00FF) ? 0x00FFFFFF : (img.dat[y][x] | 0xFF000000); + break; + default: + dat[y + oy][ox + x] = 0xFFFF00FF; + break; + } + } + } + } + void set(int sx, int sy, int ex, int ey, unsigned char fil) { + for(int y = sy; y < ey; y++) + fill(dat[y].begin() + sx, dat[y].begin() + ex, fil); + } + bool LoadPNG(const char *png_name) { + unsigned char *img_data; + int w, h; + if (1 != pngLoad(png_name, &w, &h, &img_data, false)) { + printf("Failed to load %s\n", png_name); + exit(1); + return false; + } + dat.resize(h); + for (int y = 0; y < h; y++) { + dat[y].resize(w); + memcpy(&dat[y][0], img_data + 4 * y * w, 4 * w); + } + free(img_data); + return true; + } + void SavePNG(const char *png_name) { + // Save PNG + FILE *fil = fopen(png_name, "wb"); + png_structp png_ptr; + png_infop info_ptr; + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + CHECK(png_ptr); + info_ptr = png_create_info_struct(png_ptr); + CHECK(info_ptr); + png_init_io(png_ptr, fil); + //png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); + png_set_IHDR(png_ptr, info_ptr, dat[0].size(), dat.size(), 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_write_info(png_ptr, info_ptr); + for(int y = 0; y < (int)dat.size(); y++) { + png_write_row(png_ptr, (png_byte*)&dat[y][0]); + } + png_write_end(png_ptr, NULL); + png_destroy_write_struct(&png_ptr, &info_ptr); + } + void SaveZIM(const char *zim_name, int zim_format) { + uint8 *image_data = new uint8[width() * height() * 4]; + for (int y = 0; y < height(); y++) { + memcpy(image_data + y * width() * 4, &dat[y][0], width() * 4); + } + ::SaveZIM(zim_name, width(), height(), width() * 4, zim_format | ZIM_DITHER, image_data); + } +}; + +template +bool operator<(const Image &lhs, const Image &rhs) { + return lhs.dat.size() * lhs.dat[0].size() > rhs.dat.size() * rhs.dat[0].size(); +} + +struct Data { + // item ID + int id; + // dimensions of its spot in the world + int sx, sy, ex, ey; + // offset from the origin + float ox, oy; + float voffset; // to apply at the end + // distance to move the origin forward + float wx; + + int effect; + int charNum; +}; + +bool operator<(const Data &lhs, const Data &rhs) { + return lhs.id < rhs.id; // should be unique +} + +string out_prefix; + +int NextPowerOf2(int x) { + int powof2 = 1; + // Double powof2 until >= val + while (powof2 < x) powof2 <<= 1; + return powof2; +} + +struct Bucket { + vector, Data> > items; + void AddItem(const Image &img, const Data &dat) { + items.push_back(make_pair(img, dat)); + } + vector Resolve(int image_width, Image &dest) { + // Place all the little images - whatever they are. + // Uses greedy fill algorithm. Slow but works surprisingly well, CPUs are fast. + Image masq; + masq.resize(image_width, 1); + dest.resize(image_width, 1); + sort(items.begin(), items.end()); + for (int i = 0; i < (int)items.size(); i++) { + if ((i + 1) % 200 == 0) { + printf("Resolving (%i / %i)\n", i, (int)items.size()); + } + int idx = items[i].first.dat[0].size(); + int idy = items[i].first.dat.size(); + if (idx > 1 && idy > 1) { + CHECK(idx <= image_width); + for (int ty = 0; ty < 2047; ty++) { + if(ty + idy + 1 > (int)dest.dat.size()) { + masq.resize(image_width, ty + idy + 16); + dest.resize(image_width, ty + idy + 16); + } + // Brute force packing. + int sz = (int)items[i].first.dat[0].size(); + auto &masq_ty = masq.dat[ty]; + auto &masq_idy = masq.dat[ty + idy - 1]; + for (int tx = 0; tx < image_width - sz; tx++) { + bool valid = !(masq_ty[tx] || masq_idy[tx] || masq_ty[tx + idx - 1] || masq_idy[tx + idx - 1]); + if (valid) { + for(int ity = 0; ity < idy && valid; ity++) { + for(int itx = 0; itx < idx && valid; itx++) { + if(masq.dat[ty + ity][tx + itx]) { + goto skip; + } + } + } + dest.copyfrom(items[i].first, tx, ty, items[i].second.effect); + masq.set(tx, ty, tx + idx + 1, ty + idy + 1, 255); + + items[i].second.sx = tx; + items[i].second.sy = ty; + + items[i].second.ex = tx + idx; + items[i].second.ey = ty + idy; + + // printf("Placed %d at %dx%d-%dx%d\n", items[i].second.id, tx, ty, tx + idx, ty + idy); + goto found; + } +skip: + ; + } + } +found: + ; + } + } + + if ((int)dest.dat.size() > image_width * 2) { + printf("PACKING FAIL : height=%i", (int)dest.dat.size()); + exit(1); + } + dest.resize(image_width, NextPowerOf2(dest.dat.size())); + + // Output the glyph data. + vector dats; + for(int i = 0; i < (int)items.size(); i++) + dats.push_back(items[i].second); + return dats; + } +}; + +const int supersample = 16; +const int distmult = 64 * 3; // this is "one pixel in the final version equals 64 difference". reduce this number to increase the "blur" radius, increase it to make things "sharper" +const int maxsearch = (128 * supersample + distmult - 1) / distmult; + +struct Closest { + FT_Bitmap bmp; + Closest(FT_Bitmap bmp) : bmp(bmp) { } + float find_closest(int x, int y, char search) { + int best = 1 << 30; + for(int i = 1; i <= maxsearch; i++) { + if(i * i >= best) + break; + for(int f = -i; f < i; f++) { + int dist = i * i + f * f; + if(dist >= best) continue; + if(safe_access(x + i, y + f) == search || safe_access(x - f, y + i) == search || safe_access(x - i, y - f) == search || safe_access(x + f, y - i) == search) + best = dist; + } + } + return sqrt((float)best); + } + char safe_access(int x, int y) { + if(x < 0 || y < 0 || x >= bmp.width || y >= bmp.rows) + return 0; + return bmp.buffer[x + y * bmp.width]; + } +}; + +typedef vector FT_Face_List; + +inline vector merge(const vector &a, const vector &b) { + vector result = a; + for (size_t i = 0, in = b.size(); i < in; ++i) { + bool insert = true; + for (size_t j = 0, jn = a.size(); j < jn; ++j) { + // Should never overlap, so same start is always a duplicate. + if (b[i].start == a[j].start) { + insert = false; + break; + } + } + + if (insert) { + result.push_back(b[i]); + } + } + + return result; +} + +void RasterizeFonts(const FontReferenceList fontRefs, vector &ranges, float *metrics_height, Bucket *bucket) { + FT_Library freetype; + CHECK(FT_Init_FreeType(&freetype) == 0); + + vector fonts; + fonts.resize(fontRefs.size()); + + // The ranges may overlap, so build a list of fonts per range. + map fontsByRange; + // TODO: Better way than average? + float totalHeight = 0.0f; + + for (size_t i = 0, n = fontRefs.size(); i < n; ++i) { + FT_Face &font = fonts[i]; + if (FT_New_Face(freetype, fontRefs[i].file_.c_str(), 0, &font) != 0) { + printf("Failed to load font file %s\n", fontRefs[i].file_.c_str()); + printf("bailing"); + exit(0); + } + printf("TTF info: %d glyphs, %08x flags, %d units, %d strikes\n", (int)font->num_glyphs, (int)font->face_flags, (int)font->units_per_EM, (int)font->num_fixed_sizes); + + CHECK(FT_Set_Pixel_Sizes(font, 0, fontRefs[i].size_ * supersample) == 0); + + ranges = merge(ranges, fontRefs[i].ranges_); + for (size_t r = 0, rn = fontRefs[i].ranges_.size(); r < rn; ++r) { + const CharRange &range = fontRefs[i].ranges_[r]; + fontsByRange[range.start].push_back(fonts[i]); + } + + totalHeight += font->size->metrics.height; + } + *metrics_height = totalHeight / (float) fontRefs.size(); + + // Convert all characters to bitmaps. + for (size_t r = 0, rn = ranges.size(); r < rn; r++) { + FT_Face_List &tryFonts = fontsByRange[ranges[r].start]; + ranges[r].start_index = global_id; + for(int kar = ranges[r].start; kar < ranges[r].end; kar++) { + bool filtered = false; + if (ranges[r].filter.size()) { + if (ranges[r].filter.find((u16)kar) == ranges[r].filter.end()) + filtered = true; + } + + FT_Face font; + bool foundMatch = false; + float vertOffset = 0; + for (size_t i = 0, n = tryFonts.size(); i < n; ++i) { + font = tryFonts[i]; + vertOffset = fontRefs[i].vertOffset_; + if (FT_Get_Char_Index(font, kar) != 0) { + foundMatch = true; + break; + } + } + if (!foundMatch) + fprintf(stderr, "WARNING: No font contains character %x.\n", kar); + + Image img; + if (filtered || 0 != FT_Load_Char(font, kar, FT_LOAD_RENDER|FT_LOAD_MONOCHROME)) { + img.resize(1, 1); + Data dat; + + dat.id = global_id++; + + dat.sx = 0; + dat.sy = 0; + dat.ex = 0; + dat.ey = 0; + dat.ox = 0; + dat.oy = 0; + dat.wx = 0; + dat.charNum = kar; + dat.effect = FX_RED_TO_ALPHA_SOLID_WHITE; + bucket->AddItem(img, dat); + continue; + } + + // printf("%dx%d %p\n", font->glyph->bitmap.width, font->glyph->bitmap.rows, font->glyph->bitmap.buffer); + const int bord = (128 + distmult - 1) / distmult + 1; + if(font->glyph->bitmap.buffer) { + FT_Bitmap tempbitmap; + FT_Bitmap_New(&tempbitmap); + FT_Bitmap_Convert(freetype, &font->glyph->bitmap, &tempbitmap, 1); + Closest closest(tempbitmap); + + // No resampling, just sets the size of the image. + img.resize((tempbitmap.width + supersample - 1) / supersample + bord * 2, (tempbitmap.rows + supersample - 1) / supersample + bord * 2); + int lmx = img.dat[0].size(); + int lmy = img.dat.size(); + + // AA by finding distance to character. Probably a fairly decent approximation but why not do it right? + for(int y = 0; y < lmy; y++) { + int cty = (y - bord) * supersample + supersample / 2; + for(int x = 0; x < lmx; x++) { + int ctx = (x - bord) * supersample + supersample / 2; + float dist; + if(closest.safe_access(ctx, cty)) { + dist = closest.find_closest(ctx, cty, 0); + } else { + dist = -closest.find_closest(ctx, cty, 1); + } + dist = dist / supersample * distmult + 127.5; + dist = floor(dist + 0.5); + if(dist < 0) dist = 0; + if(dist > 255) dist = 255; + + // Only set the red channel. We process when adding the image. + img.dat[y][x] = (unsigned char)dist; + } + } + FT_Bitmap_Done(freetype, &tempbitmap); + } else { + img.resize(1, 1); + } + + Data dat; + + dat.id = global_id++; + + dat.sx = 0; + dat.sy = 0; + dat.ex = img.dat[0].size(); + dat.ey = img.dat.size(); + dat.ox = (float)font->glyph->metrics.horiBearingX / 64 / supersample - bord; + dat.oy = -(float)font->glyph->metrics.horiBearingY / 64 / supersample - bord; + dat.voffset = vertOffset; + dat.wx = (float)font->glyph->metrics.horiAdvance / 64 / supersample; + dat.charNum = kar; + + dat.effect = FX_RED_TO_ALPHA_SOLID_WHITE; + bucket->AddItem(img, dat); + } + } + + for (size_t i = 0, n = fonts.size(); i < n; ++i) { + FT_Done_Face(fonts[i]); + } + FT_Done_FreeType(freetype); +} + + +bool LoadImage(const char *imagefile, Effect effect, Bucket *bucket) { + Image img; + + bool success = false; + if (!strcmp(imagefile, "white.png")) { + img.dat.resize(16); + for (int i = 0; i < 16; i++) { + img.dat[i].resize(16); + for (int j = 0; j < 16; j++) { + img.dat[i][j] = 0xFFFFFFFF; + } + } + success = true; + } else { + success = img.LoadPNG(imagefile); + // printf("loaded image: %ix%i\n", (int)img.dat[0].size(), (int)img.dat.size()); + } + if (!success) { + return false; + } + + Data dat; + memset(&dat, 0, sizeof(dat)); + dat.id = global_id++; + dat.sx = 0; + dat.sy = 0; + dat.ex = img.dat[0].size(); + dat.ey = img.dat.size(); + dat.effect = effect; + bucket->AddItem(img, dat); + return true; +} + +// Use the result array, and recorded data, to generate C++ tables for everything. +struct FontDesc { + string name; + + int first_char_id; + int last_char_id; + + float ascend; + float descend; + float height; + + float metrics_height; + + std::vector ranges; + + FontDesc() + { + } + + void ComputeHeight(const vector &results, float distmult) { + ascend = 0; + descend = 0; + for (size_t r = 0; r < ranges.size(); r++) { + for(int i = ranges[r].start; i < ranges[r].end; i++) { + int idx = i - ranges[r].start + ranges[r].start_index; + ascend = max(ascend, -results[idx].oy); + descend = max(descend, results[idx].ey - results[idx].sy + results[idx].oy); + } + } + + height = metrics_height / 64.0 / supersample; + } + + void OutputSelf(FILE *fil, float tw, float th, const vector &results) { + // Dump results as chardata. + fprintf(fil, "const AtlasChar font_%s_chardata[] = {\n", name.c_str()); + for (size_t r = 0; r < ranges.size(); r++) { + fprintf(fil, "// RANGE: 0x%x - 0x%x, start 0x%x\n", ranges[r].start, ranges[r].end, ranges[r].start_index); + for (int i = ranges[r].start; i < ranges[r].end; i++) { + int idx = i - ranges[r].start + ranges[r].start_index; + fprintf(fil, " {%ff, %ff, %ff, %ff, %1.4ff, %1.4ff, %1.4ff, %i, %i}, // %04x\n", + /*results[i].id, */ + results[idx].sx / tw, + results[idx].sy / th, + results[idx].ex / tw, + results[idx].ey / th, + results[idx].ox, + results[idx].oy + results[idx].voffset, + results[idx].wx, + results[idx].ex - results[idx].sx, results[idx].ey - results[idx].sy, + results[idx].charNum); + } + } + fprintf(fil, "};\n"); + + fprintf(fil, "const AtlasCharRange font_%s_ranges[] = {\n", name.c_str()); + // Write range information. + int start_index = 0; + for (size_t r = 0; r < ranges.size(); r++) { + int first_char_id = ranges[r].start; + int last_char_id = ranges[r].end; + fprintf(fil, " { %i, %i, %i },\n", first_char_id, last_char_id, start_index); + start_index += last_char_id - first_char_id; + } + fprintf(fil, "};\n"); + + fprintf(fil, "const AtlasFont font_%s = {\n", name.c_str()); + fprintf(fil, " %ff, // padding\n", height - ascend - descend); + fprintf(fil, " %ff, // height\n", ascend + descend); + fprintf(fil, " %ff, // ascend\n", ascend); + fprintf(fil, " %ff, // distslope\n", distmult / 256.0); + fprintf(fil, " font_%s_chardata,\n", name.c_str()); + fprintf(fil, " font_%s_ranges,\n", name.c_str()); + fprintf(fil, " %i,\n", (int)ranges.size()); + fprintf(fil, " \"%s\", // name\n", name.c_str()); + fprintf(fil, "};\n"); + } + + void OutputIndex(FILE *fil) { + fprintf(fil, " &font_%s,\n", name.c_str()); + } + + void OutputHeader(FILE *fil, int index) { + fprintf(fil, "#define %s %i\n", name.c_str(), index); + } +}; + +struct ImageDesc { + string name; + Effect effect; + int result_index; + + void OutputSelf(FILE *fil, float tw, float th, const vector &results) { + int i = result_index; + float toffx = 0.5f / tw; + float toffy = 0.5f / th; + fprintf(fil, " {%ff, %ff, %ff, %ff, %d, %d, \"%s\"},\n", + results[i].sx / tw + toffx, + results[i].sy / th + toffy, + results[i].ex / tw - toffx, + results[i].ey / th - toffy, + results[i].ex - results[i].sx, + results[i].ey - results[i].sy, + name.c_str()); + } + + void OutputHeader(FILE *fil, int index) { + fprintf(fil, "#define %s %i\n", name.c_str(), index); + } +}; + + +CharRange range(int start, int end, const std::set &filter) { + CharRange r; + r.start = start; + r.end = end + 1; + r.start_index = 0; + r.filter = filter; + return r; +} + +CharRange range(int start, int end) { + CharRange r; + r.start = start; + r.end = end + 1; + r.start_index = 0; + return r; +} + +inline bool operator <(const CharRange &a, const CharRange &b) { + // These ranges should never overlap so this should be enough. + return a.start < b.start; +} + + +void LearnFile(const char *filename, const char *desc, std::set &chars, uint32_t lowerLimit, uint32_t upperLimit) { + FILE *f = fopen(filename, "rb"); + if (f) { + fseek(f, 0, SEEK_END); + size_t sz = ftell(f); + fseek(f, 0, SEEK_SET); + char *data = new char[sz+1]; + fread(data, 1, sz, f); + fclose(f); + data[sz]=0; + + UTF8 utf(data); + int learnCount = 0; + while (!utf.end()) { + uint32_t c = utf.next(); + if (c >= lowerLimit && c <= upperLimit) { + if (chars.find(c) == chars.end()) { + learnCount++; + chars.insert(c); + } + } + } + delete [] data; + printf("%i %s characters learned.\n", learnCount, desc); + } + +} + +void GetLocales(const char *locales, std::vector &ranges) +{ + std::set kanji; + std::set hangul1, hangul2, hangul3; + for (int i = 0; i < sizeof(kanjiFilter)/sizeof(kanjiFilter[0]); i+=2) + { + // Kanji filtering. + if ((kanjiFilter[i+1] & USE_KANJI) > 0) { + kanji.insert(kanjiFilter[i]); + } + } + + // Also, load chinese.txt if available. + LearnFile("chinese.txt", "Chinese", kanji, 0x3400, 0xFFFF); + LearnFile("korean.txt", "Korean", hangul1, 0x1100, 0x11FF); + LearnFile("korean.txt", "Korean", hangul2, 0x3130, 0x318F); + LearnFile("korean.txt", "Korean", hangul3, 0xAC00, 0xD7A3); + + // The end point of a range is now inclusive! + + for (size_t i = 0; i < strlen(locales); i++) { + switch (locales[i]) { + case 'U': // US ASCII + ranges.push_back(range(32, 127)); + break; + case 'W': // Latin-1 extras 1 + ranges.push_back(range(0x80, 0x80)); // euro sign + ranges.push_back(range(0xA2, 0xFF)); // 80 - A0 appears to contain nothing interesting + ranges.push_back(range(0x2121, 0x2122)); // TEL symbol and trademark symbol + break; + case 'E': // Latin-1 Extended A (needed for Hungarian etc) + ranges.push_back(range(0x100, 0x17F)); + break; + case 'e': // Latin-1 Extended B (for some African and latinized asian languages?) + ranges.push_back(range(0x180, 0x250)); + break; + case 'k': // Katakana + ranges.push_back(range(0x30A0, 0x30FF)); + ranges.push_back(range(0x31F0, 0x31FF)); + ranges.push_back(range(0xFF00, 0xFFEF)); // half-width ascii + break; + case 'h': // Hiragana + ranges.push_back(range(0x3041, 0x3097)); + ranges.push_back(range(0x3099, 0x309F)); + break; + case 's': // ShiftJIS symbols + ranges.push_back(range(0x2010, 0x2312)); // General Punctuation, Letterlike Symbols, Arrows, + // Mathematical Operators, Miscellaneous Technical + ranges.push_back(range(0x2500, 0x254B)); // Box drawing + ranges.push_back(range(0x25A0, 0x266F)); // Geometric Shapes, Miscellaneous Symbols + ranges.push_back(range(0x3231, 0x3231)); // Co,.Ltd. symbol + ranges.push_back(range(0x2116, 0x2116)); // "No." symbol + ranges.push_back(range(0x33CD, 0x33CD)); // "K.K." symbol + break; + case 'H': // Hebrew + ranges.push_back(range(0x0590, 0x05FF)); + break; + case 'G': // Greek + ranges.push_back(range(0x0370, 0x03FF)); + break; + case 'R': // Russian + ranges.push_back(range(0x0400, 0x04FF)); + break; + case 'c': // All Kanji, filtered though! + ranges.push_back(range(0x3000, 0x303f)); // Ideographic symbols + ranges.push_back(range(0x4E00, 0x9FFF, kanji)); + // ranges.push_back(range(0xFB00, 0xFAFF, kanji)); + break; + case 'T': // Thai + ranges.push_back(range(0x0E00, 0x0E5B)); + break; + case 'K': // Korean (hangul) + ranges.push_back(range(0xAC00, 0xD7A3, hangul3)); + break; + case 'V': // Vietnamese (need 'e' too) + ranges.push_back(range(0x1EA0, 0x1EF9)); + break; + } + } + + ranges.push_back(range(0xFFFD, 0xFFFD)); + std::sort(ranges.begin(), ranges.end()); +} + +int main(int argc, char **argv) { + // initProgram(&argc, const_cast(&argv)); + // /usr/share/fonts/truetype/msttcorefonts/Arial_Black.ttf + // /usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf + if (argc < 3) { + FLOG("Not enough arguments"); + return 1; + } + CHECK(argc >= 3); + if (argc > 3) + { + if (!strcmp(argv[3], "etc1")) { + printf("ETC1 enabled!\n"); + etc1 = true; + } else if (!strcmp(argv[3], "8888")) { + highcolor = true; + printf("RGBA8888 enabled!\n"); + } + } + printf("Reading script %s\n", argv[1]); + const char *atlas_name = argv[2]; + string image_name = string(atlas_name) + "_atlas.zim"; + out_prefix = argv[2]; + + map fontRefs; + vector fonts; + vector images; + + Bucket bucket; + + char line[512]; + FILE *script = fopen(argv[1], "r"); + if (!fgets(line, 512, script)) { + printf("Error fgets-ing\n"); + } + int image_width; + sscanf(line, "%i", &image_width); + printf("Texture width: %i\n", image_width); + while (!feof(script)) { + if (!fgets(line, 511, script)) break; + if (!strlen(line)) break; + if (line[0] == '#') continue; + char *rest = strchr(line, ' '); + if (rest) { + *rest = 0; + rest++; + } + char *word = line; + if (!strcmp(word, "font")) { + // Font! + char fontname[256]; + char fontfile[256]; + char locales[256]; + int pixheight; + float vertOffset = 0; + sscanf(rest, "%s %s %s %i %f", fontname, fontfile, locales, &pixheight, &vertOffset); + printf("Font: %s (%s) in size %i. Locales: %s\n", fontname, fontfile, pixheight, locales); + + std::vector ranges; + GetLocales(locales, ranges); + printf("locales fetched.\n"); + + FontReference fnt(fontname, fontfile, ranges, pixheight, vertOffset); + fontRefs[fontname].push_back(fnt); + } else if (!strcmp(word, "image")) { + char imagename[256]; + char imagefile[256]; + char effectname[256]; + sscanf(rest, "%s %s %s", imagename, imagefile, effectname); + Effect effect = GetEffect(effectname); + printf("Image %s with effect %s (%i)\n", imagefile, effectname, (int)effect); + ImageDesc desc; + desc.name = imagename; + desc.effect = effect; + desc.result_index = (int)bucket.items.size(); + images.push_back(desc); + if (!LoadImage(imagefile, effect, &bucket)) { + fprintf(stderr, "Failed to load image %s\n", imagefile); + } + } else { + fprintf(stderr, "Warning: Failed to parse line starting with %s\n", line); + } + } + fclose(script); + + // Script fully read, now rasterize the fonts. + for (auto it = fontRefs.begin(), end = fontRefs.end(); it != end; ++it) { + FontDesc fnt; + fnt.first_char_id = (int)bucket.items.size(); + + vector finalRanges; + float metrics_height; + RasterizeFonts(it->second, finalRanges, &metrics_height, &bucket); + printf("font rasterized.\n"); + + fnt.ranges = finalRanges; + fnt.name = it->first; + fnt.metrics_height = metrics_height; + + fonts.push_back(fnt); + } + + // Script read, all subimages have been generated. + + // Place the subimages onto the main texture. Also writes to png. + Image dest; + // Place things on the bitmap. + printf("Resolving...\n"); + + vector results = bucket.Resolve(image_width, dest); + if (etc1) { + printf("Writing .ZIM %ix%i ETC1...\n", dest.width(), dest.height()); + dest.SaveZIM(image_name.c_str(), ZIM_ETC1 | ZIM_ZLIB_COMPRESSED); + } else if (highcolor) { + printf("Writing .ZIM %ix%i RGBA8888...\n", dest.width(), dest.height()); + dest.SaveZIM(image_name.c_str(), ZIM_RGBA8888 | ZIM_ZLIB_COMPRESSED); + } else { + printf("Writing .ZIM %ix%i RGBA4444...\n", dest.width(), dest.height()); + dest.SaveZIM(image_name.c_str(), ZIM_RGBA4444 | ZIM_ZLIB_COMPRESSED); + } + // Also save PNG for debugging. + printf("Writing .PNG %s\n", (image_name + ".png").c_str()); + dest.SavePNG((image_name + ".png").c_str()); + + printf("Done. Outputting source files %s_atlas.cpp/h.\n", out_prefix.c_str()); + // Sort items by ID. + sort(results.begin(), results.end()); + + FILE *cpp_file = fopen((out_prefix + "_atlas.cpp").c_str(), "wb"); + fprintf(cpp_file, "// C++ generated by atlastool from %s (hrydgard@gmail.com)\n\n", argv[1]); + fprintf(cpp_file, "#include \"%s\"\n\n", (out_prefix + "_atlas.h").c_str()); + for (int i = 0; i < (int)fonts.size(); i++) { + FontDesc &xfont = fonts[i]; + xfont.ComputeHeight(results, distmult); + xfont.OutputSelf(cpp_file, dest.width(), dest.height(), results); + } + + if (fonts.size()) { + fprintf(cpp_file, "const AtlasFont *%s_fonts[%i] = {\n", atlas_name, (int)fonts.size()); + for (int i = 0; i < (int)fonts.size(); i++) { + fonts[i].OutputIndex(cpp_file); + } + fprintf(cpp_file, "};\n"); + } + + if (images.size()) { + fprintf(cpp_file, "const AtlasImage %s_images[%i] = {\n", atlas_name, (int)images.size()); + for (int i = 0; i < (int)images.size(); i++) { + images[i].OutputSelf(cpp_file, dest.width(), dest.height(), results); + } + fprintf(cpp_file, "};\n"); + } + + fprintf(cpp_file, "const Atlas %s_atlas = {\n", atlas_name); + fprintf(cpp_file, " \"%s\",\n", image_name.c_str()); + if (fonts.size()) { + fprintf(cpp_file, " %s_fonts, %i,\n", atlas_name, (int)fonts.size()); + } else { + fprintf(cpp_file, " 0, 0,\n"); + } + if (images.size()) { + fprintf(cpp_file, " %s_images, %i,\n", atlas_name, (int)images.size()); + } else { + fprintf(cpp_file, " 0, 0,\n"); + } + fprintf(cpp_file, "};\n"); + // Should output a list pointing to all the fonts as well. + fclose(cpp_file); + + FILE *h_file = fopen((out_prefix + "_atlas.h").c_str(), "wb"); + fprintf(h_file, "// Header generated by atlastool from %s (hrydgard@gmail.com)\n\n", argv[1]); + fprintf(h_file, "#pragma once\n"); + fprintf(h_file, "#include \"gfx/texture_atlas.h\"\n\n"); + if (fonts.size()) { + fprintf(h_file, "// FONTS_%s\n", atlas_name); + for (int i = 0; i < (int)fonts.size(); i++) { + fonts[i].OutputHeader(h_file, i); + } + fprintf(h_file, "\n\n"); + } + if (images.size()) { + fprintf(h_file, "// IMAGES_%s\n", atlas_name); + for (int i = 0; i < (int)images.size(); i++) { + images[i].OutputHeader(h_file, i); + } + fprintf(h_file, "\n\n"); + } + fprintf(h_file, "extern const Atlas %s_atlas;\n", atlas_name); + fprintf(h_file, "extern const AtlasImage %s_images[%i];\n", atlas_name, (int)images.size()); + fclose(h_file); + // TODO: Turn into C++ arrays. +} diff --git a/ext/native/tools/atlastool/atlastool.vcxproj b/ext/native/tools/atlastool/atlastool.vcxproj new file mode 100644 index 0000000000..24469ad637 --- /dev/null +++ b/ext/native/tools/atlastool/atlastool.vcxproj @@ -0,0 +1,105 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {0FDAD650-7436-4803-A36B-10CF9F6F9C2B} + Win32Proj + atlastool + + + + Application + true + MultiByte + v120 + + + Application + false + false + MultiByte + v120 + + + + + + + + + + + + + true + + + false + $(ProjectDir)\..\build\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\ext;..\..\..\ext\freetype\devel;..\..\..\ext\freetype\include;..\..;..\..\ext\SDL1.2\include;..\..\..\libpng;%(AdditionalIncludeDirectories); + + + Console + true + kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies) + + + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\ext;..\..\..\ext\freetype\devel;..\..\..\ext\freetype\include;..\..;..\..\ext\SDL1.2\include;..\..\..\libpng;%(AdditionalIncludeDirectories); + + + Console + true + true + true + kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies) + + + + + + + + {78b079bd-9fc7-4b9e-b4a6-96da0f00248b} + + + {f761046e-6c38-4428-a5f1-38391a37bb34} + + + {C4DF647E-80EA-4111-A0A8-218B1B711E18} + + + + + + + + + diff --git a/ext/native/tools/audiotool.cpp b/ext/native/tools/audiotool.cpp new file mode 100644 index 0000000000..68cfee7ae3 --- /dev/null +++ b/ext/native/tools/audiotool.cpp @@ -0,0 +1,17 @@ +// TODO + +#include + +#include "audio/wav_load.h" +#include "base/logging.h" + + +struct AudioClip { + int length; + +}; + + +int main(int argc, char **argv) { + CHECK(argc == 3); +} diff --git a/ext/native/tools/b.sh b/ext/native/tools/b.sh new file mode 100755 index 0000000000..015dc7e52e --- /dev/null +++ b/ext/native/tools/b.sh @@ -0,0 +1,3 @@ +mkdir -p build +(cd build; cmake .. && make -j5; cd ..) +#cp build/atlastool /home/henrik/bin diff --git a/ext/native/tools/kanjifilter.h b/ext/native/tools/kanjifilter.h new file mode 100644 index 0000000000..e44afad1ed --- /dev/null +++ b/ext/native/tools/kanjifilter.h @@ -0,0 +1,31596 @@ +// http://www.asahi-net.or.jp/~ax2s-kmtn/character/japan.html +// http://charset.uic.jp/show/shiftjis2004/ +enum KANJI_LEVEL +{ + KANJI_LEARNING_ORDER_1 = 0x0001, + KANJI_LEARNING_ORDER_2 = 0x0002, + KANJI_LEARNING_ORDER_3 = 0x0004, + KANJI_LEARNING_ORDER_4 = 0x0008, + KANJI_LEARNING_ORDER_5 = 0x0010, + KANJI_LEARNING_ORDER_6 = 0x0020, + KANJI_LEARNING_ORDER_7 = 0x0040, + KANJI_LEARNING_ORDER_ADDTIONAL = 0x0100, // if you find garbled character when playing. + + KANJI_LEARNING_ORDER_ALL = 0x01FF, + + KANJI_SJIS_L1 = 0x0200, // daily use. this is ShiftJIS based The level 1 JIS. Almost the same as KANJI_STANDARD. + KANJI_SJIS_L2 = 0x0400, // daily use. this is ShiftJIS based The level 2 JIS. Almost the same as KANJI_STANDARD. + KANJI_SJIS_L3 = 0x0800, // not daily use. part of the level 3 and 4 JIS. + + KANJI_SJIS_ALL = 0x0E00, // ShiftJIS Kanji full support. It is not able to display all the CJK Unified Ideographs. + + // warning Cannot used. BlockAllocator size over. 2048x4096 size = 0x00400000 + KANJI_STANDARD = 0x2000, // daily use (JIS X 2008 = The level 1 JIS and The leve 2 JIS) + KANJI_RARELY_USED = 0x4000, // not daily use. but, The Chinese characters that may be used in a visual novel game maybe. (JIS X 2012 = The level 3 JIS) + KANJI_LEVEL4 = 0x8000, // JIS X 2008 extend. (JIS X 2013 = JIS X 2008 + 1259 characters of JIS X 2012 + The level 4 JIS) + +}; + +// The parameter is the learning order. +const unsigned short kanjiFilter[] = { + 0x78A7, KANJI_LEARNING_ORDER_ADDTIONAL, // 碧 + 0x7A9F, KANJI_LEARNING_ORDER_ADDTIONAL, // 窟 + 0x4E00, KANJI_LEARNING_ORDER_1, // 侀 + 0x4E01, KANJI_LEARNING_ORDER_3, // 䞁 + 0x4E03, KANJI_LEARNING_ORDER_1, // 䞃 + 0x4E07, KANJI_LEARNING_ORDER_2, // 侇 + 0x4E08, KANJI_LEARNING_ORDER_7, // 䞈 + 0x4E09, KANJI_LEARNING_ORDER_1, // 侉 + 0x4E0A, KANJI_LEARNING_ORDER_1, // 侊 + 0x4E0B, KANJI_LEARNING_ORDER_1, // 例 + 0x4E0D, KANJI_LEARNING_ORDER_4, // 䞍 + 0x4E0E, KANJI_LEARNING_ORDER_7, // 侎 + 0x4E14, KANJI_LEARNING_ORDER_7, // 侔 + 0x4E16, KANJI_LEARNING_ORDER_3, // 侖 + 0x4E18, KANJI_LEARNING_ORDER_7, // 䞘 + 0x4E19, KANJI_LEARNING_ORDER_7, // 侙 + 0x4E21, KANJI_LEARNING_ORDER_3, // äž¡ + 0x4E26, KANJI_LEARNING_ORDER_6, // 䞊 + 0x4E2D, KANJI_LEARNING_ORDER_1, // äž­ + 0x4E38, KANJI_LEARNING_ORDER_2, // äžž + 0x4E39, KANJI_LEARNING_ORDER_7, // äž¹ + 0x4E3B, KANJI_LEARNING_ORDER_3, // äž» + 0x4E45, KANJI_LEARNING_ORDER_5, // 久 + 0x4E4F, KANJI_LEARNING_ORDER_7, // 乏 + 0x4E57, KANJI_LEARNING_ORDER_3, // 乗 + 0x4E59, KANJI_LEARNING_ORDER_7, // 乙 + 0x4E5D, KANJI_LEARNING_ORDER_1, // 九 + 0x4E71, KANJI_LEARNING_ORDER_6, // ä¹± + 0x4E73, KANJI_LEARNING_ORDER_6, // ä¹³ + 0x4E7E, KANJI_LEARNING_ORDER_7, // 也 + 0x4E86, KANJI_LEARNING_ORDER_7, // 了 + 0x4E88, KANJI_LEARNING_ORDER_3, // 予 + 0x4E89, KANJI_LEARNING_ORDER_4, // 争 + 0x4E8B, KANJI_LEARNING_ORDER_3, // 事 + 0x4E8C, KANJI_LEARNING_ORDER_1, // 二 + 0x4E92, KANJI_LEARNING_ORDER_7, // 互 + 0x4E94, KANJI_LEARNING_ORDER_1, // 五 + 0x4E95, KANJI_LEARNING_ORDER_7, // 井 + 0x4E9C, KANJI_LEARNING_ORDER_7, // 亜 + 0x4EA1, KANJI_LEARNING_ORDER_6, // 亡 + 0x4EA4, KANJI_LEARNING_ORDER_2, // 亀 + 0x4EAB, KANJI_LEARNING_ORDER_7, // 享 + 0x4EAC, KANJI_LEARNING_ORDER_2, // 京 + 0x4EAD, KANJI_LEARNING_ORDER_7, // 亭 + 0x4EBA, KANJI_LEARNING_ORDER_1, // 人 + 0x4EC1, KANJI_LEARNING_ORDER_6, // 仁 + 0x4ECA, KANJI_LEARNING_ORDER_2, // 今 + 0x4ECB, KANJI_LEARNING_ORDER_7, // 介 + 0x4ECF, KANJI_LEARNING_ORDER_5, // 仏 + 0x4ED5, KANJI_LEARNING_ORDER_3, // 仕 + 0x4ED6, KANJI_LEARNING_ORDER_3, // 他 + 0x4ED8, KANJI_LEARNING_ORDER_4, // 付 + 0x4ED9, KANJI_LEARNING_ORDER_7, // 仙 + 0x4EE3, KANJI_LEARNING_ORDER_3, // 代 + 0x4EE4, KANJI_LEARNING_ORDER_4, // 什 + 0x4EE5, KANJI_LEARNING_ORDER_4, // 以 + 0x4EEE, KANJI_LEARNING_ORDER_5, // ä»® + 0x4EF0, KANJI_LEARNING_ORDER_7, // ä»° + 0x4EF2, KANJI_LEARNING_ORDER_4, // 仲 + 0x4EF6, KANJI_LEARNING_ORDER_5, // ä»¶ + 0x4EFB, KANJI_LEARNING_ORDER_5, // ä»» + 0x4F01, KANJI_LEARNING_ORDER_7, // 䌁 + 0x4F0F, KANJI_LEARNING_ORDER_7, // 䌏 + 0x4F10, KANJI_LEARNING_ORDER_7, // 䌐 + 0x4F11, KANJI_LEARNING_ORDER_1, // 䌑 + 0x4F1A, KANJI_LEARNING_ORDER_2, // 䌚 + 0x4F1D, KANJI_LEARNING_ORDER_4, // 䌝 + 0x4F2F, KANJI_LEARNING_ORDER_7, // 䌯 + 0x4F34, KANJI_LEARNING_ORDER_7, // 䌎 + 0x4F38, KANJI_LEARNING_ORDER_7, // 䌞 + 0x4F3A, KANJI_LEARNING_ORDER_7, // 䌺 + 0x4F3C, KANJI_LEARNING_ORDER_5, // 䌌 + 0x4F46, KANJI_LEARNING_ORDER_7, // 䜆 + 0x4F4D, KANJI_LEARNING_ORDER_4, // 䜍 + 0x4F4E, KANJI_LEARNING_ORDER_4, // 䜎 + 0x4F4F, KANJI_LEARNING_ORDER_3, // 䜏 + 0x4F50, KANJI_LEARNING_ORDER_7, // 䜐 + 0x4F53, KANJI_LEARNING_ORDER_2, // 䜓 + 0x4F55, KANJI_LEARNING_ORDER_2, // 䜕 + 0x4F59, KANJI_LEARNING_ORDER_5, // 䜙 + 0x4F5C, KANJI_LEARNING_ORDER_2, // 䜜 + 0x4F73, KANJI_LEARNING_ORDER_7, // 䜳 + 0x4F75, KANJI_LEARNING_ORDER_7, // 䜵 + 0x4F7F, KANJI_LEARNING_ORDER_3, // 䜿 + 0x4F8B, KANJI_LEARNING_ORDER_4, // 䟋 + 0x4F8D, KANJI_LEARNING_ORDER_7, // 䟍 + 0x4F9B, KANJI_LEARNING_ORDER_6, // 䟛 + 0x4F9D, KANJI_LEARNING_ORDER_7, // 䟝 + 0x4FA1, KANJI_LEARNING_ORDER_5, // 䟡 + 0x4FAE, KANJI_LEARNING_ORDER_7, // 䟮 + 0x4FAF, KANJI_LEARNING_ORDER_7, // 䟯 + 0x4FB5, KANJI_LEARNING_ORDER_7, // 䟵 + 0x4FBF, KANJI_LEARNING_ORDER_4, // 䟿 + 0x4FC2, KANJI_LEARNING_ORDER_3, // 係 + 0x4FC3, KANJI_LEARNING_ORDER_7, // 促 + 0x4FCA, KANJI_LEARNING_ORDER_7, // 俊 + 0x4FD7, KANJI_LEARNING_ORDER_7, // 俗 + 0x4FDD, KANJI_LEARNING_ORDER_5, // 保 + 0x4FE1, KANJI_LEARNING_ORDER_4, // ä¿¡ + 0x4FEE, KANJI_LEARNING_ORDER_5, // ä¿® + 0x4FF3, KANJI_LEARNING_ORDER_6, // 俳 + 0x4FF5, KANJI_LEARNING_ORDER_5, // 俵 + 0x4FF8, KANJI_LEARNING_ORDER_7, // 俞 + 0x5009, KANJI_LEARNING_ORDER_4, // 倉 + 0x500B, KANJI_LEARNING_ORDER_5, // 個 + 0x500D, KANJI_LEARNING_ORDER_3, // 倍 + 0x5012, KANJI_LEARNING_ORDER_7, // 倒 + 0x5019, KANJI_LEARNING_ORDER_4, // 候 + 0x501F, KANJI_LEARNING_ORDER_4, // 借 + 0x5023, KANJI_LEARNING_ORDER_7, // 倣 + 0x5024, KANJI_LEARNING_ORDER_6, // 倀 + 0x502B, KANJI_LEARNING_ORDER_7, // 倫 + 0x5039, KANJI_LEARNING_ORDER_7, // 倹 + 0x5049, KANJI_LEARNING_ORDER_7, // 偉 + 0x504F, KANJI_LEARNING_ORDER_7, // 偏 + 0x505C, KANJI_LEARNING_ORDER_4, // 停 + 0x5065, KANJI_LEARNING_ORDER_4, // 健 + 0x5074, KANJI_LEARNING_ORDER_4, // 偎 + 0x5075, KANJI_LEARNING_ORDER_7, // 偵 + 0x5076, KANJI_LEARNING_ORDER_7, // 偶 + 0x507D, KANJI_LEARNING_ORDER_7, // 停 + 0x508D, KANJI_LEARNING_ORDER_7, // 傍 + 0x5091, KANJI_LEARNING_ORDER_7, // 傑 + 0x5098, KANJI_LEARNING_ORDER_7, // 傘 + 0x5099, KANJI_LEARNING_ORDER_5, // 備 + 0x50AC, KANJI_LEARNING_ORDER_7, // 催 + 0x50B5, KANJI_LEARNING_ORDER_7, // 債 + 0x50B7, KANJI_LEARNING_ORDER_6, // 傷 + 0x50BE, KANJI_LEARNING_ORDER_7, // 傟 + 0x50CD, KANJI_LEARNING_ORDER_4, // 働 + 0x50CF, KANJI_LEARNING_ORDER_5, // 像 + 0x50D5, KANJI_LEARNING_ORDER_7, // 僕 + 0x50DA, KANJI_LEARNING_ORDER_7, // 僚 + 0x50E7, KANJI_LEARNING_ORDER_7, // 僧 + 0x5100, KANJI_LEARNING_ORDER_7, // 儀 + 0x5104, KANJI_LEARNING_ORDER_4, // 億 + 0x5112, KANJI_LEARNING_ORDER_7, // 儒 + 0x511F, KANJI_LEARNING_ORDER_7, // 償 + 0x512A, KANJI_LEARNING_ORDER_6, // 優 + 0x5143, KANJI_LEARNING_ORDER_2, // 元 + 0x5144, KANJI_LEARNING_ORDER_2, // 兄 + 0x5145, KANJI_LEARNING_ORDER_7, // 充 + 0x5146, KANJI_LEARNING_ORDER_4, // 兆 + 0x5148, KANJI_LEARNING_ORDER_1, // 先 + 0x5149, KANJI_LEARNING_ORDER_2, // 光 + 0x514B, KANJI_LEARNING_ORDER_7, // 克 + 0x514D, KANJI_LEARNING_ORDER_7, // 免 + 0x5150, KANJI_LEARNING_ORDER_4, // 児 + 0x515A, KANJI_LEARNING_ORDER_6, // 党 + 0x5165, KANJI_LEARNING_ORDER_1, // 入 + 0x5168, KANJI_LEARNING_ORDER_3, // å…š + 0x516B, KANJI_LEARNING_ORDER_1, // 八 + 0x516C, KANJI_LEARNING_ORDER_2, // 公 + 0x516D, KANJI_LEARNING_ORDER_1, // 六 + 0x5171, KANJI_LEARNING_ORDER_4, // 共 + 0x5175, KANJI_LEARNING_ORDER_4, // 兵 + 0x5177, KANJI_LEARNING_ORDER_3, // 具 + 0x5178, KANJI_LEARNING_ORDER_4, // å…ž + 0x517C, KANJI_LEARNING_ORDER_7, // å…Œ + 0x5185, KANJI_LEARNING_ORDER_2, // 内 + 0x5186, KANJI_LEARNING_ORDER_1, // 円 + 0x518A, KANJI_LEARNING_ORDER_6, // 冊 + 0x518D, KANJI_LEARNING_ORDER_5, // 再 + 0x5192, KANJI_LEARNING_ORDER_7, // 冒 + 0x5197, KANJI_LEARNING_ORDER_7, // 冗 + 0x5199, KANJI_LEARNING_ORDER_3, // 写 + 0x51A0, KANJI_LEARNING_ORDER_7, // 冠 + 0x51AC, KANJI_LEARNING_ORDER_2, // 冬 + 0x51B7, KANJI_LEARNING_ORDER_4, // 冷 + 0x51C6, KANJI_LEARNING_ORDER_7, // 准 + 0x51CD, KANJI_LEARNING_ORDER_7, // 凍 + 0x51DD, KANJI_LEARNING_ORDER_7, // 凝 + 0x51E1, KANJI_LEARNING_ORDER_7, // 凡 + 0x51E6, KANJI_LEARNING_ORDER_6, // 凊 + 0x51F6, KANJI_LEARNING_ORDER_7, // 凶 + 0x51F8, KANJI_LEARNING_ORDER_7, // 凞 + 0x51F9, KANJI_LEARNING_ORDER_7, // 凹 + 0x51FA, KANJI_LEARNING_ORDER_1, // 出 + 0x5200, KANJI_LEARNING_ORDER_2, // 刀 + 0x5203, KANJI_LEARNING_ORDER_7, // 刃 + 0x5206, KANJI_LEARNING_ORDER_2, // 分 + 0x5207, KANJI_LEARNING_ORDER_2, // 切 + 0x5208, KANJI_LEARNING_ORDER_7, // 刈 + 0x520A, KANJI_LEARNING_ORDER_5, // 刊 + 0x5211, KANJI_LEARNING_ORDER_7, // 刑 + 0x5217, KANJI_LEARNING_ORDER_3, // 列 + 0x521D, KANJI_LEARNING_ORDER_4, // 初 + 0x5224, KANJI_LEARNING_ORDER_5, // 刀 + 0x5225, KANJI_LEARNING_ORDER_4, // 別 + 0x5229, KANJI_LEARNING_ORDER_4, // 利 + 0x5230, KANJI_LEARNING_ORDER_7, // 到 + 0x5236, KANJI_LEARNING_ORDER_5, // 制 + 0x5237, KANJI_LEARNING_ORDER_4, // 刷 + 0x5238, KANJI_LEARNING_ORDER_5, // 刞 + 0x523A, KANJI_LEARNING_ORDER_7, // 刺 + 0x523B, KANJI_LEARNING_ORDER_6, // 刻 + 0x5247, KANJI_LEARNING_ORDER_5, // 則 + 0x524A, KANJI_LEARNING_ORDER_7, // 削 + 0x524D, KANJI_LEARNING_ORDER_2, // 前 + 0x5256, KANJI_LEARNING_ORDER_7, // 剖 + 0x525B, KANJI_LEARNING_ORDER_7, // 剛 + 0x5263, KANJI_LEARNING_ORDER_7, // 剣 + 0x5264, KANJI_LEARNING_ORDER_7, // 剀 + 0x526F, KANJI_LEARNING_ORDER_4, // 副 + 0x5270, KANJI_LEARNING_ORDER_7, // 剰 + 0x5272, KANJI_LEARNING_ORDER_6, // 割 + 0x5275, KANJI_LEARNING_ORDER_6, // 創 + 0x5287, KANJI_LEARNING_ORDER_6, // 劇 + 0x529B, KANJI_LEARNING_ORDER_1, // 力 + 0x529F, KANJI_LEARNING_ORDER_4, // 功 + 0x52A0, KANJI_LEARNING_ORDER_4, // 加 + 0x52A3, KANJI_LEARNING_ORDER_7, // 劣 + 0x52A9, KANJI_LEARNING_ORDER_3, // 助 + 0x52AA, KANJI_LEARNING_ORDER_4, // 努 + 0x52B1, KANJI_LEARNING_ORDER_7, // 励 + 0x52B4, KANJI_LEARNING_ORDER_4, // 劎 + 0x52B9, KANJI_LEARNING_ORDER_5, // 効 + 0x52BE, KANJI_LEARNING_ORDER_7, // 功 + 0x52C5, KANJI_LEARNING_ORDER_7, // 勅 + 0x52C7, KANJI_LEARNING_ORDER_4, // 勇 + 0x52C9, KANJI_LEARNING_ORDER_3, // 勉 + 0x52D5, KANJI_LEARNING_ORDER_3, // 動 + 0x52D8, KANJI_LEARNING_ORDER_7, // 勘 + 0x52D9, KANJI_LEARNING_ORDER_5, // 務 + 0x52DD, KANJI_LEARNING_ORDER_3, // 勝 + 0x52DF, KANJI_LEARNING_ORDER_7, // 募 + 0x52E2, KANJI_LEARNING_ORDER_5, // 勢 + 0x52E4, KANJI_LEARNING_ORDER_6, // å‹€ + 0x52E7, KANJI_LEARNING_ORDER_7, // 勧 + 0x52F2, KANJI_LEARNING_ORDER_7, // 勲 + 0x52FA, KANJI_LEARNING_ORDER_7, // 勺 + 0x5301, KANJI_LEARNING_ORDER_7, // 匁 + 0x5305, KANJI_LEARNING_ORDER_4, // 包 + 0x5316, KANJI_LEARNING_ORDER_3, // 化 + 0x5317, KANJI_LEARNING_ORDER_2, // 北 + 0x5320, KANJI_LEARNING_ORDER_7, // 匠 + 0x5339, KANJI_LEARNING_ORDER_7, // 匹 + 0x533A, KANJI_LEARNING_ORDER_3, // 区 + 0x533B, KANJI_LEARNING_ORDER_3, // 医 + 0x533F, KANJI_LEARNING_ORDER_7, // 匿 + 0x5341, KANJI_LEARNING_ORDER_1, // 十 + 0x5343, KANJI_LEARNING_ORDER_1, // 千 + 0x5347, KANJI_LEARNING_ORDER_7, // 升 + 0x5348, KANJI_LEARNING_ORDER_2, // 午 + 0x534A, KANJI_LEARNING_ORDER_2, // 半 + 0x5351, KANJI_LEARNING_ORDER_7, // 卑 + 0x5352, KANJI_LEARNING_ORDER_4, // 卒 + 0x5353, KANJI_LEARNING_ORDER_7, // 卓 + 0x5354, KANJI_LEARNING_ORDER_4, // 協 + 0x5357, KANJI_LEARNING_ORDER_2, // 南 + 0x5358, KANJI_LEARNING_ORDER_4, // 単 + 0x535A, KANJI_LEARNING_ORDER_4, // 博 + 0x5360, KANJI_LEARNING_ORDER_7, // 占 + 0x5370, KANJI_LEARNING_ORDER_4, // 印 + 0x5371, KANJI_LEARNING_ORDER_6, // 危 + 0x5373, KANJI_LEARNING_ORDER_7, // 即 + 0x5374, KANJI_LEARNING_ORDER_7, // 华 + 0x5375, KANJI_LEARNING_ORDER_6, // 卵 + 0x5378, KANJI_LEARNING_ORDER_7, // 卞 + 0x5384, KANJI_LEARNING_ORDER_7, // 厄 + 0x5398, KANJI_LEARNING_ORDER_7, // 厘 + 0x539A, KANJI_LEARNING_ORDER_5, // 厚 + 0x539F, KANJI_LEARNING_ORDER_2, // 原 + 0x53B3, KANJI_LEARNING_ORDER_6, // 厳 + 0x53BB, KANJI_LEARNING_ORDER_3, // 去 + 0x53C2, KANJI_LEARNING_ORDER_4, // 参 + 0x53C8, KANJI_LEARNING_ORDER_7, // 又 + 0x53CA, KANJI_LEARNING_ORDER_7, // 及 + 0x53CB, KANJI_LEARNING_ORDER_2, // 友 + 0x53CC, KANJI_LEARNING_ORDER_7, // 双 + 0x53CD, KANJI_LEARNING_ORDER_3, // 反 + 0x53CE, KANJI_LEARNING_ORDER_6, // 収 + 0x53D4, KANJI_LEARNING_ORDER_7, // 叔 + 0x53D6, KANJI_LEARNING_ORDER_3, // 取 + 0x53D7, KANJI_LEARNING_ORDER_3, // 受 + 0x53D9, KANJI_LEARNING_ORDER_7, // 叙 + 0x53E3, KANJI_LEARNING_ORDER_1, // 口 + 0x53E4, KANJI_LEARNING_ORDER_2, // 叀 + 0x53E5, KANJI_LEARNING_ORDER_5, // 句 + 0x53EB, KANJI_LEARNING_ORDER_7, // 叫 + 0x53EC, KANJI_LEARNING_ORDER_7, // 召 + 0x53EF, KANJI_LEARNING_ORDER_5, // 可 + 0x53F0, KANJI_LEARNING_ORDER_2, // 台 + 0x53F2, KANJI_LEARNING_ORDER_4, // 史 + 0x53F3, KANJI_LEARNING_ORDER_1, // 右 + 0x53F7, KANJI_LEARNING_ORDER_3, // 号 + 0x53F8, KANJI_LEARNING_ORDER_4, // 叞 + 0x5404, KANJI_LEARNING_ORDER_4, // 各 + 0x5408, KANJI_LEARNING_ORDER_2, // 合 + 0x5409, KANJI_LEARNING_ORDER_7, // 吉 + 0x540C, KANJI_LEARNING_ORDER_2, // 同 + 0x540D, KANJI_LEARNING_ORDER_1, // 名 + 0x540E, KANJI_LEARNING_ORDER_6, // 后 + 0x540F, KANJI_LEARNING_ORDER_7, // 吏 + 0x5410, KANJI_LEARNING_ORDER_7, // 吐 + 0x5411, KANJI_LEARNING_ORDER_3, // 向 + 0x541B, KANJI_LEARNING_ORDER_3, // 君 + 0x541F, KANJI_LEARNING_ORDER_7, // 吟 + 0x5426, KANJI_LEARNING_ORDER_6, // 吊 + 0x542B, KANJI_LEARNING_ORDER_7, // 含 + 0x5438, KANJI_LEARNING_ORDER_6, // 吞 + 0x5439, KANJI_LEARNING_ORDER_7, // 吹 + 0x5448, KANJI_LEARNING_ORDER_7, // 呈 + 0x5449, KANJI_LEARNING_ORDER_7, // 呉 + 0x544A, KANJI_LEARNING_ORDER_4, // 告 + 0x5468, KANJI_LEARNING_ORDER_4, // 呚 + 0x5473, KANJI_LEARNING_ORDER_3, // 味 + 0x547C, KANJI_LEARNING_ORDER_6, // 呌 + 0x547D, KANJI_LEARNING_ORDER_3, // 呜 + 0x548C, KANJI_LEARNING_ORDER_3, // 和 + 0x54B2, KANJI_LEARNING_ORDER_7, // 咲 + 0x54C0, KANJI_LEARNING_ORDER_7, // 哀 + 0x54C1, KANJI_LEARNING_ORDER_3, // 品 + 0x54E1, KANJI_LEARNING_ORDER_3, // 員 + 0x54F2, KANJI_LEARNING_ORDER_7, // 哲 + 0x5506, KANJI_LEARNING_ORDER_7, // 唆 + 0x5507, KANJI_LEARNING_ORDER_7, // 唇 + 0x5510, KANJI_LEARNING_ORDER_7, // 唐 + 0x552F, KANJI_LEARNING_ORDER_7, // 唯 + 0x5531, KANJI_LEARNING_ORDER_4, // 唱 + 0x5546, KANJI_LEARNING_ORDER_3, // 商 + 0x554F, KANJI_LEARNING_ORDER_3, // 問 + 0x5553, KANJI_LEARNING_ORDER_7, // 啓 + 0x5584, KANJI_LEARNING_ORDER_6, // 善 + 0x559A, KANJI_LEARNING_ORDER_7, // 喚 + 0x559C, KANJI_LEARNING_ORDER_4, // 喜 + 0x559D, KANJI_LEARNING_ORDER_7, // 喝 + 0x55AA, KANJI_LEARNING_ORDER_7, // 喪 + 0x55AB, KANJI_LEARNING_ORDER_7, // 喫 + 0x55B6, KANJI_LEARNING_ORDER_5, // 営 + 0x55E3, KANJI_LEARNING_ORDER_7, // 嗣 + 0x5606, KANJI_LEARNING_ORDER_7, // 嘆 + 0x5631, KANJI_LEARNING_ORDER_7, // 嘱 + 0x5668, KANJI_LEARNING_ORDER_4, // 噚 + 0x5674, KANJI_LEARNING_ORDER_7, // 噎 + 0x5687, KANJI_LEARNING_ORDER_7, // 嚇 + 0x56DA, KANJI_LEARNING_ORDER_7, // 囚 + 0x56DB, KANJI_LEARNING_ORDER_1, // 四 + 0x56DE, KANJI_LEARNING_ORDER_2, // 回 + 0x56E0, KANJI_LEARNING_ORDER_5, // 因 + 0x56E3, KANJI_LEARNING_ORDER_5, // 団 + 0x56F0, KANJI_LEARNING_ORDER_6, // 困 + 0x56F2, KANJI_LEARNING_ORDER_4, // 囲 + 0x56F3, KANJI_LEARNING_ORDER_2, // 図 + 0x56FA, KANJI_LEARNING_ORDER_4, // 固 + 0x56FD, KANJI_LEARNING_ORDER_2, // 囜 + 0x570F, KANJI_LEARNING_ORDER_7, // 圏 + 0x5712, KANJI_LEARNING_ORDER_2, // 園 + 0x571F, KANJI_LEARNING_ORDER_1, // 土 + 0x5727, KANJI_LEARNING_ORDER_5, // 圧 + 0x5728, KANJI_LEARNING_ORDER_5, // 圚 + 0x5730, KANJI_LEARNING_ORDER_2, // 地 + 0x5742, KANJI_LEARNING_ORDER_3, // 坂 + 0x5747, KANJI_LEARNING_ORDER_5, // 均 + 0x574A, KANJI_LEARNING_ORDER_7, // 坊 + 0x5751, KANJI_LEARNING_ORDER_7, // 坑 + 0x576A, KANJI_LEARNING_ORDER_7, // 坪 + 0x5782, KANJI_LEARNING_ORDER_6, // 垂 + 0x578B, KANJI_LEARNING_ORDER_4, // 型 + 0x57A3, KANJI_LEARNING_ORDER_7, // 垣 + 0x57CB, KANJI_LEARNING_ORDER_7, // 埋 + 0x57CE, KANJI_LEARNING_ORDER_6, // 城 + 0x57DF, KANJI_LEARNING_ORDER_6, // 域 + 0x57F7, KANJI_LEARNING_ORDER_7, // 執 + 0x57F9, KANJI_LEARNING_ORDER_7, // 培 + 0x57FA, KANJI_LEARNING_ORDER_5, // 基 + 0x5800, KANJI_LEARNING_ORDER_7, // 堀 + 0x5802, KANJI_LEARNING_ORDER_4, // 堂 + 0x5805, KANJI_LEARNING_ORDER_7, // 堅 + 0x5815, KANJI_LEARNING_ORDER_7, // 堕 + 0x5824, KANJI_LEARNING_ORDER_7, // å € + 0x582A, KANJI_LEARNING_ORDER_7, // å ª + 0x5831, KANJI_LEARNING_ORDER_5, // å ± + 0x5834, KANJI_LEARNING_ORDER_2, // å Ž + 0x5840, KANJI_LEARNING_ORDER_7, // 塀 + 0x5841, KANJI_LEARNING_ORDER_7, // 塁 + 0x584A, KANJI_LEARNING_ORDER_7, // 塊 + 0x5851, KANJI_LEARNING_ORDER_7, // 塑 + 0x5854, KANJI_LEARNING_ORDER_7, // 塔 + 0x5857, KANJI_LEARNING_ORDER_7, // 塗 + 0x585A, KANJI_LEARNING_ORDER_7, // 塚 + 0x5869, KANJI_LEARNING_ORDER_4, // å¡© + 0x587E, KANJI_LEARNING_ORDER_7, // 塟 + 0x5883, KANJI_LEARNING_ORDER_5, // 境 + 0x5893, KANJI_LEARNING_ORDER_5, // 墓 + 0x5897, KANJI_LEARNING_ORDER_5, // 増 + 0x589C, KANJI_LEARNING_ORDER_7, // 墜 + 0x58A8, KANJI_LEARNING_ORDER_7, // 墚 + 0x58B3, KANJI_LEARNING_ORDER_7, // 墳 + 0x58BE, KANJI_LEARNING_ORDER_7, // 墟 + 0x58C1, KANJI_LEARNING_ORDER_7, // 壁 + 0x58C7, KANJI_LEARNING_ORDER_7, // 壇 + 0x58CA, KANJI_LEARNING_ORDER_7, // 壊 + 0x58CC, KANJI_LEARNING_ORDER_7, // 壌 + 0x58EB, KANJI_LEARNING_ORDER_4, // 士 + 0x58EE, KANJI_LEARNING_ORDER_7, // 壮 + 0x58F0, KANJI_LEARNING_ORDER_2, // 声 + 0x58F1, KANJI_LEARNING_ORDER_7, // 壱 + 0x58F2, KANJI_LEARNING_ORDER_2, // 売 + 0x5909, KANJI_LEARNING_ORDER_4, // 倉 + 0x590F, KANJI_LEARNING_ORDER_2, // 倏 + 0x5915, KANJI_LEARNING_ORDER_1, // 倕 + 0x5916, KANJI_LEARNING_ORDER_2, // 倖 + 0x591A, KANJI_LEARNING_ORDER_2, // 倚 + 0x591C, KANJI_LEARNING_ORDER_2, // 倜 + 0x5922, KANJI_LEARNING_ORDER_5, // 倢 + 0x5927, KANJI_LEARNING_ORDER_1, // 倧 + 0x5929, KANJI_LEARNING_ORDER_1, // 倩 + 0x592A, KANJI_LEARNING_ORDER_2, // 倪 + 0x592B, KANJI_LEARNING_ORDER_4, // 倫 + 0x592E, KANJI_LEARNING_ORDER_3, // 倮 + 0x5931, KANJI_LEARNING_ORDER_4, // 倱 + 0x5947, KANJI_LEARNING_ORDER_7, // 奇 + 0x5949, KANJI_LEARNING_ORDER_7, // 奉 + 0x594F, KANJI_LEARNING_ORDER_6, // 奏 + 0x5951, KANJI_LEARNING_ORDER_7, // 契 + 0x5954, KANJI_LEARNING_ORDER_7, // 奔 + 0x5965, KANJI_LEARNING_ORDER_7, // 奥 + 0x5968, KANJI_LEARNING_ORDER_7, // 奚 + 0x596A, KANJI_LEARNING_ORDER_7, // 奪 + 0x596E, KANJI_LEARNING_ORDER_6, // 奮 + 0x5973, KANJI_LEARNING_ORDER_1, // 女 + 0x5974, KANJI_LEARNING_ORDER_7, // 奎 + 0x597D, KANJI_LEARNING_ORDER_4, // 奜 + 0x5982, KANJI_LEARNING_ORDER_7, // 劂 + 0x5983, KANJI_LEARNING_ORDER_7, // 劃 + 0x5984, KANJI_LEARNING_ORDER_7, // 劄 + 0x598A, KANJI_LEARNING_ORDER_7, // 劊 + 0x5999, KANJI_LEARNING_ORDER_7, // 劙 + 0x59A5, KANJI_LEARNING_ORDER_7, // 劥 + 0x59A8, KANJI_LEARNING_ORDER_7, // 劚 + 0x59B9, KANJI_LEARNING_ORDER_2, // 効 + 0x59BB, KANJI_LEARNING_ORDER_5, // 劻 + 0x59C9, KANJI_LEARNING_ORDER_2, // 姉 + 0x59CB, KANJI_LEARNING_ORDER_3, // 始 + 0x59D3, KANJI_LEARNING_ORDER_7, // 姓 + 0x59D4, KANJI_LEARNING_ORDER_3, // 委 + 0x59EB, KANJI_LEARNING_ORDER_7, // å§« + 0x59FB, KANJI_LEARNING_ORDER_7, // å§» + 0x59FF, KANJI_LEARNING_ORDER_6, // å§¿ + 0x5A01, KANJI_LEARNING_ORDER_7, // 嚁 + 0x5A18, KANJI_LEARNING_ORDER_7, // 嚘 + 0x5A20, KANJI_LEARNING_ORDER_7, // åš  + 0x5A2F, KANJI_LEARNING_ORDER_7, // 嚯 + 0x5A46, KANJI_LEARNING_ORDER_7, // 婆 + 0x5A5A, KANJI_LEARNING_ORDER_7, // 婚 + 0x5A66, KANJI_LEARNING_ORDER_5, // 婊 + 0x5A7F, KANJI_LEARNING_ORDER_7, // å©¿ + 0x5A92, KANJI_LEARNING_ORDER_7, // 媒 + 0x5AC1, KANJI_LEARNING_ORDER_7, // 嫁 + 0x5ACC, KANJI_LEARNING_ORDER_7, // 嫌 + 0x5AE1, KANJI_LEARNING_ORDER_7, // å«¡ + 0x5B22, KANJI_LEARNING_ORDER_7, // 嬢 + 0x5B50, KANJI_LEARNING_ORDER_1, // 子 + 0x5B54, KANJI_LEARNING_ORDER_7, // 孔 + 0x5B57, KANJI_LEARNING_ORDER_1, // 字 + 0x5B58, KANJI_LEARNING_ORDER_6, // 存 + 0x5B5D, KANJI_LEARNING_ORDER_6, // 孝 + 0x5B63, KANJI_LEARNING_ORDER_4, // å­£ + 0x5B64, KANJI_LEARNING_ORDER_7, // å­€ + 0x5B66, KANJI_LEARNING_ORDER_1, // å­Š + 0x5B6B, KANJI_LEARNING_ORDER_4, // å­« + 0x5B85, KANJI_LEARNING_ORDER_6, // 宅 + 0x5B87, KANJI_LEARNING_ORDER_6, // 宇 + 0x5B88, KANJI_LEARNING_ORDER_3, // 守 + 0x5B89, KANJI_LEARNING_ORDER_3, // 安 + 0x5B8C, KANJI_LEARNING_ORDER_4, // 完 + 0x5B97, KANJI_LEARNING_ORDER_6, // 宗 + 0x5B98, KANJI_LEARNING_ORDER_4, // 官 + 0x5B99, KANJI_LEARNING_ORDER_6, // 宙 + 0x5B9A, KANJI_LEARNING_ORDER_3, // 定 + 0x5B9C, KANJI_LEARNING_ORDER_7, // 宜 + 0x5B9D, KANJI_LEARNING_ORDER_6, // 宝 + 0x5B9F, KANJI_LEARNING_ORDER_3, // 実 + 0x5BA2, KANJI_LEARNING_ORDER_3, // 客 + 0x5BA3, KANJI_LEARNING_ORDER_6, // 宣 + 0x5BA4, KANJI_LEARNING_ORDER_2, // 宀 + 0x5BAE, KANJI_LEARNING_ORDER_3, // å®® + 0x5BB0, KANJI_LEARNING_ORDER_7, // å®° + 0x5BB3, KANJI_LEARNING_ORDER_4, // 害 + 0x5BB4, KANJI_LEARNING_ORDER_7, // 宎 + 0x5BB5, KANJI_LEARNING_ORDER_7, // 宵 + 0x5BB6, KANJI_LEARNING_ORDER_2, // å®¶ + 0x5BB9, KANJI_LEARNING_ORDER_5, // 容 + 0x5BBF, KANJI_LEARNING_ORDER_3, // 宿 + 0x5BC2, KANJI_LEARNING_ORDER_7, // 寂 + 0x5BC4, KANJI_LEARNING_ORDER_5, // 寄 + 0x5BC6, KANJI_LEARNING_ORDER_6, // 密 + 0x5BCC, KANJI_LEARNING_ORDER_5, // 富 + 0x5BD2, KANJI_LEARNING_ORDER_3, // 寒 + 0x5BDB, KANJI_LEARNING_ORDER_7, // 寛 + 0x5BDD, KANJI_LEARNING_ORDER_7, // 寝 + 0x5BDF, KANJI_LEARNING_ORDER_4, // 察 + 0x5BE1, KANJI_LEARNING_ORDER_7, // 寡 + 0x5BE7, KANJI_LEARNING_ORDER_7, // 寧 + 0x5BE9, KANJI_LEARNING_ORDER_7, // 審 + 0x5BEE, KANJI_LEARNING_ORDER_7, // 寮 + 0x5BF8, KANJI_LEARNING_ORDER_6, // 寞 + 0x5BFA, KANJI_LEARNING_ORDER_2, // 寺 + 0x5BFE, KANJI_LEARNING_ORDER_3, // 察 + 0x5BFF, KANJI_LEARNING_ORDER_7, // 寿 + 0x5C01, KANJI_LEARNING_ORDER_7, // 封 + 0x5C02, KANJI_LEARNING_ORDER_6, // 専 + 0x5C04, KANJI_LEARNING_ORDER_6, // 射 + 0x5C06, KANJI_LEARNING_ORDER_6, // 将 + 0x5C09, KANJI_LEARNING_ORDER_7, // 尉 + 0x5C0A, KANJI_LEARNING_ORDER_6, // 尊 + 0x5C0B, KANJI_LEARNING_ORDER_7, // 尋 + 0x5C0E, KANJI_LEARNING_ORDER_5, // 導 + 0x5C0F, KANJI_LEARNING_ORDER_1, // 小 + 0x5C11, KANJI_LEARNING_ORDER_2, // 少 + 0x5C1A, KANJI_LEARNING_ORDER_7, // 尚 + 0x5C31, KANJI_LEARNING_ORDER_6, // å°± + 0x5C3A, KANJI_LEARNING_ORDER_6, // å°º + 0x5C3C, KANJI_LEARNING_ORDER_7, // å°Œ + 0x5C3D, KANJI_LEARNING_ORDER_7, // å°œ + 0x5C3E, KANJI_LEARNING_ORDER_7, // å°Ÿ + 0x5C3F, KANJI_LEARNING_ORDER_7, // å°¿ + 0x5C40, KANJI_LEARNING_ORDER_3, // 局 + 0x5C45, KANJI_LEARNING_ORDER_5, // 居 + 0x5C48, KANJI_LEARNING_ORDER_7, // 屈 + 0x5C4A, KANJI_LEARNING_ORDER_6, // 届 + 0x5C4B, KANJI_LEARNING_ORDER_3, // 屋 + 0x5C55, KANJI_LEARNING_ORDER_6, // 展 + 0x5C5E, KANJI_LEARNING_ORDER_5, // 属 + 0x5C64, KANJI_LEARNING_ORDER_6, // å±€ + 0x5C65, KANJI_LEARNING_ORDER_7, // å±¥ + 0x5C6F, KANJI_LEARNING_ORDER_7, // 屯 + 0x5C71, KANJI_LEARNING_ORDER_1, // å±± + 0x5C90, KANJI_LEARNING_ORDER_7, // 岐 + 0x5CA9, KANJI_LEARNING_ORDER_2, // 岩 + 0x5CAC, KANJI_LEARNING_ORDER_7, // 岬 + 0x5CB3, KANJI_LEARNING_ORDER_7, // å²³ + 0x5CB8, KANJI_LEARNING_ORDER_3, // 岞 + 0x5CE0, KANJI_LEARNING_ORDER_7, // å³  + 0x5CE1, KANJI_LEARNING_ORDER_7, // 峡 + 0x5CF0, KANJI_LEARNING_ORDER_7, // å³° + 0x5CF6, KANJI_LEARNING_ORDER_3, // å³¶ + 0x5D07, KANJI_LEARNING_ORDER_7, // 厇 + 0x5D0E, KANJI_LEARNING_ORDER_7, // 厎 + 0x5D29, KANJI_LEARNING_ORDER_7, // 厩 + 0x5DDD, KANJI_LEARNING_ORDER_1, // 川 + 0x5DDE, KANJI_LEARNING_ORDER_3, // 州 + 0x5DE1, KANJI_LEARNING_ORDER_7, // å·¡ + 0x5DE3, KANJI_LEARNING_ORDER_4, // å·£ + 0x5DE5, KANJI_LEARNING_ORDER_2, // å·¥ + 0x5DE6, KANJI_LEARNING_ORDER_1, // å·Š + 0x5DE7, KANJI_LEARNING_ORDER_7, // å·§ + 0x5DE8, KANJI_LEARNING_ORDER_7, // å·š + 0x5DEE, KANJI_LEARNING_ORDER_4, // å·® + 0x5DF1, KANJI_LEARNING_ORDER_6, // å·± + 0x5DFB, KANJI_LEARNING_ORDER_6, // å·» + 0x5E02, KANJI_LEARNING_ORDER_2, // åž‚ + 0x5E03, KANJI_LEARNING_ORDER_5, // 垃 + 0x5E06, KANJI_LEARNING_ORDER_7, // 垆 + 0x5E0C, KANJI_LEARNING_ORDER_4, // 垌 + 0x5E1D, KANJI_LEARNING_ORDER_7, // 垝 + 0x5E25, KANJI_LEARNING_ORDER_7, // 垥 + 0x5E2B, KANJI_LEARNING_ORDER_5, // åž« + 0x5E2D, KANJI_LEARNING_ORDER_4, // åž­ + 0x5E2F, KANJI_LEARNING_ORDER_4, // 垯 + 0x5E30, KANJI_LEARNING_ORDER_2, // åž° + 0x5E33, KANJI_LEARNING_ORDER_3, // åž³ + 0x5E38, KANJI_LEARNING_ORDER_5, // åžž + 0x5E3D, KANJI_LEARNING_ORDER_7, // åžœ + 0x5E45, KANJI_LEARNING_ORDER_7, // 幅 + 0x5E55, KANJI_LEARNING_ORDER_6, // 幕 + 0x5E63, KANJI_LEARNING_ORDER_7, // å¹£ + 0x5E72, KANJI_LEARNING_ORDER_6, // å¹² + 0x5E73, KANJI_LEARNING_ORDER_3, // å¹³ + 0x5E74, KANJI_LEARNING_ORDER_1, // 幎 + 0x5E78, KANJI_LEARNING_ORDER_3, // 幞 + 0x5E79, KANJI_LEARNING_ORDER_5, // å¹¹ + 0x5E7B, KANJI_LEARNING_ORDER_7, // å¹» + 0x5E7C, KANJI_LEARNING_ORDER_6, // 幌 + 0x5E7D, KANJI_LEARNING_ORDER_7, // 幜 + 0x5E7E, KANJI_LEARNING_ORDER_7, // 幟 + 0x5E81, KANJI_LEARNING_ORDER_6, // 庁 + 0x5E83, KANJI_LEARNING_ORDER_2, // 広 + 0x5E8A, KANJI_LEARNING_ORDER_7, // 床 + 0x5E8F, KANJI_LEARNING_ORDER_5, // 序 + 0x5E95, KANJI_LEARNING_ORDER_4, // 底 + 0x5E97, KANJI_LEARNING_ORDER_2, // 店 + 0x5E9C, KANJI_LEARNING_ORDER_4, // 府 + 0x5EA6, KANJI_LEARNING_ORDER_3, // 床 + 0x5EA7, KANJI_LEARNING_ORDER_6, // 座 + 0x5EAB, KANJI_LEARNING_ORDER_3, // 庫 + 0x5EAD, KANJI_LEARNING_ORDER_3, // 庭 + 0x5EB6, KANJI_LEARNING_ORDER_7, // 庶 + 0x5EB7, KANJI_LEARNING_ORDER_4, // 康 + 0x5EB8, KANJI_LEARNING_ORDER_7, // 庞 + 0x5EC3, KANJI_LEARNING_ORDER_7, // 廃 + 0x5EC9, KANJI_LEARNING_ORDER_7, // 廉 + 0x5ECA, KANJI_LEARNING_ORDER_7, // 廊 + 0x5EF6, KANJI_LEARNING_ORDER_6, // å»¶ + 0x5EF7, KANJI_LEARNING_ORDER_7, // å»· + 0x5EFA, KANJI_LEARNING_ORDER_4, // 建 + 0x5F01, KANJI_LEARNING_ORDER_5, // 匁 + 0x5F0A, KANJI_LEARNING_ORDER_7, // 匊 + 0x5F0F, KANJI_LEARNING_ORDER_3, // 匏 + 0x5F10, KANJI_LEARNING_ORDER_7, // 匐 + 0x5F13, KANJI_LEARNING_ORDER_2, // 匓 + 0x5F14, KANJI_LEARNING_ORDER_7, // 匔 + 0x5F15, KANJI_LEARNING_ORDER_2, // 匕 + 0x5F1F, KANJI_LEARNING_ORDER_2, // 匟 + 0x5F26, KANJI_LEARNING_ORDER_7, // 匊 + 0x5F27, KANJI_LEARNING_ORDER_7, // 匧 + 0x5F31, KANJI_LEARNING_ORDER_2, // 匱 + 0x5F35, KANJI_LEARNING_ORDER_5, // 匵 + 0x5F37, KANJI_LEARNING_ORDER_2, // 匷 + 0x5F3E, KANJI_LEARNING_ORDER_7, // 匟 + 0x5F53, KANJI_LEARNING_ORDER_2, // 圓 + 0x5F62, KANJI_LEARNING_ORDER_2, // 圢 + 0x5F69, KANJI_LEARNING_ORDER_7, // 圩 + 0x5F6B, KANJI_LEARNING_ORDER_7, // 圫 + 0x5F70, KANJI_LEARNING_ORDER_7, // 地 + 0x5F71, KANJI_LEARNING_ORDER_7, // 圱 + 0x5F79, KANJI_LEARNING_ORDER_3, // 圹 + 0x5F7C, KANJI_LEARNING_ORDER_7, // 圌 + 0x5F80, KANJI_LEARNING_ORDER_5, // 埀 + 0x5F81, KANJI_LEARNING_ORDER_7, // 埁 + 0x5F84, KANJI_LEARNING_ORDER_4, // 埄 + 0x5F85, KANJI_LEARNING_ORDER_3, // 埅 + 0x5F8B, KANJI_LEARNING_ORDER_6, // 埋 + 0x5F8C, KANJI_LEARNING_ORDER_2, // 埌 + 0x5F90, KANJI_LEARNING_ORDER_7, // 埐 + 0x5F92, KANJI_LEARNING_ORDER_4, // 埒 + 0x5F93, KANJI_LEARNING_ORDER_6, // 埓 + 0x5F97, KANJI_LEARNING_ORDER_4, // 埗 + 0x5FA1, KANJI_LEARNING_ORDER_7, // 埡 + 0x5FA9, KANJI_LEARNING_ORDER_5, // 埩 + 0x5FAA, KANJI_LEARNING_ORDER_7, // 埪 + 0x5FAE, KANJI_LEARNING_ORDER_7, // 埮 + 0x5FB3, KANJI_LEARNING_ORDER_5, // 埳 + 0x5FB4, KANJI_LEARNING_ORDER_7, // 城 + 0x5FB9, KANJI_LEARNING_ORDER_7, // 培 + 0x5FC3, KANJI_LEARNING_ORDER_2, // 心 + 0x5FC5, KANJI_LEARNING_ORDER_4, // 必 + 0x5FCC, KANJI_LEARNING_ORDER_7, // 忌 + 0x5FCD, KANJI_LEARNING_ORDER_7, // 忍 + 0x5FD7, KANJI_LEARNING_ORDER_5, // 志 + 0x5FD8, KANJI_LEARNING_ORDER_6, // 忘 + 0x5FD9, KANJI_LEARNING_ORDER_7, // 忙 + 0x5FDC, KANJI_LEARNING_ORDER_5, // 応 + 0x5FE0, KANJI_LEARNING_ORDER_6, // å¿  + 0x5FEB, KANJI_LEARNING_ORDER_5, // å¿« + 0x5FF5, KANJI_LEARNING_ORDER_4, // 念 + 0x6012, KANJI_LEARNING_ORDER_7, // 怒 + 0x6016, KANJI_LEARNING_ORDER_7, // 怖 + 0x601D, KANJI_LEARNING_ORDER_2, // 思 + 0x6020, KANJI_LEARNING_ORDER_7, // 怠 + 0x6025, KANJI_LEARNING_ORDER_3, // 急 + 0x6027, KANJI_LEARNING_ORDER_5, // 性 + 0x602A, KANJI_LEARNING_ORDER_7, // 怪 + 0x604B, KANJI_LEARNING_ORDER_7, // 恋 + 0x6050, KANJI_LEARNING_ORDER_7, // 恐 + 0x6052, KANJI_LEARNING_ORDER_7, // 恒 + 0x6065, KANJI_LEARNING_ORDER_7, // 恥 + 0x6068, KANJI_LEARNING_ORDER_7, // 恚 + 0x6069, KANJI_LEARNING_ORDER_5, // 恩 + 0x606D, KANJI_LEARNING_ORDER_7, // 恭 + 0x606F, KANJI_LEARNING_ORDER_3, // 息 + 0x6075, KANJI_LEARNING_ORDER_7, // 恵 + 0x6094, KANJI_LEARNING_ORDER_7, // 悔 + 0x609F, KANJI_LEARNING_ORDER_7, // 悟 + 0x60A0, KANJI_LEARNING_ORDER_7, // 悠 + 0x60A3, KANJI_LEARNING_ORDER_7, // 患 + 0x60A6, KANJI_LEARNING_ORDER_7, // 悊 + 0x60A9, KANJI_LEARNING_ORDER_7, // 悩 + 0x60AA, KANJI_LEARNING_ORDER_3, // 悪 + 0x60B2, KANJI_LEARNING_ORDER_3, // 悲 + 0x60BC, KANJI_LEARNING_ORDER_7, // 悌 + 0x60C5, KANJI_LEARNING_ORDER_5, // 情 + 0x60D1, KANJI_LEARNING_ORDER_7, // 惑 + 0x60DC, KANJI_LEARNING_ORDER_7, // 惜 + 0x60E8, KANJI_LEARNING_ORDER_7, // 惚 + 0x60F0, KANJI_LEARNING_ORDER_7, // 惰 + 0x60F3, KANJI_LEARNING_ORDER_3, // 想 + 0x6101, KANJI_LEARNING_ORDER_7, // 愁 + 0x6109, KANJI_LEARNING_ORDER_7, // 愉 + 0x610F, KANJI_LEARNING_ORDER_3, // 意 + 0x611A, KANJI_LEARNING_ORDER_7, // 愚 + 0x611B, KANJI_LEARNING_ORDER_4, // 愛 + 0x611F, KANJI_LEARNING_ORDER_3, // 感 + 0x6148, KANJI_LEARNING_ORDER_7, // 慈 + 0x614B, KANJI_LEARNING_ORDER_5, // 態 + 0x614C, KANJI_LEARNING_ORDER_7, // 慌 + 0x614E, KANJI_LEARNING_ORDER_7, // 慎 + 0x6155, KANJI_LEARNING_ORDER_7, // 慕 + 0x6162, KANJI_LEARNING_ORDER_7, // 慢 + 0x6163, KANJI_LEARNING_ORDER_5, // 慣 + 0x6168, KANJI_LEARNING_ORDER_7, // æ…š + 0x616E, KANJI_LEARNING_ORDER_7, // 慮 + 0x6170, KANJI_LEARNING_ORDER_7, // 慰 + 0x6176, KANJI_LEARNING_ORDER_7, // 慶 + 0x6182, KANJI_LEARNING_ORDER_7, // 憂 + 0x618E, KANJI_LEARNING_ORDER_7, // 憎 + 0x61A4, KANJI_LEARNING_ORDER_7, // 憀 + 0x61A9, KANJI_LEARNING_ORDER_7, // 憩 + 0x61B2, KANJI_LEARNING_ORDER_6, // 憲 + 0x61B6, KANJI_LEARNING_ORDER_7, // 憶 + 0x61BE, KANJI_LEARNING_ORDER_7, // 憟 + 0x61C7, KANJI_LEARNING_ORDER_7, // 懇 + 0x61D0, KANJI_LEARNING_ORDER_7, // 懐 + 0x61F2, KANJI_LEARNING_ORDER_7, // 懲 + 0x61F8, KANJI_LEARNING_ORDER_7, // 懞 + 0x6210, KANJI_LEARNING_ORDER_4, // 成 + 0x6211, KANJI_LEARNING_ORDER_6, // 我 + 0x6212, KANJI_LEARNING_ORDER_7, // 戒 + 0x6226, KANJI_LEARNING_ORDER_4, // 戊 + 0x622F, KANJI_LEARNING_ORDER_7, // 戯 + 0x6238, KANJI_LEARNING_ORDER_2, // 戞 + 0x623B, KANJI_LEARNING_ORDER_7, // 戻 + 0x623F, KANJI_LEARNING_ORDER_7, // 房 + 0x6240, KANJI_LEARNING_ORDER_3, // 所 + 0x6247, KANJI_LEARNING_ORDER_7, // 扇 + 0x6249, KANJI_LEARNING_ORDER_7, // 扉 + 0x624B, KANJI_LEARNING_ORDER_1, // 手 + 0x624D, KANJI_LEARNING_ORDER_2, // 才 + 0x6253, KANJI_LEARNING_ORDER_3, // 打 + 0x6255, KANJI_LEARNING_ORDER_7, // 払 + 0x6271, KANJI_LEARNING_ORDER_7, // 扱 + 0x6276, KANJI_LEARNING_ORDER_7, // 扶 + 0x6279, KANJI_LEARNING_ORDER_6, // 批 + 0x627F, KANJI_LEARNING_ORDER_5, // 承 + 0x6280, KANJI_LEARNING_ORDER_5, // 技 + 0x6284, KANJI_LEARNING_ORDER_7, // 抄 + 0x628A, KANJI_LEARNING_ORDER_7, // 把 + 0x6291, KANJI_LEARNING_ORDER_7, // 抑 + 0x6295, KANJI_LEARNING_ORDER_3, // 投 + 0x6297, KANJI_LEARNING_ORDER_7, // 抗 + 0x6298, KANJI_LEARNING_ORDER_4, // 折 + 0x629C, KANJI_LEARNING_ORDER_7, // 抜 + 0x629E, KANJI_LEARNING_ORDER_7, // 択 + 0x62AB, KANJI_LEARNING_ORDER_7, // 披 + 0x62B1, KANJI_LEARNING_ORDER_7, // 抱 + 0x62B5, KANJI_LEARNING_ORDER_7, // 抵 + 0x62B9, KANJI_LEARNING_ORDER_7, // 抹 + 0x62BC, KANJI_LEARNING_ORDER_7, // 抌 + 0x62BD, KANJI_LEARNING_ORDER_7, // 抜 + 0x62C5, KANJI_LEARNING_ORDER_6, // 担 + 0x62CD, KANJI_LEARNING_ORDER_7, // 拍 + 0x62D0, KANJI_LEARNING_ORDER_7, // 拐 + 0x62D2, KANJI_LEARNING_ORDER_7, // 拒 + 0x62D3, KANJI_LEARNING_ORDER_7, // 拓 + 0x62D8, KANJI_LEARNING_ORDER_7, // 拘 + 0x62D9, KANJI_LEARNING_ORDER_7, // 拙 + 0x62DB, KANJI_LEARNING_ORDER_5, // 招 + 0x62DD, KANJI_LEARNING_ORDER_6, // 拝 + 0x62E0, KANJI_LEARNING_ORDER_7, // 拠 + 0x62E1, KANJI_LEARNING_ORDER_6, // 拡 + 0x62EC, KANJI_LEARNING_ORDER_7, // 括 + 0x62F7, KANJI_LEARNING_ORDER_7, // 拷 + 0x62FE, KANJI_LEARNING_ORDER_3, // 拟 + 0x6301, KANJI_LEARNING_ORDER_3, // 持 + 0x6307, KANJI_LEARNING_ORDER_3, // 指 + 0x6311, KANJI_LEARNING_ORDER_7, // 挑 + 0x6319, KANJI_LEARNING_ORDER_4, // 挙 + 0x631F, KANJI_LEARNING_ORDER_7, // 挟 + 0x632F, KANJI_LEARNING_ORDER_7, // 振 + 0x633F, KANJI_LEARNING_ORDER_7, // 挿 + 0x6355, KANJI_LEARNING_ORDER_7, // 捕 + 0x635C, KANJI_LEARNING_ORDER_7, // 捜 + 0x6368, KANJI_LEARNING_ORDER_6, // 捚 + 0x636E, KANJI_LEARNING_ORDER_7, // 据 + 0x6383, KANJI_LEARNING_ORDER_7, // 掃 + 0x6388, KANJI_LEARNING_ORDER_5, // 授 + 0x638C, KANJI_LEARNING_ORDER_7, // 掌 + 0x6392, KANJI_LEARNING_ORDER_7, // 排 + 0x6398, KANJI_LEARNING_ORDER_7, // 掘 + 0x639B, KANJI_LEARNING_ORDER_7, // 掛 + 0x63A1, KANJI_LEARNING_ORDER_5, // 採 + 0x63A2, KANJI_LEARNING_ORDER_6, // 探 + 0x63A5, KANJI_LEARNING_ORDER_5, // 接 + 0x63A7, KANJI_LEARNING_ORDER_7, // 控 + 0x63A8, KANJI_LEARNING_ORDER_6, // 掚 + 0x63AA, KANJI_LEARNING_ORDER_7, // 措 + 0x63B2, KANJI_LEARNING_ORDER_7, // 掲 + 0x63CF, KANJI_LEARNING_ORDER_7, // 描 + 0x63D0, KANJI_LEARNING_ORDER_5, // 提 + 0x63DA, KANJI_LEARNING_ORDER_7, // 揚 + 0x63DB, KANJI_LEARNING_ORDER_7, // 換 + 0x63E1, KANJI_LEARNING_ORDER_7, // 握 + 0x63EE, KANJI_LEARNING_ORDER_6, // 揮 + 0x63F4, KANJI_LEARNING_ORDER_7, // 揎 + 0x63FA, KANJI_LEARNING_ORDER_7, // 揺 + 0x640D, KANJI_LEARNING_ORDER_5, // 損 + 0x642C, KANJI_LEARNING_ORDER_7, // 搬 + 0x642D, KANJI_LEARNING_ORDER_7, // 搭 + 0x643A, KANJI_LEARNING_ORDER_7, // 携 + 0x643E, KANJI_LEARNING_ORDER_7, // 搟 + 0x6442, KANJI_LEARNING_ORDER_7, // 摂 + 0x6458, KANJI_LEARNING_ORDER_7, // 摘 + 0x6469, KANJI_LEARNING_ORDER_7, // 摩 + 0x6483, KANJI_LEARNING_ORDER_7, // 撃 + 0x64A4, KANJI_LEARNING_ORDER_7, // æ’€ + 0x64AE, KANJI_LEARNING_ORDER_7, // 撮 + 0x64B2, KANJI_LEARNING_ORDER_7, // 撲 + 0x64C1, KANJI_LEARNING_ORDER_7, // 擁 + 0x64CD, KANJI_LEARNING_ORDER_6, // 操 + 0x64E6, KANJI_LEARNING_ORDER_7, // 擊 + 0x64EC, KANJI_LEARNING_ORDER_7, // 擬 + 0x652F, KANJI_LEARNING_ORDER_5, // 支 + 0x6539, KANJI_LEARNING_ORDER_4, // 改 + 0x653B, KANJI_LEARNING_ORDER_7, // 攻 + 0x653E, KANJI_LEARNING_ORDER_3, // 攟 + 0x653F, KANJI_LEARNING_ORDER_5, // 政 + 0x6545, KANJI_LEARNING_ORDER_5, // 故 + 0x654F, KANJI_LEARNING_ORDER_7, // 敏 + 0x6551, KANJI_LEARNING_ORDER_4, // 救 + 0x6557, KANJI_LEARNING_ORDER_4, // 敗 + 0x6559, KANJI_LEARNING_ORDER_2, // 教 + 0x6562, KANJI_LEARNING_ORDER_7, // 敢 + 0x6563, KANJI_LEARNING_ORDER_4, // 散 + 0x656C, KANJI_LEARNING_ORDER_6, // 敬 + 0x6570, KANJI_LEARNING_ORDER_2, // 数 + 0x6574, KANJI_LEARNING_ORDER_3, // 敎 + 0x6575, KANJI_LEARNING_ORDER_5, // 敵 + 0x6577, KANJI_LEARNING_ORDER_7, // 敷 + 0x6587, KANJI_LEARNING_ORDER_1, // 文 + 0x6589, KANJI_LEARNING_ORDER_7, // 斉 + 0x658E, KANJI_LEARNING_ORDER_7, // 斎 + 0x6597, KANJI_LEARNING_ORDER_7, // 斗 + 0x6599, KANJI_LEARNING_ORDER_4, // 料 + 0x659C, KANJI_LEARNING_ORDER_7, // 斜 + 0x65A4, KANJI_LEARNING_ORDER_7, // æ–€ + 0x65A5, KANJI_LEARNING_ORDER_7, // 斥 + 0x65AD, KANJI_LEARNING_ORDER_5, // 断 + 0x65B0, KANJI_LEARNING_ORDER_2, // 新 + 0x65B9, KANJI_LEARNING_ORDER_2, // 方 + 0x65BD, KANJI_LEARNING_ORDER_7, // æ–œ + 0x65C5, KANJI_LEARNING_ORDER_3, // 旅 + 0x65CB, KANJI_LEARNING_ORDER_7, // 旋 + 0x65CF, KANJI_LEARNING_ORDER_3, // 族 + 0x65D7, KANJI_LEARNING_ORDER_4, // 旗 + 0x65E2, KANJI_LEARNING_ORDER_7, // 既 + 0x65E5, KANJI_LEARNING_ORDER_1, // 日 + 0x65E7, KANJI_LEARNING_ORDER_5, // 旧 + 0x65E8, KANJI_LEARNING_ORDER_7, // æ—š + 0x65E9, KANJI_LEARNING_ORDER_1, // 早 + 0x65EC, KANJI_LEARNING_ORDER_7, // 旬 + 0x6606, KANJI_LEARNING_ORDER_7, // 昆 + 0x6607, KANJI_LEARNING_ORDER_7, // 昇 + 0x660E, KANJI_LEARNING_ORDER_2, // 明 + 0x6613, KANJI_LEARNING_ORDER_5, // 易 + 0x6614, KANJI_LEARNING_ORDER_3, // 昔 + 0x661F, KANJI_LEARNING_ORDER_2, // 星 + 0x6620, KANJI_LEARNING_ORDER_6, // 映 + 0x6625, KANJI_LEARNING_ORDER_2, // 春 + 0x6628, KANJI_LEARNING_ORDER_4, // 昚 + 0x662D, KANJI_LEARNING_ORDER_3, // 昭 + 0x662F, KANJI_LEARNING_ORDER_7, // 是 + 0x663C, KANJI_LEARNING_ORDER_2, // 昌 + 0x6642, KANJI_LEARNING_ORDER_2, // 時 + 0x6669, KANJI_LEARNING_ORDER_6, // 晩 + 0x666E, KANJI_LEARNING_ORDER_7, // 普 + 0x666F, KANJI_LEARNING_ORDER_4, // 景 + 0x6674, KANJI_LEARNING_ORDER_2, // 晎 + 0x6676, KANJI_LEARNING_ORDER_7, // 晶 + 0x6681, KANJI_LEARNING_ORDER_7, // 暁 + 0x6687, KANJI_LEARNING_ORDER_7, // 暇 + 0x6691, KANJI_LEARNING_ORDER_3, // 暑 + 0x6696, KANJI_LEARNING_ORDER_6, // 暖 + 0x6697, KANJI_LEARNING_ORDER_3, // 暗 + 0x66A6, KANJI_LEARNING_ORDER_7, // 暊 + 0x66AB, KANJI_LEARNING_ORDER_7, // 暫 + 0x66AE, KANJI_LEARNING_ORDER_6, // 暮 + 0x66B4, KANJI_LEARNING_ORDER_5, // 暎 + 0x66C7, KANJI_LEARNING_ORDER_7, // 曇 + 0x66DC, KANJI_LEARNING_ORDER_2, // 曜 + 0x66F2, KANJI_LEARNING_ORDER_3, // 曲 + 0x66F4, KANJI_LEARNING_ORDER_7, // 曎 + 0x66F8, KANJI_LEARNING_ORDER_2, // 曞 + 0x66F9, KANJI_LEARNING_ORDER_7, // 曹 + 0x66FF, KANJI_LEARNING_ORDER_7, // 替 + 0x6700, KANJI_LEARNING_ORDER_4, // 最 + 0x6708, KANJI_LEARNING_ORDER_1, // 月 + 0x6709, KANJI_LEARNING_ORDER_3, // 有 + 0x670D, KANJI_LEARNING_ORDER_3, // 服 + 0x6715, KANJI_LEARNING_ORDER_7, // 朕 + 0x6717, KANJI_LEARNING_ORDER_6, // 朗 + 0x671B, KANJI_LEARNING_ORDER_4, // 望 + 0x671D, KANJI_LEARNING_ORDER_2, // 朝 + 0x671F, KANJI_LEARNING_ORDER_3, // 期 + 0x6728, KANJI_LEARNING_ORDER_1, // 朚 + 0x672A, KANJI_LEARNING_ORDER_4, // 未 + 0x672B, KANJI_LEARNING_ORDER_4, // 末 + 0x672C, KANJI_LEARNING_ORDER_1, // 本 + 0x672D, KANJI_LEARNING_ORDER_4, // 札 + 0x6731, KANJI_LEARNING_ORDER_7, // 朱 + 0x6734, KANJI_LEARNING_ORDER_7, // 朎 + 0x673A, KANJI_LEARNING_ORDER_6, // 机 + 0x673D, KANJI_LEARNING_ORDER_7, // 朜 + 0x6749, KANJI_LEARNING_ORDER_7, // 杉 + 0x6750, KANJI_LEARNING_ORDER_4, // 材 + 0x6751, KANJI_LEARNING_ORDER_1, // 村 + 0x675F, KANJI_LEARNING_ORDER_4, // 束 + 0x6761, KANJI_LEARNING_ORDER_5, // 条 + 0x6765, KANJI_LEARNING_ORDER_2, // 来 + 0x676F, KANJI_LEARNING_ORDER_7, // 杯 + 0x6771, KANJI_LEARNING_ORDER_2, // 東 + 0x677E, KANJI_LEARNING_ORDER_4, // 束 + 0x677F, KANJI_LEARNING_ORDER_3, // 板 + 0x6790, KANJI_LEARNING_ORDER_7, // 析 + 0x6797, KANJI_LEARNING_ORDER_1, // 林 + 0x679A, KANJI_LEARNING_ORDER_6, // 枚 + 0x679C, KANJI_LEARNING_ORDER_4, // 果 + 0x679D, KANJI_LEARNING_ORDER_5, // 枝 + 0x67A0, KANJI_LEARNING_ORDER_7, // 枠 + 0x67A2, KANJI_LEARNING_ORDER_7, // 枢 + 0x67AF, KANJI_LEARNING_ORDER_7, // 枯 + 0x67B6, KANJI_LEARNING_ORDER_7, // 架 + 0x67C4, KANJI_LEARNING_ORDER_7, // 柄 + 0x67D0, KANJI_LEARNING_ORDER_7, // 某 + 0x67D3, KANJI_LEARNING_ORDER_6, // 染 + 0x67D4, KANJI_LEARNING_ORDER_7, // 柔 + 0x67F1, KANJI_LEARNING_ORDER_3, // 柱 + 0x67F3, KANJI_LEARNING_ORDER_7, // 柳 + 0x67FB, KANJI_LEARNING_ORDER_5, // 査 + 0x6804, KANJI_LEARNING_ORDER_4, // 栄 + 0x6813, KANJI_LEARNING_ORDER_7, // 栓 + 0x6821, KANJI_LEARNING_ORDER_1, // æ ¡ + 0x682A, KANJI_LEARNING_ORDER_6, // æ ª + 0x6838, KANJI_LEARNING_ORDER_7, // æ ž + 0x6839, KANJI_LEARNING_ORDER_3, // æ ¹ + 0x683C, KANJI_LEARNING_ORDER_5, // æ Œ + 0x683D, KANJI_LEARNING_ORDER_7, // æ œ + 0x6843, KANJI_LEARNING_ORDER_7, // 桃 + 0x6848, KANJI_LEARNING_ORDER_4, // 案 + 0x6851, KANJI_LEARNING_ORDER_7, // 桑 + 0x685C, KANJI_LEARNING_ORDER_5, // 桜 + 0x685F, KANJI_LEARNING_ORDER_7, // 桟 + 0x6885, KANJI_LEARNING_ORDER_4, // 梅 + 0x68B0, KANJI_LEARNING_ORDER_4, // 械 + 0x68C4, KANJI_LEARNING_ORDER_7, // 棄 + 0x68CB, KANJI_LEARNING_ORDER_7, // 棋 + 0x68D2, KANJI_LEARNING_ORDER_6, // 棒 + 0x68DA, KANJI_LEARNING_ORDER_7, // 棚 + 0x68DF, KANJI_LEARNING_ORDER_7, // 棟 + 0x68EE, KANJI_LEARNING_ORDER_1, // 森 + 0x68FA, KANJI_LEARNING_ORDER_7, // 棺 + 0x690D, KANJI_LEARNING_ORDER_3, // 怍 + 0x691C, KANJI_LEARNING_ORDER_5, // 怜 + 0x696D, KANJI_LEARNING_ORDER_3, // 業 + 0x6975, KANJI_LEARNING_ORDER_4, // 極 + 0x697C, KANJI_LEARNING_ORDER_7, // 楌 + 0x697D, KANJI_LEARNING_ORDER_2, // 楜 + 0x6982, KANJI_LEARNING_ORDER_7, // 抂 + 0x69CB, KANJI_LEARNING_ORDER_5, // 構 + 0x69D8, KANJI_LEARNING_ORDER_3, // 様 + 0x69FD, KANJI_LEARNING_ORDER_7, // æ§œ + 0x6A19, KANJI_LEARNING_ORDER_4, // æš™ + 0x6A21, KANJI_LEARNING_ORDER_6, // æš¡ + 0x6A29, KANJI_LEARNING_ORDER_6, // æš© + 0x6A2A, KANJI_LEARNING_ORDER_3, // 暪 + 0x6A39, KANJI_LEARNING_ORDER_6, // æš¹ + 0x6A4B, KANJI_LEARNING_ORDER_3, // 橋 + 0x6A5F, KANJI_LEARNING_ORDER_4, // 機 + 0x6B04, KANJI_LEARNING_ORDER_7, // 欄 + 0x6B20, KANJI_LEARNING_ORDER_4, // 欠 + 0x6B21, KANJI_LEARNING_ORDER_3, // 次 + 0x6B27, KANJI_LEARNING_ORDER_7, // 欧 + 0x6B32, KANJI_LEARNING_ORDER_6, // 欲 + 0x6B3A, KANJI_LEARNING_ORDER_7, // 欺 + 0x6B3E, KANJI_LEARNING_ORDER_7, // 欟 + 0x6B4C, KANJI_LEARNING_ORDER_2, // 歌 + 0x6B53, KANJI_LEARNING_ORDER_7, // 歓 + 0x6B62, KANJI_LEARNING_ORDER_2, // æ­¢ + 0x6B63, KANJI_LEARNING_ORDER_1, // æ­£ + 0x6B66, KANJI_LEARNING_ORDER_5, // æ­Š + 0x6B69, KANJI_LEARNING_ORDER_2, // æ­© + 0x6B6F, KANJI_LEARNING_ORDER_3, // æ­¯ + 0x6B73, KANJI_LEARNING_ORDER_7, // æ­³ + 0x6B74, KANJI_LEARNING_ORDER_4, // æ­Ž + 0x6B7B, KANJI_LEARNING_ORDER_3, // æ­» + 0x6B89, KANJI_LEARNING_ORDER_7, // 殉 + 0x6B8A, KANJI_LEARNING_ORDER_7, // 殊 + 0x6B8B, KANJI_LEARNING_ORDER_4, // 残 + 0x6B96, KANJI_LEARNING_ORDER_7, // 殖 + 0x6BB4, KANJI_LEARNING_ORDER_7, // 殎 + 0x6BB5, KANJI_LEARNING_ORDER_6, // 段 + 0x6BBA, KANJI_LEARNING_ORDER_4, // 殺 + 0x6BBB, KANJI_LEARNING_ORDER_7, // æ®» + 0x6BBF, KANJI_LEARNING_ORDER_7, // 殿 + 0x6BCD, KANJI_LEARNING_ORDER_2, // 母 + 0x6BCE, KANJI_LEARNING_ORDER_2, // 毎 + 0x6BD2, KANJI_LEARNING_ORDER_4, // 毒 + 0x6BD4, KANJI_LEARNING_ORDER_5, // 比 + 0x6BDB, KANJI_LEARNING_ORDER_2, // 毛 + 0x6C0F, KANJI_LEARNING_ORDER_4, // 氏 + 0x6C11, KANJI_LEARNING_ORDER_4, // 民 + 0x6C17, KANJI_LEARNING_ORDER_1, // 気 + 0x6C34, KANJI_LEARNING_ORDER_1, // æ°Ž + 0x6C37, KANJI_LEARNING_ORDER_3, // æ°· + 0x6C38, KANJI_LEARNING_ORDER_5, // æ°ž + 0x6C41, KANJI_LEARNING_ORDER_7, // 汁 + 0x6C42, KANJI_LEARNING_ORDER_4, // 求 + 0x6C57, KANJI_LEARNING_ORDER_7, // 汗 + 0x6C5A, KANJI_LEARNING_ORDER_7, // 汚 + 0x6C5F, KANJI_LEARNING_ORDER_7, // 江 + 0x6C60, KANJI_LEARNING_ORDER_2, // æ±  + 0x6C7A, KANJI_LEARNING_ORDER_3, // 決 + 0x6C7D, KANJI_LEARNING_ORDER_2, // 汜 + 0x6C88, KANJI_LEARNING_ORDER_7, // 沈 + 0x6C96, KANJI_LEARNING_ORDER_7, // 沖 + 0x6CA1, KANJI_LEARNING_ORDER_7, // 没 + 0x6CA2, KANJI_LEARNING_ORDER_7, // æ²¢ + 0x6CB3, KANJI_LEARNING_ORDER_5, // æ²³ + 0x6CB8, KANJI_LEARNING_ORDER_7, // 沞 + 0x6CB9, KANJI_LEARNING_ORDER_3, // æ²¹ + 0x6CBB, KANJI_LEARNING_ORDER_4, // æ²» + 0x6CBC, KANJI_LEARNING_ORDER_7, // 沌 + 0x6CBF, KANJI_LEARNING_ORDER_6, // 沿 + 0x6CC1, KANJI_LEARNING_ORDER_7, // 況 + 0x6CC9, KANJI_LEARNING_ORDER_6, // 泉 + 0x6CCA, KANJI_LEARNING_ORDER_7, // 泊 + 0x6CCC, KANJI_LEARNING_ORDER_7, // 泌 + 0x6CD5, KANJI_LEARNING_ORDER_4, // 法 + 0x6CE1, KANJI_LEARNING_ORDER_7, // 泡 + 0x6CE2, KANJI_LEARNING_ORDER_3, // æ³¢ + 0x6CE3, KANJI_LEARNING_ORDER_4, // æ³£ + 0x6CE5, KANJI_LEARNING_ORDER_7, // æ³¥ + 0x6CE8, KANJI_LEARNING_ORDER_3, // 泚 + 0x6CF0, KANJI_LEARNING_ORDER_7, // æ³° + 0x6CF3, KANJI_LEARNING_ORDER_3, // æ³³ + 0x6D0B, KANJI_LEARNING_ORDER_3, // 掋 + 0x6D17, KANJI_LEARNING_ORDER_6, // 掗 + 0x6D1E, KANJI_LEARNING_ORDER_7, // 掞 + 0x6D25, KANJI_LEARNING_ORDER_7, // 接 + 0x6D2A, KANJI_LEARNING_ORDER_7, // 措 + 0x6D3B, KANJI_LEARNING_ORDER_2, // 掻 + 0x6D3E, KANJI_LEARNING_ORDER_6, // 掟 + 0x6D41, KANJI_LEARNING_ORDER_3, // 流 + 0x6D44, KANJI_LEARNING_ORDER_7, // 浄 + 0x6D45, KANJI_LEARNING_ORDER_4, // 浅 + 0x6D5C, KANJI_LEARNING_ORDER_7, // 浜 + 0x6D66, KANJI_LEARNING_ORDER_7, // 浊 + 0x6D6A, KANJI_LEARNING_ORDER_7, // 浪 + 0x6D6E, KANJI_LEARNING_ORDER_7, // æµ® + 0x6D74, KANJI_LEARNING_ORDER_4, // 济 + 0x6D77, KANJI_LEARNING_ORDER_2, // æµ· + 0x6D78, KANJI_LEARNING_ORDER_7, // 浞 + 0x6D88, KANJI_LEARNING_ORDER_3, // 消 + 0x6D99, KANJI_LEARNING_ORDER_7, // 涙 + 0x6DAF, KANJI_LEARNING_ORDER_7, // 涯 + 0x6DB2, KANJI_LEARNING_ORDER_5, // æ¶² + 0x6DBC, KANJI_LEARNING_ORDER_7, // æ¶Œ + 0x6DD1, KANJI_LEARNING_ORDER_7, // 淑 + 0x6DE1, KANJI_LEARNING_ORDER_7, // æ·¡ + 0x6DF1, KANJI_LEARNING_ORDER_3, // æ·± + 0x6DF7, KANJI_LEARNING_ORDER_5, // æ·· + 0x6DFB, KANJI_LEARNING_ORDER_7, // æ·» + 0x6E05, KANJI_LEARNING_ORDER_4, // æž… + 0x6E07, KANJI_LEARNING_ORDER_7, // 枇 + 0x6E08, KANJI_LEARNING_ORDER_6, // 枈 + 0x6E09, KANJI_LEARNING_ORDER_7, // 枉 + 0x6E0B, KANJI_LEARNING_ORDER_7, // æž‹ + 0x6E13, KANJI_LEARNING_ORDER_7, // æž“ + 0x6E1B, KANJI_LEARNING_ORDER_5, // æž› + 0x6E21, KANJI_LEARNING_ORDER_7, // æž¡ + 0x6E26, KANJI_LEARNING_ORDER_7, // 枊 + 0x6E29, KANJI_LEARNING_ORDER_3, // æž© + 0x6E2C, KANJI_LEARNING_ORDER_5, // 枬 + 0x6E2F, KANJI_LEARNING_ORDER_3, // 枯 + 0x6E56, KANJI_LEARNING_ORDER_3, // 湖 + 0x6E6F, KANJI_LEARNING_ORDER_3, // 湯 + 0x6E7E, KANJI_LEARNING_ORDER_7, // 湟 + 0x6E7F, KANJI_LEARNING_ORDER_7, // 湿 + 0x6E80, KANJI_LEARNING_ORDER_4, // 満 + 0x6E90, KANJI_LEARNING_ORDER_6, // 源 + 0x6E96, KANJI_LEARNING_ORDER_5, // 準 + 0x6E9D, KANJI_LEARNING_ORDER_7, // 溝 + 0x6EB6, KANJI_LEARNING_ORDER_7, // 溶 + 0x6EC5, KANJI_LEARNING_ORDER_7, // 滅 + 0x6ECB, KANJI_LEARNING_ORDER_7, // 滋 + 0x6ED1, KANJI_LEARNING_ORDER_7, // 滑 + 0x6EDD, KANJI_LEARNING_ORDER_7, // 滝 + 0x6EDE, KANJI_LEARNING_ORDER_7, // 滞 + 0x6EF4, KANJI_LEARNING_ORDER_7, // 滎 + 0x6F01, KANJI_LEARNING_ORDER_4, // 持 + 0x6F02, KANJI_LEARNING_ORDER_7, // 挂 + 0x6F06, KANJI_LEARNING_ORDER_7, // 挆 + 0x6F0F, KANJI_LEARNING_ORDER_7, // 挏 + 0x6F14, KANJI_LEARNING_ORDER_5, // 挔 + 0x6F20, KANJI_LEARNING_ORDER_7, // 挠 + 0x6F22, KANJI_LEARNING_ORDER_3, // 挢 + 0x6F2B, KANJI_LEARNING_ORDER_7, // 挫 + 0x6F2C, KANJI_LEARNING_ORDER_7, // 挬 + 0x6F38, KANJI_LEARNING_ORDER_7, // 挞 + 0x6F54, KANJI_LEARNING_ORDER_5, // 朔 + 0x6F5C, KANJI_LEARNING_ORDER_7, // 朜 + 0x6F5F, KANJI_LEARNING_ORDER_7, // 期 + 0x6F64, KANJI_LEARNING_ORDER_7, // 最 + 0x6F6E, KANJI_LEARNING_ORDER_6, // 朮 + 0x6F84, KANJI_LEARNING_ORDER_7, // 柄 + 0x6FC0, KANJI_LEARNING_ORDER_6, // 激 + 0x6FC1, KANJI_LEARNING_ORDER_7, // 濁 + 0x6FC3, KANJI_LEARNING_ORDER_7, // 濃 + 0x6FEB, KANJI_LEARNING_ORDER_7, // æ¿« + 0x6FEF, KANJI_LEARNING_ORDER_7, // 濯 + 0x702C, KANJI_LEARNING_ORDER_7, // 瀬 + 0x706B, KANJI_LEARNING_ORDER_1, // 火 + 0x706F, KANJI_LEARNING_ORDER_4, // 灯 + 0x7070, KANJI_LEARNING_ORDER_6, // 灰 + 0x707D, KANJI_LEARNING_ORDER_5, // 灜 + 0x7089, KANJI_LEARNING_ORDER_7, // 炉 + 0x708A, KANJI_LEARNING_ORDER_7, // 炊 + 0x708E, KANJI_LEARNING_ORDER_7, // 炎 + 0x70AD, KANJI_LEARNING_ORDER_3, // 炭 + 0x70B9, KANJI_LEARNING_ORDER_2, // 点 + 0x70BA, KANJI_LEARNING_ORDER_7, // 為 + 0x70C8, KANJI_LEARNING_ORDER_7, // 烈 + 0x7121, KANJI_LEARNING_ORDER_4, // 無 + 0x7126, KANJI_LEARNING_ORDER_7, // 焩 + 0x7136, KANJI_LEARNING_ORDER_4, // 然 + 0x713C, KANJI_LEARNING_ORDER_4, // 焌 + 0x7159, KANJI_LEARNING_ORDER_7, // 煙 + 0x7167, KANJI_LEARNING_ORDER_4, // 照 + 0x7169, KANJI_LEARNING_ORDER_7, // 煩 + 0x716E, KANJI_LEARNING_ORDER_7, // 煮 + 0x719F, KANJI_LEARNING_ORDER_6, // 熟 + 0x71B1, KANJI_LEARNING_ORDER_4, // 熱 + 0x71C3, KANJI_LEARNING_ORDER_5, // 燃 + 0x71C8, KANJI_LEARNING_ORDER_7, // 燈 + 0x71E5, KANJI_LEARNING_ORDER_7, // 燥 + 0x7206, KANJI_LEARNING_ORDER_7, // 爆 + 0x7235, KANJI_LEARNING_ORDER_7, // 爵 + 0x7236, KANJI_LEARNING_ORDER_2, // 父 + 0x7247, KANJI_LEARNING_ORDER_6, // 片 + 0x7248, KANJI_LEARNING_ORDER_5, // 版 + 0x725B, KANJI_LEARNING_ORDER_2, // 牛 + 0x7267, KANJI_LEARNING_ORDER_4, // 牧 + 0x7269, KANJI_LEARNING_ORDER_3, // 物 + 0x7272, KANJI_LEARNING_ORDER_7, // 牲 + 0x7279, KANJI_LEARNING_ORDER_4, // 特 + 0x72A0, KANJI_LEARNING_ORDER_7, // 犠 + 0x72AC, KANJI_LEARNING_ORDER_1, // 犬 + 0x72AF, KANJI_LEARNING_ORDER_5, // 犯 + 0x72B6, KANJI_LEARNING_ORDER_5, // 状 + 0x72C2, KANJI_LEARNING_ORDER_7, // 狂 + 0x72E9, KANJI_LEARNING_ORDER_7, // 狩 + 0x72EC, KANJI_LEARNING_ORDER_5, // 独 + 0x72ED, KANJI_LEARNING_ORDER_7, // 狭 + 0x731B, KANJI_LEARNING_ORDER_7, // 猛 + 0x731F, KANJI_LEARNING_ORDER_7, // 猟 + 0x732B, KANJI_LEARNING_ORDER_7, // 猫 + 0x732E, KANJI_LEARNING_ORDER_7, // 献 + 0x7336, KANJI_LEARNING_ORDER_7, // 猶 + 0x733F, KANJI_LEARNING_ORDER_7, // 猿 + 0x7344, KANJI_LEARNING_ORDER_7, // 獄 + 0x7363, KANJI_LEARNING_ORDER_7, // 獣 + 0x7372, KANJI_LEARNING_ORDER_7, // 獲 + 0x7384, KANJI_LEARNING_ORDER_7, // 玄 + 0x7387, KANJI_LEARNING_ORDER_5, // 率 + 0x7389, KANJI_LEARNING_ORDER_1, // 玉 + 0x738B, KANJI_LEARNING_ORDER_1, // 王 + 0x73CD, KANJI_LEARNING_ORDER_7, // 珍 + 0x73E0, KANJI_LEARNING_ORDER_7, // 珠 + 0x73ED, KANJI_LEARNING_ORDER_6, // 班 + 0x73FE, KANJI_LEARNING_ORDER_5, // 珟 + 0x7403, KANJI_LEARNING_ORDER_3, // 球 + 0x7406, KANJI_LEARNING_ORDER_2, // 理 + 0x7434, KANJI_LEARNING_ORDER_7, // 琎 + 0x74B0, KANJI_LEARNING_ORDER_7, // 環 + 0x74BD, KANJI_LEARNING_ORDER_7, // ç’œ + 0x74F6, KANJI_LEARNING_ORDER_7, // 瓶 + 0x7518, KANJI_LEARNING_ORDER_7, // 甘 + 0x751A, KANJI_LEARNING_ORDER_7, // 甚 + 0x751F, KANJI_LEARNING_ORDER_1, // 生 + 0x7523, KANJI_LEARNING_ORDER_4, // 産 + 0x7528, KANJI_LEARNING_ORDER_2, // 甹 + 0x7530, KANJI_LEARNING_ORDER_1, // 田 + 0x7531, KANJI_LEARNING_ORDER_3, // 由 + 0x7532, KANJI_LEARNING_ORDER_7, // 甲 + 0x7533, KANJI_LEARNING_ORDER_3, // 申 + 0x7537, KANJI_LEARNING_ORDER_1, // 男 + 0x753A, KANJI_LEARNING_ORDER_1, // 町 + 0x753B, KANJI_LEARNING_ORDER_2, // 画 + 0x754C, KANJI_LEARNING_ORDER_3, // 界 + 0x7551, KANJI_LEARNING_ORDER_3, // 畑 + 0x7554, KANJI_LEARNING_ORDER_7, // 畔 + 0x7559, KANJI_LEARNING_ORDER_5, // 留 + 0x755C, KANJI_LEARNING_ORDER_7, // 畜 + 0x755D, KANJI_LEARNING_ORDER_7, // 畝 + 0x7565, KANJI_LEARNING_ORDER_5, // 略 + 0x756A, KANJI_LEARNING_ORDER_2, // 番 + 0x7570, KANJI_LEARNING_ORDER_6, // 異 + 0x7573, KANJI_LEARNING_ORDER_7, // 畳 + 0x758E, KANJI_LEARNING_ORDER_7, // 疎 + 0x7591, KANJI_LEARNING_ORDER_6, // 疑 + 0x75AB, KANJI_LEARNING_ORDER_7, // 疫 + 0x75B2, KANJI_LEARNING_ORDER_7, // 疲 + 0x75BE, KANJI_LEARNING_ORDER_7, // ç–Ÿ + 0x75C5, KANJI_LEARNING_ORDER_3, // 病 + 0x75C7, KANJI_LEARNING_ORDER_7, // 症 + 0x75D8, KANJI_LEARNING_ORDER_7, // 痘 + 0x75DB, KANJI_LEARNING_ORDER_6, // 痛 + 0x75E2, KANJI_LEARNING_ORDER_7, // 痢 + 0x75F4, KANJI_LEARNING_ORDER_7, // 痮 + 0x7642, KANJI_LEARNING_ORDER_7, // 療 + 0x7652, KANJI_LEARNING_ORDER_7, // 癒 + 0x7656, KANJI_LEARNING_ORDER_7, // 癖 + 0x767A, KANJI_LEARNING_ORDER_3, // 発 + 0x767B, KANJI_LEARNING_ORDER_3, // 登 + 0x767D, KANJI_LEARNING_ORDER_1, // 癜 + 0x767E, KANJI_LEARNING_ORDER_1, // 癟 + 0x7684, KANJI_LEARNING_ORDER_4, // 的 + 0x7686, KANJI_LEARNING_ORDER_7, // 皆 + 0x7687, KANJI_LEARNING_ORDER_6, // 皇 + 0x76AE, KANJI_LEARNING_ORDER_3, // 皮 + 0x76BF, KANJI_LEARNING_ORDER_3, // 皿 + 0x76C6, KANJI_LEARNING_ORDER_7, // 盆 + 0x76CA, KANJI_LEARNING_ORDER_5, // 益 + 0x76D7, KANJI_LEARNING_ORDER_7, // 盗 + 0x76DB, KANJI_LEARNING_ORDER_6, // 盛 + 0x76DF, KANJI_LEARNING_ORDER_6, // 盟 + 0x76E3, KANJI_LEARNING_ORDER_7, // 監 + 0x76E4, KANJI_LEARNING_ORDER_7, // 盀 + 0x76EE, KANJI_LEARNING_ORDER_1, // 目 + 0x76F2, KANJI_LEARNING_ORDER_7, // 盲 + 0x76F4, KANJI_LEARNING_ORDER_2, // 目 + 0x76F8, KANJI_LEARNING_ORDER_3, // 盾 + 0x76FE, KANJI_LEARNING_ORDER_7, // 盟 + 0x7701, KANJI_LEARNING_ORDER_4, // 省 + 0x770B, KANJI_LEARNING_ORDER_6, // 看 + 0x770C, KANJI_LEARNING_ORDER_3, // 県 + 0x771F, KANJI_LEARNING_ORDER_3, // 真 + 0x7720, KANJI_LEARNING_ORDER_7, // 眠 + 0x773A, KANJI_LEARNING_ORDER_7, // 眺 + 0x773C, KANJI_LEARNING_ORDER_5, // 県 + 0x7740, KANJI_LEARNING_ORDER_3, // 着 + 0x7761, KANJI_LEARNING_ORDER_7, // 睡 + 0x7763, KANJI_LEARNING_ORDER_7, // 督 + 0x77AC, KANJI_LEARNING_ORDER_7, // 瞬 + 0x77DB, KANJI_LEARNING_ORDER_7, // 矛 + 0x77E2, KANJI_LEARNING_ORDER_2, // 矢 + 0x77E5, KANJI_LEARNING_ORDER_2, // 知 + 0x77ED, KANJI_LEARNING_ORDER_3, // 短 + 0x77EF, KANJI_LEARNING_ORDER_7, // 矯 + 0x77F3, KANJI_LEARNING_ORDER_1, // 石 + 0x7802, KANJI_LEARNING_ORDER_6, // 砂 + 0x7814, KANJI_LEARNING_ORDER_3, // 研 + 0x7815, KANJI_LEARNING_ORDER_7, // 砕 + 0x7832, KANJI_LEARNING_ORDER_7, // ç ² + 0x7834, KANJI_LEARNING_ORDER_5, // ç Ž + 0x785D, KANJI_LEARNING_ORDER_7, // 硝 + 0x786B, KANJI_LEARNING_ORDER_7, // ç¡« + 0x786C, KANJI_LEARNING_ORDER_7, // 硬 + 0x7881, KANJI_LEARNING_ORDER_7, // 碁 + 0x7891, KANJI_LEARNING_ORDER_7, // 碑 + 0x78BA, KANJI_LEARNING_ORDER_5, // 確 + 0x78C1, KANJI_LEARNING_ORDER_6, // 磁 + 0x78E8, KANJI_LEARNING_ORDER_7, // 磚 + 0x7901, KANJI_LEARNING_ORDER_7, // 瀁 + 0x790E, KANJI_LEARNING_ORDER_7, // 瀎 + 0x793A, KANJI_LEARNING_ORDER_5, // 瀺 + 0x793C, KANJI_LEARNING_ORDER_3, // 瀌 + 0x793E, KANJI_LEARNING_ORDER_2, // 瀟 + 0x7948, KANJI_LEARNING_ORDER_7, // 祈 + 0x7949, KANJI_LEARNING_ORDER_7, // 祉 + 0x7956, KANJI_LEARNING_ORDER_5, // 祖 + 0x795D, KANJI_LEARNING_ORDER_4, // 祝 + 0x795E, KANJI_LEARNING_ORDER_3, // 神 + 0x7965, KANJI_LEARNING_ORDER_7, // 祥 + 0x7968, KANJI_LEARNING_ORDER_4, // 祚 + 0x796D, KANJI_LEARNING_ORDER_3, // 祭 + 0x7981, KANJI_LEARNING_ORDER_5, // 犁 + 0x7985, KANJI_LEARNING_ORDER_7, // 穅 + 0x798D, KANJI_LEARNING_ORDER_7, // 犍 + 0x798F, KANJI_LEARNING_ORDER_3, // 犏 + 0x79C0, KANJI_LEARNING_ORDER_7, // 秀 + 0x79C1, KANJI_LEARNING_ORDER_6, // 私 + 0x79CB, KANJI_LEARNING_ORDER_2, // 秋 + 0x79D1, KANJI_LEARNING_ORDER_2, // 科 + 0x79D2, KANJI_LEARNING_ORDER_3, // 秒 + 0x79D8, KANJI_LEARNING_ORDER_6, // 秘 + 0x79DF, KANJI_LEARNING_ORDER_7, // 租 + 0x79E9, KANJI_LEARNING_ORDER_7, // ç§© + 0x79F0, KANJI_LEARNING_ORDER_7, // ç§° + 0x79FB, KANJI_LEARNING_ORDER_5, // ç§» + 0x7A0B, KANJI_LEARNING_ORDER_5, // 繋 + 0x7A0E, KANJI_LEARNING_ORDER_5, // 皎 + 0x7A1A, KANJI_LEARNING_ORDER_7, // 繚 + 0x7A2E, KANJI_LEARNING_ORDER_4, // çš® + 0x7A32, KANJI_LEARNING_ORDER_7, // çš² + 0x7A3C, KANJI_LEARNING_ORDER_7, // 皌 + 0x7A3F, KANJI_LEARNING_ORDER_7, // çš¿ + 0x7A40, KANJI_LEARNING_ORDER_6, // 穀 + 0x7A42, KANJI_LEARNING_ORDER_7, // 穂 + 0x7A4D, KANJI_LEARNING_ORDER_4, // 積 + 0x7A4F, KANJI_LEARNING_ORDER_7, // 穏 + 0x7A6B, KANJI_LEARNING_ORDER_7, // ç©« + 0x7A74, KANJI_LEARNING_ORDER_6, // 穎 + 0x7A76, KANJI_LEARNING_ORDER_3, // ç©¶ + 0x7A7A, KANJI_LEARNING_ORDER_1, // 空 + 0x7A81, KANJI_LEARNING_ORDER_7, // 突 + 0x7A83, KANJI_LEARNING_ORDER_7, // 窃 + 0x7A92, KANJI_LEARNING_ORDER_7, // 窒 + 0x7A93, KANJI_LEARNING_ORDER_6, // 窓 + 0x7AAE, KANJI_LEARNING_ORDER_7, // 窮 + 0x7AAF, KANJI_LEARNING_ORDER_7, // 窯 + 0x7ACB, KANJI_LEARNING_ORDER_1, // 立 + 0x7ADC, KANJI_LEARNING_ORDER_7, // 竜 + 0x7AE0, KANJI_LEARNING_ORDER_3, // ç«  + 0x7AE5, KANJI_LEARNING_ORDER_3, // ç«¥ + 0x7AEF, KANJI_LEARNING_ORDER_7, // 端 + 0x7AF6, KANJI_LEARNING_ORDER_4, // ç«¶ + 0x7AF9, KANJI_LEARNING_ORDER_1, // 竹 + 0x7B11, KANJI_LEARNING_ORDER_4, // 笑 + 0x7B1B, KANJI_LEARNING_ORDER_3, // 笛 + 0x7B26, KANJI_LEARNING_ORDER_7, // 笊 + 0x7B2C, KANJI_LEARNING_ORDER_3, // 第 + 0x7B46, KANJI_LEARNING_ORDER_3, // 筆 + 0x7B49, KANJI_LEARNING_ORDER_3, // 等 + 0x7B4B, KANJI_LEARNING_ORDER_6, // 筋 + 0x7B52, KANJI_LEARNING_ORDER_7, // 筒 + 0x7B54, KANJI_LEARNING_ORDER_2, // 答 + 0x7B56, KANJI_LEARNING_ORDER_6, // 策 + 0x7B87, KANJI_LEARNING_ORDER_7, // 箇 + 0x7B97, KANJI_LEARNING_ORDER_2, // 算 + 0x7BA1, KANJI_LEARNING_ORDER_4, // 管 + 0x7BB1, KANJI_LEARNING_ORDER_3, // ç®± + 0x7BC0, KANJI_LEARNING_ORDER_4, // 節 + 0x7BC4, KANJI_LEARNING_ORDER_7, // 範 + 0x7BC9, KANJI_LEARNING_ORDER_5, // 築 + 0x7BE4, KANJI_LEARNING_ORDER_7, // 節 + 0x7C21, KANJI_LEARNING_ORDER_6, // ç°¡ + 0x7C3F, KANJI_LEARNING_ORDER_7, // ç°¿ + 0x7C4D, KANJI_LEARNING_ORDER_7, // 籍 + 0x7C73, KANJI_LEARNING_ORDER_2, // ç±³ + 0x7C89, KANJI_LEARNING_ORDER_4, // 粉 + 0x7C8B, KANJI_LEARNING_ORDER_7, // 粋 + 0x7C92, KANJI_LEARNING_ORDER_7, // 粒 + 0x7C97, KANJI_LEARNING_ORDER_7, // 粗 + 0x7C98, KANJI_LEARNING_ORDER_7, // 粘 + 0x7C9B, KANJI_LEARNING_ORDER_7, // 粛 + 0x7CA7, KANJI_LEARNING_ORDER_7, // ç²§ + 0x7CBE, KANJI_LEARNING_ORDER_5, // 粟 + 0x7CD6, KANJI_LEARNING_ORDER_6, // 糖 + 0x7CE7, KANJI_LEARNING_ORDER_7, // ç³§ + 0x7CF8, KANJI_LEARNING_ORDER_1, // 糞 + 0x7CFB, KANJI_LEARNING_ORDER_6, // ç³» + 0x7CFE, KANJI_LEARNING_ORDER_7, // 糟 + 0x7D00, KANJI_LEARNING_ORDER_4, // 简 + 0x7D04, KANJI_LEARNING_ORDER_4, // 箄 + 0x7D05, KANJI_LEARNING_ORDER_6, // 箅 + 0x7D0B, KANJI_LEARNING_ORDER_7, // 箋 + 0x7D0D, KANJI_LEARNING_ORDER_6, // 玍 + 0x7D14, KANJI_LEARNING_ORDER_6, // 箔 + 0x7D19, KANJI_LEARNING_ORDER_2, // 箙 + 0x7D1A, KANJI_LEARNING_ORDER_3, // 箚 + 0x7D1B, KANJI_LEARNING_ORDER_7, // 箛 + 0x7D20, KANJI_LEARNING_ORDER_5, // 玠 + 0x7D21, KANJI_LEARNING_ORDER_7, // 玡 + 0x7D22, KANJI_LEARNING_ORDER_7, // 玢 + 0x7D2B, KANJI_LEARNING_ORDER_7, // 玫 + 0x7D2F, KANJI_LEARNING_ORDER_7, // 环 + 0x7D30, KANJI_LEARNING_ORDER_2, // 现 + 0x7D33, KANJI_LEARNING_ORDER_7, // 玳 + 0x7D39, KANJI_LEARNING_ORDER_7, // 玹 + 0x7D3A, KANJI_LEARNING_ORDER_7, // 玺 + 0x7D42, KANJI_LEARNING_ORDER_3, // 終 + 0x7D44, KANJI_LEARNING_ORDER_2, // 組 + 0x7D4C, KANJI_LEARNING_ORDER_5, // 経 + 0x7D50, KANJI_LEARNING_ORDER_4, // 結 + 0x7D5E, KANJI_LEARNING_ORDER_7, // 絞 + 0x7D61, KANJI_LEARNING_ORDER_7, // 絡 + 0x7D66, KANJI_LEARNING_ORDER_4, // 絊 + 0x7D71, KANJI_LEARNING_ORDER_5, // çµ± + 0x7D75, KANJI_LEARNING_ORDER_2, // çµµ + 0x7D76, KANJI_LEARNING_ORDER_5, // çµ¶ + 0x7D79, KANJI_LEARNING_ORDER_6, // çµ¹ + 0x7D99, KANJI_LEARNING_ORDER_7, // 継 + 0x7D9A, KANJI_LEARNING_ORDER_4, // 続 + 0x7DAD, KANJI_LEARNING_ORDER_7, // ç¶­ + 0x7DB1, KANJI_LEARNING_ORDER_7, // ç¶± + 0x7DB2, KANJI_LEARNING_ORDER_7, // ç¶² + 0x7DBF, KANJI_LEARNING_ORDER_5, // ç¶¿ + 0x7DCA, KANJI_LEARNING_ORDER_7, // 緊 + 0x7DCF, KANJI_LEARNING_ORDER_5, // 総 + 0x7DD1, KANJI_LEARNING_ORDER_3, // 緑 + 0x7DD2, KANJI_LEARNING_ORDER_7, // 緒 + 0x7DDA, KANJI_LEARNING_ORDER_2, // 線 + 0x7DE0, KANJI_LEARNING_ORDER_7, // ç·  + 0x7DE8, KANJI_LEARNING_ORDER_5, // ç·š + 0x7DE9, KANJI_LEARNING_ORDER_7, // ç·© + 0x7DEF, KANJI_LEARNING_ORDER_7, // ç·¯ + 0x7DF4, KANJI_LEARNING_ORDER_3, // ç·Ž + 0x7E01, KANJI_LEARNING_ORDER_7, // 瞁 + 0x7E04, KANJI_LEARNING_ORDER_7, // 羄 + 0x7E1B, KANJI_LEARNING_ORDER_7, // 羛 + 0x7E26, KANJI_LEARNING_ORDER_6, // 瞊 + 0x7E2B, KANJI_LEARNING_ORDER_7, // çž« + 0x7E2E, KANJI_LEARNING_ORDER_6, // çž® + 0x7E3E, KANJI_LEARNING_ORDER_5, // 瞟 + 0x7E41, KANJI_LEARNING_ORDER_7, // 繁 + 0x7E4A, KANJI_LEARNING_ORDER_7, // 繊 + 0x7E54, KANJI_LEARNING_ORDER_5, // 織 + 0x7E55, KANJI_LEARNING_ORDER_7, // 繕 + 0x7E6D, KANJI_LEARNING_ORDER_7, // ç¹­ + 0x7E70, KANJI_LEARNING_ORDER_7, // ç¹° + 0x7F36, KANJI_LEARNING_ORDER_7, // 猶 + 0x7F6A, KANJI_LEARNING_ORDER_5, // 眪 + 0x7F6E, KANJI_LEARNING_ORDER_4, // 眮 + 0x7F70, KANJI_LEARNING_ORDER_7, // 眰 + 0x7F72, KANJI_LEARNING_ORDER_6, // 眲 + 0x7F77, KANJI_LEARNING_ORDER_7, // 眷 + 0x7F85, KANJI_LEARNING_ORDER_7, // 矅 + 0x7F8A, KANJI_LEARNING_ORDER_3, // 矊 + 0x7F8E, KANJI_LEARNING_ORDER_3, // 矎 + 0x7FA4, KANJI_LEARNING_ORDER_5, // 矀 + 0x7FA9, KANJI_LEARNING_ORDER_5, // 矩 + 0x7FBD, KANJI_LEARNING_ORDER_2, // 矜 + 0x7FC1, KANJI_LEARNING_ORDER_7, // 翁 + 0x7FCC, KANJI_LEARNING_ORDER_6, // 翌 + 0x7FD2, KANJI_LEARNING_ORDER_3, // 習 + 0x7FFB, KANJI_LEARNING_ORDER_7, // ç¿» + 0x7FFC, KANJI_LEARNING_ORDER_7, // 翌 + 0x8001, KANJI_LEARNING_ORDER_4, // 老 + 0x8003, KANJI_LEARNING_ORDER_2, // 考 + 0x8005, KANJI_LEARNING_ORDER_3, // 者 + 0x8010, KANJI_LEARNING_ORDER_7, // 耐 + 0x8015, KANJI_LEARNING_ORDER_5, // 耕 + 0x8017, KANJI_LEARNING_ORDER_7, // 耗 + 0x8033, KANJI_LEARNING_ORDER_1, // 耳 + 0x8056, KANJI_LEARNING_ORDER_6, // 聖 + 0x805E, KANJI_LEARNING_ORDER_2, // 聞 + 0x8074, KANJI_LEARNING_ORDER_7, // 聎 + 0x8077, KANJI_LEARNING_ORDER_5, // 職 + 0x8089, KANJI_LEARNING_ORDER_2, // 肉 + 0x808C, KANJI_LEARNING_ORDER_7, // 肌 + 0x8096, KANJI_LEARNING_ORDER_7, // 肖 + 0x809D, KANJI_LEARNING_ORDER_7, // 肝 + 0x80A2, KANJI_LEARNING_ORDER_7, // 肢 + 0x80A5, KANJI_LEARNING_ORDER_5, // 肥 + 0x80A9, KANJI_LEARNING_ORDER_7, // 肩 + 0x80AA, KANJI_LEARNING_ORDER_7, // 肪 + 0x80AF, KANJI_LEARNING_ORDER_7, // 肯 + 0x80B2, KANJI_LEARNING_ORDER_3, // 育 + 0x80BA, KANJI_LEARNING_ORDER_6, // 肺 + 0x80C3, KANJI_LEARNING_ORDER_4, // 胃 + 0x80C6, KANJI_LEARNING_ORDER_7, // 胆 + 0x80CC, KANJI_LEARNING_ORDER_6, // 背 + 0x80CE, KANJI_LEARNING_ORDER_7, // 胎 + 0x80DE, KANJI_LEARNING_ORDER_7, // 胞 + 0x80F4, KANJI_LEARNING_ORDER_7, // 胎 + 0x80F8, KANJI_LEARNING_ORDER_6, // 胞 + 0x80FD, KANJI_LEARNING_ORDER_5, // 胜 + 0x8102, KANJI_LEARNING_ORDER_7, // 脂 + 0x8105, KANJI_LEARNING_ORDER_7, // 脅 + 0x8108, KANJI_LEARNING_ORDER_4, // 脈 + 0x811A, KANJI_LEARNING_ORDER_7, // 脚 + 0x8131, KANJI_LEARNING_ORDER_7, // 脱 + 0x8133, KANJI_LEARNING_ORDER_6, // 脳 + 0x8139, KANJI_LEARNING_ORDER_7, // 脹 + 0x8150, KANJI_LEARNING_ORDER_7, // 腐 + 0x8155, KANJI_LEARNING_ORDER_7, // 腕 + 0x8170, KANJI_LEARNING_ORDER_7, // 腰 + 0x8178, KANJI_LEARNING_ORDER_4, // è…ž + 0x8179, KANJI_LEARNING_ORDER_6, // 腹 + 0x819A, KANJI_LEARNING_ORDER_7, // 膚 + 0x819C, KANJI_LEARNING_ORDER_7, // 膜 + 0x81A8, KANJI_LEARNING_ORDER_7, // 膚 + 0x81D3, KANJI_LEARNING_ORDER_6, // 臓 + 0x81E3, KANJI_LEARNING_ORDER_4, // 臣 + 0x81E8, KANJI_LEARNING_ORDER_6, // 臚 + 0x81EA, KANJI_LEARNING_ORDER_2, // 自 + 0x81ED, KANJI_LEARNING_ORDER_7, // 臭 + 0x81F3, KANJI_LEARNING_ORDER_6, // 至 + 0x81F4, KANJI_LEARNING_ORDER_7, // 臎 + 0x8208, KANJI_LEARNING_ORDER_5, // 興 + 0x820C, KANJI_LEARNING_ORDER_5, // 舌 + 0x820E, KANJI_LEARNING_ORDER_5, // 舎 + 0x8217, KANJI_LEARNING_ORDER_7, // 舗 + 0x821E, KANJI_LEARNING_ORDER_7, // 舞 + 0x821F, KANJI_LEARNING_ORDER_7, // 舟 + 0x822A, KANJI_LEARNING_ORDER_4, // 航 + 0x822C, KANJI_LEARNING_ORDER_7, // 般 + 0x8236, KANJI_LEARNING_ORDER_7, // 舶 + 0x8239, KANJI_LEARNING_ORDER_2, // 船 + 0x8247, KANJI_LEARNING_ORDER_7, // 艇 + 0x8266, KANJI_LEARNING_ORDER_7, // 艊 + 0x826F, KANJI_LEARNING_ORDER_4, // 良 + 0x8272, KANJI_LEARNING_ORDER_2, // 色 + 0x828B, KANJI_LEARNING_ORDER_7, // 芋 + 0x829D, KANJI_LEARNING_ORDER_7, // 芝 + 0x82B1, KANJI_LEARNING_ORDER_1, // 花 + 0x82B3, KANJI_LEARNING_ORDER_7, // 芳 + 0x82B8, KANJI_LEARNING_ORDER_4, // 芞 + 0x82BD, KANJI_LEARNING_ORDER_4, // 芜 + 0x82D7, KANJI_LEARNING_ORDER_7, // 苗 + 0x82E5, KANJI_LEARNING_ORDER_6, // 若 + 0x82E6, KANJI_LEARNING_ORDER_3, // 苊 + 0x82F1, KANJI_LEARNING_ORDER_4, // 英 + 0x8302, KANJI_LEARNING_ORDER_7, // 茂 + 0x830E, KANJI_LEARNING_ORDER_7, // 茎 + 0x8336, KANJI_LEARNING_ORDER_2, // 茶 + 0x8349, KANJI_LEARNING_ORDER_1, // 草 + 0x8352, KANJI_LEARNING_ORDER_7, // 荒 + 0x8358, KANJI_LEARNING_ORDER_7, // 荘 + 0x8377, KANJI_LEARNING_ORDER_3, // 荷 + 0x83CA, KANJI_LEARNING_ORDER_7, // 菊 + 0x83CC, KANJI_LEARNING_ORDER_7, // 菌 + 0x83D3, KANJI_LEARNING_ORDER_7, // 菓 + 0x83DC, KANJI_LEARNING_ORDER_4, // 菜 + 0x83EF, KANJI_LEARNING_ORDER_7, // 華 + 0x843D, KANJI_LEARNING_ORDER_3, // 萜 + 0x8449, KANJI_LEARNING_ORDER_3, // 葉 + 0x8457, KANJI_LEARNING_ORDER_6, // 著 + 0x846C, KANJI_LEARNING_ORDER_7, // 葬 + 0x84B8, KANJI_LEARNING_ORDER_6, // è’ž + 0x84C4, KANJI_LEARNING_ORDER_7, // 蓄 + 0x8535, KANJI_LEARNING_ORDER_6, // 蔵 + 0x8584, KANJI_LEARNING_ORDER_7, // 薄 + 0x85A6, KANJI_LEARNING_ORDER_7, // è–Š + 0x85AA, KANJI_LEARNING_ORDER_7, // 薪 + 0x85AB, KANJI_LEARNING_ORDER_7, // 薫 + 0x85AC, KANJI_LEARNING_ORDER_3, // 薬 + 0x85E9, KANJI_LEARNING_ORDER_7, // 藩 + 0x85FB, KANJI_LEARNING_ORDER_7, // 藻 + 0x8650, KANJI_LEARNING_ORDER_7, // 虐 + 0x865A, KANJI_LEARNING_ORDER_7, // 虚 + 0x865C, KANJI_LEARNING_ORDER_7, // 虜 + 0x865E, KANJI_LEARNING_ORDER_7, // 虞 + 0x866B, KANJI_LEARNING_ORDER_1, // 虫 + 0x868A, KANJI_LEARNING_ORDER_7, // 蚊 + 0x8695, KANJI_LEARNING_ORDER_6, // 蚕 + 0x86C7, KANJI_LEARNING_ORDER_7, // 蛇 + 0x86CD, KANJI_LEARNING_ORDER_7, // 蛍 + 0x86EE, KANJI_LEARNING_ORDER_7, // 蛮 + 0x878D, KANJI_LEARNING_ORDER_7, // 融 + 0x8840, KANJI_LEARNING_ORDER_3, // 血 + 0x8846, KANJI_LEARNING_ORDER_6, // 衆 + 0x884C, KANJI_LEARNING_ORDER_2, // 行 + 0x8853, KANJI_LEARNING_ORDER_5, // 術 + 0x8857, KANJI_LEARNING_ORDER_4, // 街 + 0x885B, KANJI_LEARNING_ORDER_5, // 衛 + 0x885D, KANJI_LEARNING_ORDER_7, // 衝 + 0x8861, KANJI_LEARNING_ORDER_7, // è¡¡ + 0x8863, KANJI_LEARNING_ORDER_4, // è¡£ + 0x8868, KANJI_LEARNING_ORDER_3, // 衚 + 0x8870, KANJI_LEARNING_ORDER_7, // è¡° + 0x8877, KANJI_LEARNING_ORDER_7, // è¡· + 0x888B, KANJI_LEARNING_ORDER_7, // 袋 + 0x88AB, KANJI_LEARNING_ORDER_7, // 被 + 0x88C1, KANJI_LEARNING_ORDER_6, // 裁 + 0x88C2, KANJI_LEARNING_ORDER_7, // 裂 + 0x88C5, KANJI_LEARNING_ORDER_6, // 装 + 0x88CF, KANJI_LEARNING_ORDER_6, // 裏 + 0x88D5, KANJI_LEARNING_ORDER_7, // 裕 + 0x88DC, KANJI_LEARNING_ORDER_6, // 補 + 0x88F8, KANJI_LEARNING_ORDER_7, // 裞 + 0x88FD, KANJI_LEARNING_ORDER_5, // 補 + 0x8907, KANJI_LEARNING_ORDER_5, // 耇 + 0x8910, KANJI_LEARNING_ORDER_7, // 耐 + 0x8912, KANJI_LEARNING_ORDER_7, // 耒 + 0x895F, KANJI_LEARNING_ORDER_7, // 襟 + 0x8972, KANJI_LEARNING_ORDER_7, // 襲 + 0x897F, KANJI_LEARNING_ORDER_2, // 西 + 0x8981, KANJI_LEARNING_ORDER_4, // 芁 + 0x8986, KANJI_LEARNING_ORDER_7, // 芆 + 0x8987, KANJI_LEARNING_ORDER_7, // 芇 + 0x898B, KANJI_LEARNING_ORDER_1, // 芋 + 0x898F, KANJI_LEARNING_ORDER_5, // 芏 + 0x8996, KANJI_LEARNING_ORDER_6, // 芖 + 0x899A, KANJI_LEARNING_ORDER_4, // 芚 + 0x89A7, KANJI_LEARNING_ORDER_6, // 芧 + 0x89AA, KANJI_LEARNING_ORDER_2, // 芪 + 0x89B3, KANJI_LEARNING_ORDER_4, // 芳 + 0x89D2, KANJI_LEARNING_ORDER_2, // 角 + 0x89E3, KANJI_LEARNING_ORDER_5, // è§£ + 0x89E6, KANJI_LEARNING_ORDER_7, // è§Š + 0x8A00, KANJI_LEARNING_ORDER_2, // 蚀 + 0x8A02, KANJI_LEARNING_ORDER_7, // èš‚ + 0x8A08, KANJI_LEARNING_ORDER_2, // 蚈 + 0x8A0E, KANJI_LEARNING_ORDER_6, // 蚎 + 0x8A13, KANJI_LEARNING_ORDER_4, // èš“ + 0x8A17, KANJI_LEARNING_ORDER_7, // èš— + 0x8A18, KANJI_LEARNING_ORDER_2, // 蚘 + 0x8A1F, KANJI_LEARNING_ORDER_7, // 蚟 + 0x8A2A, KANJI_LEARNING_ORDER_6, // 蚪 + 0x8A2D, KANJI_LEARNING_ORDER_5, // èš­ + 0x8A31, KANJI_LEARNING_ORDER_5, // èš± + 0x8A33, KANJI_LEARNING_ORDER_6, // èš³ + 0x8A34, KANJI_LEARNING_ORDER_7, // 蚎 + 0x8A3A, KANJI_LEARNING_ORDER_7, // 蚺 + 0x8A3C, KANJI_LEARNING_ORDER_5, // 蚌 + 0x8A50, KANJI_LEARNING_ORDER_7, // 詐 + 0x8A54, KANJI_LEARNING_ORDER_7, // 詔 + 0x8A55, KANJI_LEARNING_ORDER_5, // 評 + 0x8A5E, KANJI_LEARNING_ORDER_6, // 詞 + 0x8A60, KANJI_LEARNING_ORDER_7, // è©  + 0x8A66, KANJI_LEARNING_ORDER_4, // 詊 + 0x8A69, KANJI_LEARNING_ORDER_3, // è©© + 0x8A70, KANJI_LEARNING_ORDER_7, // è©° + 0x8A71, KANJI_LEARNING_ORDER_2, // 話 + 0x8A72, KANJI_LEARNING_ORDER_7, // 該 + 0x8A73, KANJI_LEARNING_ORDER_7, // 詳 + 0x8A87, KANJI_LEARNING_ORDER_7, // 誇 + 0x8A89, KANJI_LEARNING_ORDER_7, // 誉 + 0x8A8C, KANJI_LEARNING_ORDER_6, // 誌 + 0x8A8D, KANJI_LEARNING_ORDER_6, // 認 + 0x8A93, KANJI_LEARNING_ORDER_7, // 誓 + 0x8A95, KANJI_LEARNING_ORDER_6, // 誕 + 0x8A98, KANJI_LEARNING_ORDER_7, // 誘 + 0x8A9E, KANJI_LEARNING_ORDER_2, // 語 + 0x8AA0, KANJI_LEARNING_ORDER_6, // 誠 + 0x8AA4, KANJI_LEARNING_ORDER_6, // 誀 + 0x8AAC, KANJI_LEARNING_ORDER_4, // 説 + 0x8AAD, KANJI_LEARNING_ORDER_2, // 読 + 0x8AB2, KANJI_LEARNING_ORDER_4, // 課 + 0x8ABF, KANJI_LEARNING_ORDER_3, // 調 + 0x8AC7, KANJI_LEARNING_ORDER_3, // 談 + 0x8ACB, KANJI_LEARNING_ORDER_7, // 請 + 0x8AD6, KANJI_LEARNING_ORDER_6, // 論 + 0x8AED, KANJI_LEARNING_ORDER_7, // è«­ + 0x8AEE, KANJI_LEARNING_ORDER_7, // è«® + 0x8AF8, KANJI_LEARNING_ORDER_6, // 諞 + 0x8AFE, KANJI_LEARNING_ORDER_7, // 諟 + 0x8B00, KANJI_LEARNING_ORDER_7, // 謀 + 0x8B01, KANJI_LEARNING_ORDER_7, // 謁 + 0x8B04, KANJI_LEARNING_ORDER_7, // 謄 + 0x8B19, KANJI_LEARNING_ORDER_7, // 謙 + 0x8B1B, KANJI_LEARNING_ORDER_5, // 講 + 0x8B1D, KANJI_LEARNING_ORDER_5, // 謝 + 0x8B21, KANJI_LEARNING_ORDER_7, // 謡 + 0x8B39, KANJI_LEARNING_ORDER_7, // 謹 + 0x8B58, KANJI_LEARNING_ORDER_5, // 識 + 0x8B5C, KANJI_LEARNING_ORDER_7, // 譜 + 0x8B66, KANJI_LEARNING_ORDER_6, // è­Š + 0x8B70, KANJI_LEARNING_ORDER_4, // è­° + 0x8B72, KANJI_LEARNING_ORDER_7, // è­² + 0x8B77, KANJI_LEARNING_ORDER_5, // è­· + 0x8C37, KANJI_LEARNING_ORDER_2, // è°· + 0x8C46, KANJI_LEARNING_ORDER_3, // 豆 + 0x8C4A, KANJI_LEARNING_ORDER_5, // 豊 + 0x8C5A, KANJI_LEARNING_ORDER_7, // 豚 + 0x8C61, KANJI_LEARNING_ORDER_4, // 象 + 0x8C6A, KANJI_LEARNING_ORDER_7, // 豪 + 0x8C9D, KANJI_LEARNING_ORDER_1, // 貝 + 0x8C9E, KANJI_LEARNING_ORDER_7, // 貞 + 0x8CA0, KANJI_LEARNING_ORDER_3, // è²  + 0x8CA1, KANJI_LEARNING_ORDER_5, // 財 + 0x8CA2, KANJI_LEARNING_ORDER_7, // è²¢ + 0x8CA7, KANJI_LEARNING_ORDER_5, // è²§ + 0x8CA8, KANJI_LEARNING_ORDER_4, // 貚 + 0x8CA9, KANJI_LEARNING_ORDER_7, // 販 + 0x8CAB, KANJI_LEARNING_ORDER_7, // 貫 + 0x8CAC, KANJI_LEARNING_ORDER_5, // 責 + 0x8CAF, KANJI_LEARNING_ORDER_4, // 貯 + 0x8CB4, KANJI_LEARNING_ORDER_6, // 貎 + 0x8CB7, KANJI_LEARNING_ORDER_2, // è²· + 0x8CB8, KANJI_LEARNING_ORDER_5, // 貞 + 0x8CBB, KANJI_LEARNING_ORDER_4, // è²» + 0x8CBF, KANJI_LEARNING_ORDER_5, // 貿 + 0x8CC0, KANJI_LEARNING_ORDER_5, // 賀 + 0x8CC3, KANJI_LEARNING_ORDER_6, // 賃 + 0x8CC4, KANJI_LEARNING_ORDER_7, // 賄 + 0x8CC7, KANJI_LEARNING_ORDER_5, // 資 + 0x8CCA, KANJI_LEARNING_ORDER_7, // 賊 + 0x8CD3, KANJI_LEARNING_ORDER_7, // 賓 + 0x8CDB, KANJI_LEARNING_ORDER_5, // 賛 + 0x8CDC, KANJI_LEARNING_ORDER_7, // 賜 + 0x8CDE, KANJI_LEARNING_ORDER_4, // 賞 + 0x8CE0, KANJI_LEARNING_ORDER_7, // è³  + 0x8CE2, KANJI_LEARNING_ORDER_7, // è³¢ + 0x8CE6, KANJI_LEARNING_ORDER_7, // 賊 + 0x8CEA, KANJI_LEARNING_ORDER_5, // 質 + 0x8CFC, KANJI_LEARNING_ORDER_7, // 賌 + 0x8D08, KANJI_LEARNING_ORDER_7, // 莈 + 0x8D64, KANJI_LEARNING_ORDER_1, // èµ€ + 0x8D66, KANJI_LEARNING_ORDER_7, // 赊 + 0x8D70, KANJI_LEARNING_ORDER_2, // èµ° + 0x8D74, KANJI_LEARNING_ORDER_7, // 赎 + 0x8D77, KANJI_LEARNING_ORDER_3, // èµ· + 0x8D85, KANJI_LEARNING_ORDER_7, // 超 + 0x8D8A, KANJI_LEARNING_ORDER_7, // 越 + 0x8DA3, KANJI_LEARNING_ORDER_7, // è¶£ + 0x8DB3, KANJI_LEARNING_ORDER_1, // è¶³ + 0x8DDD, KANJI_LEARNING_ORDER_7, // 距 + 0x8DE1, KANJI_LEARNING_ORDER_7, // è·¡ + 0x8DEF, KANJI_LEARNING_ORDER_3, // è·¯ + 0x8DF3, KANJI_LEARNING_ORDER_7, // è·³ + 0x8DF5, KANJI_LEARNING_ORDER_7, // è·µ + 0x8E0A, KANJI_LEARNING_ORDER_7, // 螊 + 0x8E0F, KANJI_LEARNING_ORDER_7, // 螏 + 0x8E8D, KANJI_LEARNING_ORDER_7, // 躍 + 0x8EAB, KANJI_LEARNING_ORDER_3, // 身 + 0x8ECA, KANJI_LEARNING_ORDER_1, // 車 + 0x8ECC, KANJI_LEARNING_ORDER_7, // 軌 + 0x8ECD, KANJI_LEARNING_ORDER_4, // 軍 + 0x8ED2, KANJI_LEARNING_ORDER_7, // 軒 + 0x8EDF, KANJI_LEARNING_ORDER_7, // 軟 + 0x8EE2, KANJI_LEARNING_ORDER_3, // 転 + 0x8EF8, KANJI_LEARNING_ORDER_7, // 軞 + 0x8EFD, KANJI_LEARNING_ORDER_3, // 軜 + 0x8F03, KANJI_LEARNING_ORDER_7, // 范 + 0x8F09, KANJI_LEARNING_ORDER_7, // 茉 + 0x8F1D, KANJI_LEARNING_ORDER_7, // 茝 + 0x8F29, KANJI_LEARNING_ORDER_7, // 茩 + 0x8F2A, KANJI_LEARNING_ORDER_4, // 茪 + 0x8F38, KANJI_LEARNING_ORDER_5, // 茞 + 0x8F44, KANJI_LEARNING_ORDER_7, // 蜄 + 0x8F9B, KANJI_LEARNING_ORDER_7, // 蟛 + 0x8F9E, KANJI_LEARNING_ORDER_4, // 蟞 + 0x8FB1, KANJI_LEARNING_ORDER_7, // 蟱 + 0x8FB2, KANJI_LEARNING_ORDER_3, // 蟲 + 0x8FBA, KANJI_LEARNING_ORDER_4, // 蟺 + 0x8FBC, KANJI_LEARNING_ORDER_7, // 蟌 + 0x8FC5, KANJI_LEARNING_ORDER_7, // 迅 + 0x8FCE, KANJI_LEARNING_ORDER_7, // 迎 + 0x8FD1, KANJI_LEARNING_ORDER_2, // 近 + 0x8FD4, KANJI_LEARNING_ORDER_3, // 返 + 0x8FEB, KANJI_LEARNING_ORDER_7, // è¿« + 0x8FED, KANJI_LEARNING_ORDER_7, // è¿­ + 0x8FF0, KANJI_LEARNING_ORDER_5, // è¿° + 0x8FF7, KANJI_LEARNING_ORDER_5, // è¿· + 0x8FFD, KANJI_LEARNING_ORDER_3, // 远 + 0x9000, KANJI_LEARNING_ORDER_5, // 退 + 0x9001, KANJI_LEARNING_ORDER_3, // 送 + 0x9003, KANJI_LEARNING_ORDER_7, // 逃 + 0x9006, KANJI_LEARNING_ORDER_5, // 逆 + 0x900F, KANJI_LEARNING_ORDER_7, // 透 + 0x9010, KANJI_LEARNING_ORDER_7, // 逐 + 0x9013, KANJI_LEARNING_ORDER_7, // 逓 + 0x9014, KANJI_LEARNING_ORDER_7, // 途 + 0x901A, KANJI_LEARNING_ORDER_2, // 通 + 0x901D, KANJI_LEARNING_ORDER_7, // 逝 + 0x901F, KANJI_LEARNING_ORDER_3, // 速 + 0x9020, KANJI_LEARNING_ORDER_5, // 造 + 0x9023, KANJI_LEARNING_ORDER_4, // 連 + 0x902E, KANJI_LEARNING_ORDER_7, // 逮 + 0x9031, KANJI_LEARNING_ORDER_2, // 週 + 0x9032, KANJI_LEARNING_ORDER_3, // 進 + 0x9038, KANJI_LEARNING_ORDER_7, // 逾 + 0x9042, KANJI_LEARNING_ORDER_7, // 遂 + 0x9045, KANJI_LEARNING_ORDER_7, // 遅 + 0x9047, KANJI_LEARNING_ORDER_7, // 遇 + 0x904A, KANJI_LEARNING_ORDER_3, // 遊 + 0x904B, KANJI_LEARNING_ORDER_3, // 運 + 0x904D, KANJI_LEARNING_ORDER_7, // 遍 + 0x904E, KANJI_LEARNING_ORDER_5, // 過 + 0x9053, KANJI_LEARNING_ORDER_2, // 道 + 0x9054, KANJI_LEARNING_ORDER_4, // 達 + 0x9055, KANJI_LEARNING_ORDER_7, // 違 + 0x9060, KANJI_LEARNING_ORDER_2, // 遠 + 0x9063, KANJI_LEARNING_ORDER_7, // 遣 + 0x9069, KANJI_LEARNING_ORDER_5, // 適 + 0x906D, KANJI_LEARNING_ORDER_7, // 遭 + 0x906E, KANJI_LEARNING_ORDER_7, // 遮 + 0x9075, KANJI_LEARNING_ORDER_7, // 遵 + 0x9077, KANJI_LEARNING_ORDER_7, // 遷 + 0x9078, KANJI_LEARNING_ORDER_4, // 遞 + 0x907A, KANJI_LEARNING_ORDER_6, // 遺 + 0x907F, KANJI_LEARNING_ORDER_7, // 避 + 0x9084, KANJI_LEARNING_ORDER_7, // 還 + 0x90A6, KANJI_LEARNING_ORDER_7, // 邩 + 0x90AA, KANJI_LEARNING_ORDER_7, // 邪 + 0x90B8, KANJI_LEARNING_ORDER_7, // 邾 + 0x90CA, KANJI_LEARNING_ORDER_7, // 郊 + 0x90CE, KANJI_LEARNING_ORDER_7, // 郎 + 0x90E1, KANJI_LEARNING_ORDER_4, // 郡 + 0x90E8, KANJI_LEARNING_ORDER_3, // 郚 + 0x90ED, KANJI_LEARNING_ORDER_7, // 郭 + 0x90F5, KANJI_LEARNING_ORDER_6, // 郵 + 0x90F7, KANJI_LEARNING_ORDER_6, // 郷 + 0x90FD, KANJI_LEARNING_ORDER_3, // 郜 + 0x914C, KANJI_LEARNING_ORDER_7, // 酌 + 0x914D, KANJI_LEARNING_ORDER_3, // 配 + 0x9152, KANJI_LEARNING_ORDER_3, // 酒 + 0x9154, KANJI_LEARNING_ORDER_7, // 酔 + 0x9162, KANJI_LEARNING_ORDER_7, // 酢 + 0x916A, KANJI_LEARNING_ORDER_7, // 酪 + 0x916C, KANJI_LEARNING_ORDER_7, // 酬 + 0x9175, KANJI_LEARNING_ORDER_7, // 酵 + 0x9177, KANJI_LEARNING_ORDER_7, // 酷 + 0x9178, KANJI_LEARNING_ORDER_5, // 酾 + 0x919C, KANJI_LEARNING_ORDER_7, // 醜 + 0x91B8, KANJI_LEARNING_ORDER_7, // 醾 + 0x91C8, KANJI_LEARNING_ORDER_7, // 釈 + 0x91CC, KANJI_LEARNING_ORDER_2, // 里 + 0x91CD, KANJI_LEARNING_ORDER_3, // 重 + 0x91CE, KANJI_LEARNING_ORDER_2, // 野 + 0x91CF, KANJI_LEARNING_ORDER_4, // 量 + 0x91D1, KANJI_LEARNING_ORDER_1, // 金 + 0x91DD, KANJI_LEARNING_ORDER_6, // 針 + 0x91E3, KANJI_LEARNING_ORDER_7, // 釣 + 0x920D, KANJI_LEARNING_ORDER_7, // 鈍 + 0x9234, KANJI_LEARNING_ORDER_7, // 鈎 + 0x9244, KANJI_LEARNING_ORDER_3, // 鉄 + 0x925B, KANJI_LEARNING_ORDER_7, // 鉛 + 0x9262, KANJI_LEARNING_ORDER_7, // 鉢 + 0x9271, KANJI_LEARNING_ORDER_5, // 鉱 + 0x9280, KANJI_LEARNING_ORDER_3, // 銀 + 0x9283, KANJI_LEARNING_ORDER_7, // 銃 + 0x9285, KANJI_LEARNING_ORDER_5, // 銅 + 0x9291, KANJI_LEARNING_ORDER_7, // 銑 + 0x9298, KANJI_LEARNING_ORDER_7, // 銘 + 0x92AD, KANJI_LEARNING_ORDER_5, // 銭 + 0x92ED, KANJI_LEARNING_ORDER_7, // 鋭 + 0x92F3, KANJI_LEARNING_ORDER_7, // 鋳 + 0x92FC, KANJI_LEARNING_ORDER_6, // 鋌 + 0x9318, KANJI_LEARNING_ORDER_7, // 錘 + 0x9320, KANJI_LEARNING_ORDER_7, // 錠 + 0x932C, KANJI_LEARNING_ORDER_7, // 錬 + 0x932F, KANJI_LEARNING_ORDER_7, // 錯 + 0x9332, KANJI_LEARNING_ORDER_4, // 録 + 0x935B, KANJI_LEARNING_ORDER_7, // 鍛 + 0x9396, KANJI_LEARNING_ORDER_7, // 鎖 + 0x93AE, KANJI_LEARNING_ORDER_7, // 鎮 + 0x93E1, KANJI_LEARNING_ORDER_4, // 鏡 + 0x9418, KANJI_LEARNING_ORDER_7, // 鐘 + 0x9451, KANJI_LEARNING_ORDER_7, // 鑑 + 0x9577, KANJI_LEARNING_ORDER_2, // 長 + 0x9580, KANJI_LEARNING_ORDER_2, // 門 + 0x9589, KANJI_LEARNING_ORDER_6, // 閉 + 0x958B, KANJI_LEARNING_ORDER_3, // 開 + 0x9591, KANJI_LEARNING_ORDER_7, // 閑 + 0x9593, KANJI_LEARNING_ORDER_2, // 間 + 0x95A2, KANJI_LEARNING_ORDER_4, // 関 + 0x95A3, KANJI_LEARNING_ORDER_6, // 閣 + 0x95A5, KANJI_LEARNING_ORDER_7, // 閥 + 0x95B2, KANJI_LEARNING_ORDER_7, // 閲 + 0x95D8, KANJI_LEARNING_ORDER_7, // 闘 + 0x9632, KANJI_LEARNING_ORDER_5, // 防 + 0x963B, KANJI_LEARNING_ORDER_7, // 阻 + 0x9644, KANJI_LEARNING_ORDER_7, // 附 + 0x964D, KANJI_LEARNING_ORDER_6, // 降 + 0x9650, KANJI_LEARNING_ORDER_5, // 限 + 0x965B, KANJI_LEARNING_ORDER_6, // 陛 + 0x9662, KANJI_LEARNING_ORDER_3, // 院 + 0x9663, KANJI_LEARNING_ORDER_7, // 陣 + 0x9664, KANJI_LEARNING_ORDER_6, // 陀 + 0x9665, KANJI_LEARNING_ORDER_7, // 陥 + 0x966A, KANJI_LEARNING_ORDER_7, // 陪 + 0x9670, KANJI_LEARNING_ORDER_7, // 陰 + 0x9673, KANJI_LEARNING_ORDER_7, // 陳 + 0x9675, KANJI_LEARNING_ORDER_7, // 陵 + 0x9676, KANJI_LEARNING_ORDER_7, // 陶 + 0x9678, KANJI_LEARNING_ORDER_4, // 陾 + 0x967A, KANJI_LEARNING_ORDER_5, // 険 + 0x967D, KANJI_LEARNING_ORDER_3, // 陜 + 0x9685, KANJI_LEARNING_ORDER_7, // 隅 + 0x9686, KANJI_LEARNING_ORDER_7, // 隆 + 0x968A, KANJI_LEARNING_ORDER_4, // 隊 + 0x968E, KANJI_LEARNING_ORDER_3, // 階 + 0x968F, KANJI_LEARNING_ORDER_7, // 随 + 0x9694, KANJI_LEARNING_ORDER_7, // 隔 + 0x969B, KANJI_LEARNING_ORDER_5, // 際 + 0x969C, KANJI_LEARNING_ORDER_6, // 障 + 0x96A0, KANJI_LEARNING_ORDER_7, // 隠 + 0x96A3, KANJI_LEARNING_ORDER_7, // 隣 + 0x96B7, KANJI_LEARNING_ORDER_7, // 隷 + 0x96BB, KANJI_LEARNING_ORDER_7, // 隻 + 0x96C4, KANJI_LEARNING_ORDER_7, // 雄 + 0x96C5, KANJI_LEARNING_ORDER_7, // 雅 + 0x96C6, KANJI_LEARNING_ORDER_3, // 集 + 0x96C7, KANJI_LEARNING_ORDER_7, // 雇 + 0x96CC, KANJI_LEARNING_ORDER_7, // 雌 + 0x96D1, KANJI_LEARNING_ORDER_5, // 雑 + 0x96E2, KANJI_LEARNING_ORDER_7, // 離 + 0x96E3, KANJI_LEARNING_ORDER_6, // 難 + 0x96E8, KANJI_LEARNING_ORDER_1, // 雹 + 0x96EA, KANJI_LEARNING_ORDER_2, // 雪 + 0x96F0, KANJI_LEARNING_ORDER_7, // 雰 + 0x96F2, KANJI_LEARNING_ORDER_2, // 雲 + 0x96F6, KANJI_LEARNING_ORDER_7, // 零 + 0x96F7, KANJI_LEARNING_ORDER_7, // 雷 + 0x96FB, KANJI_LEARNING_ORDER_2, // 電 + 0x9700, KANJI_LEARNING_ORDER_7, // 需 + 0x9707, KANJI_LEARNING_ORDER_7, // 震 + 0x970A, KANJI_LEARNING_ORDER_7, // 霊 + 0x971C, KANJI_LEARNING_ORDER_7, // 霜 + 0x9727, KANJI_LEARNING_ORDER_7, // 霧 + 0x9732, KANJI_LEARNING_ORDER_7, // 露 + 0x9752, KANJI_LEARNING_ORDER_1, // 青 + 0x9759, KANJI_LEARNING_ORDER_4, // 静 + 0x975E, KANJI_LEARNING_ORDER_5, // 非 + 0x9762, KANJI_LEARNING_ORDER_3, // 面 + 0x9769, KANJI_LEARNING_ORDER_6, // 革 + 0x9774, KANJI_LEARNING_ORDER_7, // 靎 + 0x97F3, KANJI_LEARNING_ORDER_1, // 音 + 0x97FB, KANJI_LEARNING_ORDER_7, // 韻 + 0x97FF, KANJI_LEARNING_ORDER_7, // 響 + 0x9802, KANJI_LEARNING_ORDER_6, // 頂 + 0x9805, KANJI_LEARNING_ORDER_7, // 項 + 0x9806, KANJI_LEARNING_ORDER_4, // 順 + 0x9810, KANJI_LEARNING_ORDER_5, // 預 + 0x9811, KANJI_LEARNING_ORDER_7, // 頑 + 0x9812, KANJI_LEARNING_ORDER_7, // 頒 + 0x9818, KANJI_LEARNING_ORDER_5, // 領 + 0x982D, KANJI_LEARNING_ORDER_2, // é ­ + 0x983B, KANJI_LEARNING_ORDER_7, // é » + 0x983C, KANJI_LEARNING_ORDER_7, // é Œ + 0x984C, KANJI_LEARNING_ORDER_3, // 題 + 0x984D, KANJI_LEARNING_ORDER_5, // 額 + 0x9854, KANJI_LEARNING_ORDER_2, // 顔 + 0x9855, KANJI_LEARNING_ORDER_7, // 顕 + 0x9858, KANJI_LEARNING_ORDER_4, // 願 + 0x985E, KANJI_LEARNING_ORDER_4, // 類 + 0x9867, KANJI_LEARNING_ORDER_7, // é¡§ + 0x98A8, KANJI_LEARNING_ORDER_2, // 颚 + 0x98DB, KANJI_LEARNING_ORDER_4, // 飛 + 0x98DF, KANJI_LEARNING_ORDER_2, // 食 + 0x98E2, KANJI_LEARNING_ORDER_7, // 飢 + 0x98EF, KANJI_LEARNING_ORDER_4, // 飯 + 0x98F2, KANJI_LEARNING_ORDER_3, // 飲 + 0x98FC, KANJI_LEARNING_ORDER_5, // 飌 + 0x98FD, KANJI_LEARNING_ORDER_7, // 飜 + 0x98FE, KANJI_LEARNING_ORDER_7, // 食 + 0x990A, KANJI_LEARNING_ORDER_4, // 逊 + 0x9913, KANJI_LEARNING_ORDER_7, // 逓 + 0x9928, KANJI_LEARNING_ORDER_3, // 通 + 0x9996, KANJI_LEARNING_ORDER_2, // 驖 + 0x9999, KANJI_LEARNING_ORDER_7, // 驙 + 0x99AC, KANJI_LEARNING_ORDER_2, // 銬 + 0x99C4, KANJI_LEARNING_ORDER_7, // 駄 + 0x99C5, KANJI_LEARNING_ORDER_3, // 駅 + 0x99C6, KANJI_LEARNING_ORDER_7, // 駆 + 0x99D0, KANJI_LEARNING_ORDER_7, // 駐 + 0x9A0E, KANJI_LEARNING_ORDER_7, // 階 + 0x9A12, KANJI_LEARNING_ORDER_7, // 鹒 + 0x9A13, KANJI_LEARNING_ORDER_4, // 鹓 + 0x9A30, KANJI_LEARNING_ORDER_7, // éš° + 0x9A5A, KANJI_LEARNING_ORDER_7, // 驚 + 0x9AA8, KANJI_LEARNING_ORDER_6, // 骚 + 0x9AC4, KANJI_LEARNING_ORDER_7, // 髄 + 0x9AD8, KANJI_LEARNING_ORDER_2, // 高 + 0x9AEA, KANJI_LEARNING_ORDER_7, // 髪 + 0x9B3C, KANJI_LEARNING_ORDER_7, // 鬌 + 0x9B42, KANJI_LEARNING_ORDER_7, // 魂 + 0x9B45, KANJI_LEARNING_ORDER_7, // 魅 + 0x9B54, KANJI_LEARNING_ORDER_7, // 魔 + 0x9B5A, KANJI_LEARNING_ORDER_2, // 魚 + 0x9BAE, KANJI_LEARNING_ORDER_7, // é®® + 0x9BE8, KANJI_LEARNING_ORDER_7, // 鯚 + 0x9CE5, KANJI_LEARNING_ORDER_2, // é³¥ + 0x9CF4, KANJI_LEARNING_ORDER_2, // 鳎 + 0x9D8F, KANJI_LEARNING_ORDER_7, // 鶏 + 0x9E97, KANJI_LEARNING_ORDER_7, // 麗 + 0x9EA6, KANJI_LEARNING_ORDER_2, // 麊 + 0x9EBB, KANJI_LEARNING_ORDER_7, // 麻 + 0x9EC4, KANJI_LEARNING_ORDER_2, // 黄 + 0x9ED2, KANJI_LEARNING_ORDER_2, // 黒 + 0x9ED9, KANJI_LEARNING_ORDER_7, // 黙 + 0x9F13, KANJI_LEARNING_ORDER_7, // 錓 + 0x9F3B, KANJI_LEARNING_ORDER_3, // 錻 + 0x9F62, KANJI_LEARNING_ORDER_7, // 霢 + 0x4E9C, KANJI_STANDARD, // 亜 + 0x5516, KANJI_STANDARD, // 唖 + 0x5A03, KANJI_STANDARD, // 嚃 + 0x963F, KANJI_STANDARD, // 阿 + 0x54C0, KANJI_STANDARD, // 哀 + 0x611B, KANJI_STANDARD, // 愛 + 0x6328, KANJI_STANDARD, // 挚 + 0x59F6, KANJI_STANDARD, // å§¶ + 0x9022, KANJI_STANDARD, // 逢 + 0x8475, KANJI_STANDARD, // 葵 + 0x831C, KANJI_STANDARD, // 茜 + 0x7A50, KANJI_STANDARD, // 穐 + 0x60AA, KANJI_STANDARD, // 悪 + 0x63E1, KANJI_STANDARD, // 握 + 0x6E25, KANJI_STANDARD, // 枥 + 0x65ED, KANJI_STANDARD, // 旭 + 0x8466, KANJI_STANDARD, // 葊 + 0x82A6, KANJI_STANDARD, // 芊 + 0x9BF5, KANJI_STANDARD, // 鯵 + 0x6893, KANJI_STANDARD, // 梓 + 0x5727, KANJI_STANDARD, // 圧 + 0x65A1, KANJI_STANDARD, // 斡 + 0x6271, KANJI_STANDARD, // 扱 + 0x5B9B, KANJI_STANDARD, // 宛 + 0x59D0, KANJI_STANDARD, // 姐 + 0x867B, KANJI_STANDARD, // 虻 + 0x98F4, KANJI_STANDARD, // 风 + 0x7D62, KANJI_STANDARD, // çµ¢ + 0x7DBE, KANJI_STANDARD, // ç¶Ÿ + 0x9B8E, KANJI_STANDARD, // 鮎 + 0x6216, KANJI_STANDARD, // 或 + 0x7C9F, KANJI_STANDARD, // 粟 + 0x88B7, KANJI_STANDARD, // 袷 + 0x5B89, KANJI_STANDARD, // 安 + 0x5EB5, KANJI_STANDARD, // 庵 + 0x6309, KANJI_STANDARD, // 按 + 0x6697, KANJI_STANDARD, // 暗 + 0x6848, KANJI_STANDARD, // 案 + 0x95C7, KANJI_STANDARD, // 闇 + 0x978D, KANJI_STANDARD, // 鞍 + 0x674F, KANJI_STANDARD, // 杏 + 0x4EE5, KANJI_STANDARD, // 以 + 0x4F0A, KANJI_STANDARD, // 䌊 + 0x4F4D, KANJI_STANDARD, // 䜍 + 0x4F9D, KANJI_STANDARD, // 䟝 + 0x5049, KANJI_STANDARD, // 偉 + 0x56F2, KANJI_STANDARD, // 囲 + 0x5937, KANJI_STANDARD, // 倷 + 0x59D4, KANJI_STANDARD, // 委 + 0x5A01, KANJI_STANDARD, // 嚁 + 0x5C09, KANJI_STANDARD, // 尉 + 0x60DF, KANJI_STANDARD, // 惟 + 0x610F, KANJI_STANDARD, // 意 + 0x6170, KANJI_STANDARD, // 慰 + 0x6613, KANJI_STANDARD, // 易 + 0x6905, KANJI_STANDARD, // 怅 + 0x70BA, KANJI_STANDARD, // 為 + 0x754F, KANJI_STANDARD, // 畏 + 0x7570, KANJI_STANDARD, // 異 + 0x79FB, KANJI_STANDARD, // ç§» + 0x7DAD, KANJI_STANDARD, // ç¶­ + 0x7DEF, KANJI_STANDARD, // ç·¯ + 0x80C3, KANJI_STANDARD, // 胃 + 0x840E, KANJI_STANDARD, // 萎 + 0x8863, KANJI_STANDARD, // è¡£ + 0x8B02, KANJI_STANDARD, // 謂 + 0x9055, KANJI_STANDARD, // 違 + 0x907A, KANJI_STANDARD, // 遺 + 0x533B, KANJI_STANDARD, // 医 + 0x4E95, KANJI_STANDARD, // 井 + 0x4EA5, KANJI_STANDARD, // 亥 + 0x57DF, KANJI_STANDARD, // 域 + 0x80B2, KANJI_STANDARD, // 育 + 0x90C1, KANJI_STANDARD, // 郁 + 0x78EF, KANJI_STANDARD, // 磯 + 0x4E00, KANJI_STANDARD, // 侀 + 0x58F1, KANJI_STANDARD, // 壱 + 0x6EA2, KANJI_STANDARD, // 溢 + 0x9038, KANJI_STANDARD, // 逾 + 0x7A32, KANJI_STANDARD, // çš² + 0x8328, KANJI_STANDARD, // 茚 + 0x828B, KANJI_STANDARD, // 芋 + 0x9C2F, KANJI_STANDARD, // é°¯ + 0x5141, KANJI_STANDARD, // 允 + 0x5370, KANJI_STANDARD, // 印 + 0x54BD, KANJI_STANDARD, // å’œ + 0x54E1, KANJI_STANDARD, // 員 + 0x56E0, KANJI_STANDARD, // 因 + 0x59FB, KANJI_STANDARD, // å§» + 0x5F15, KANJI_STANDARD, // 匕 + 0x98F2, KANJI_STANDARD, // 飲 + 0x6DEB, KANJI_STANDARD, // æ·« + 0x80E4, KANJI_STANDARD, // 胀 + 0x852D, KANJI_STANDARD, // 蔭 + 0x9662, KANJI_STANDARD, // 院 + 0x9670, KANJI_STANDARD, // 陰 + 0x96A0, KANJI_STANDARD, // 隠 + 0x97FB, KANJI_STANDARD, // 韻 + 0x540B, KANJI_STANDARD, // 吋 + 0x53F3, KANJI_STANDARD, // 右 + 0x5B87, KANJI_STANDARD, // 宇 + 0x70CF, KANJI_STANDARD, // 烏 + 0x7FBD, KANJI_STANDARD, // 矜 + 0x8FC2, KANJI_STANDARD, // 迂 + 0x96E8, KANJI_STANDARD, // 雹 + 0x536F, KANJI_STANDARD, // 卯 + 0x9D5C, KANJI_STANDARD, // 鵜 + 0x7ABA, KANJI_STANDARD, // 窺 + 0x4E11, KANJI_STANDARD, // 侑 + 0x7893, KANJI_STANDARD, // 碓 + 0x81FC, KANJI_STANDARD, // 臌 + 0x6E26, KANJI_STANDARD, // 枊 + 0x5618, KANJI_STANDARD, // 嘘 + 0x5504, KANJI_STANDARD, // 唄 + 0x6B1D, KANJI_STANDARD, // 欝 + 0x851A, KANJI_STANDARD, // 蔚 + 0x9C3B, KANJI_STANDARD, // é°» + 0x59E5, KANJI_STANDARD, // å§¥ + 0x53A9, KANJI_STANDARD, // 厩 + 0x6D66, KANJI_STANDARD, // 浊 + 0x74DC, KANJI_STANDARD, // 瓜 + 0x958F, KANJI_STANDARD, // 閏 + 0x5642, KANJI_STANDARD, // 噂 + 0x4E91, KANJI_STANDARD, // 云 + 0x904B, KANJI_STANDARD, // 運 + 0x96F2, KANJI_STANDARD, // 雲 + 0x834F, KANJI_STANDARD, // 荏 + 0x990C, KANJI_STANDARD, // 逌 + 0x53E1, KANJI_STANDARD, // 叡 + 0x55B6, KANJI_STANDARD, // 営 + 0x5B30, KANJI_STANDARD, // 嬰 + 0x5F71, KANJI_STANDARD, // 圱 + 0x6620, KANJI_STANDARD, // 映 + 0x66F3, KANJI_STANDARD, // 曳 + 0x6804, KANJI_STANDARD, // 栄 + 0x6C38, KANJI_STANDARD, // æ°ž + 0x6CF3, KANJI_STANDARD, // æ³³ + 0x6D29, KANJI_STANDARD, // 掩 + 0x745B, KANJI_STANDARD, // 瑛 + 0x76C8, KANJI_STANDARD, // 盈 + 0x7A4E, KANJI_STANDARD, // 穎 + 0x9834, KANJI_STANDARD, // é Ž + 0x82F1, KANJI_STANDARD, // 英 + 0x885B, KANJI_STANDARD, // 衛 + 0x8A60, KANJI_STANDARD, // è©  + 0x92ED, KANJI_STANDARD, // 鋭 + 0x6DB2, KANJI_STANDARD, // æ¶² + 0x75AB, KANJI_STANDARD, // 疫 + 0x76CA, KANJI_STANDARD, // 益 + 0x99C5, KANJI_STANDARD, // 駅 + 0x60A6, KANJI_STANDARD, // 悊 + 0x8B01, KANJI_STANDARD, // 謁 + 0x8D8A, KANJI_STANDARD, // 越 + 0x95B2, KANJI_STANDARD, // 閲 + 0x698E, KANJI_STANDARD, // 抎 + 0x53AD, KANJI_STANDARD, // 厭 + 0x5186, KANJI_STANDARD, // 円 + 0x5712, KANJI_STANDARD, // 園 + 0x5830, KANJI_STANDARD, // å ° + 0x5944, KANJI_STANDARD, // 奄 + 0x5BB4, KANJI_STANDARD, // 宎 + 0x5EF6, KANJI_STANDARD, // å»¶ + 0x6028, KANJI_STANDARD, // 怚 + 0x63A9, KANJI_STANDARD, // 掩 + 0x63F4, KANJI_STANDARD, // 揎 + 0x6CBF, KANJI_STANDARD, // 沿 + 0x6F14, KANJI_STANDARD, // 挔 + 0x708E, KANJI_STANDARD, // 炎 + 0x7114, KANJI_STANDARD, // 焔 + 0x7159, KANJI_STANDARD, // 煙 + 0x71D5, KANJI_STANDARD, // 燕 + 0x733F, KANJI_STANDARD, // 猿 + 0x7E01, KANJI_STANDARD, // 瞁 + 0x8276, KANJI_STANDARD, // 艶 + 0x82D1, KANJI_STANDARD, // 苑 + 0x8597, KANJI_STANDARD, // 薗 + 0x9060, KANJI_STANDARD, // 遠 + 0x925B, KANJI_STANDARD, // 鉛 + 0x9D1B, KANJI_STANDARD, // 鮛 + 0x5869, KANJI_STANDARD, // å¡© + 0x65BC, KANJI_STANDARD, // æ–Œ + 0x6C5A, KANJI_STANDARD, // 汚 + 0x7525, KANJI_STANDARD, // 甥 + 0x51F9, KANJI_STANDARD, // 凹 + 0x592E, KANJI_STANDARD, // 倮 + 0x5965, KANJI_STANDARD, // 奥 + 0x5F80, KANJI_STANDARD, // 埀 + 0x5FDC, KANJI_STANDARD, // 応 + 0x62BC, KANJI_STANDARD, // 抌 + 0x65FA, KANJI_STANDARD, // 旺 + 0x6A2A, KANJI_STANDARD, // 暪 + 0x6B27, KANJI_STANDARD, // 欧 + 0x6BB4, KANJI_STANDARD, // 殎 + 0x738B, KANJI_STANDARD, // 王 + 0x7FC1, KANJI_STANDARD, // 翁 + 0x8956, KANJI_STANDARD, // 襖 + 0x9D2C, KANJI_STANDARD, // 鎬 + 0x9D0E, KANJI_STANDARD, // 鮎 + 0x9EC4, KANJI_STANDARD, // 黄 + 0x5CA1, KANJI_STANDARD, // 岡 + 0x6C96, KANJI_STANDARD, // 沖 + 0x837B, KANJI_STANDARD, // 荻 + 0x5104, KANJI_STANDARD, // 億 + 0x5C4B, KANJI_STANDARD, // 屋 + 0x61B6, KANJI_STANDARD, // 憶 + 0x81C6, KANJI_STANDARD, // 臆 + 0x6876, KANJI_STANDARD, // æ¡¶ + 0x7261, KANJI_STANDARD, // 牡 + 0x4E59, KANJI_STANDARD, // 乙 + 0x4FFA, KANJI_STANDARD, // 俺 + 0x5378, KANJI_STANDARD, // 卞 + 0x6069, KANJI_STANDARD, // 恩 + 0x6E29, KANJI_STANDARD, // æž© + 0x7A4F, KANJI_STANDARD, // 穏 + 0x97F3, KANJI_STANDARD, // 音 + 0x4E0B, KANJI_STANDARD, // 例 + 0x5316, KANJI_STANDARD, // 化 + 0x4EEE, KANJI_STANDARD, // ä»® + 0x4F55, KANJI_STANDARD, // 䜕 + 0x4F3D, KANJI_STANDARD, // 䌜 + 0x4FA1, KANJI_STANDARD, // 䟡 + 0x4F73, KANJI_STANDARD, // 䜳 + 0x52A0, KANJI_STANDARD, // 加 + 0x53EF, KANJI_STANDARD, // 可 + 0x5609, KANJI_STANDARD, // 嘉 + 0x590F, KANJI_STANDARD, // 倏 + 0x5AC1, KANJI_STANDARD, // 嫁 + 0x5BB6, KANJI_STANDARD, // å®¶ + 0x5BE1, KANJI_STANDARD, // 寡 + 0x79D1, KANJI_STANDARD, // 科 + 0x6687, KANJI_STANDARD, // 暇 + 0x679C, KANJI_STANDARD, // 果 + 0x67B6, KANJI_STANDARD, // 架 + 0x6B4C, KANJI_STANDARD, // 歌 + 0x6CB3, KANJI_STANDARD, // æ²³ + 0x706B, KANJI_STANDARD, // 火 + 0x73C2, KANJI_STANDARD, // 珂 + 0x798D, KANJI_STANDARD, // 犍 + 0x79BE, KANJI_STANDARD, // 犟 + 0x7A3C, KANJI_STANDARD, // 皌 + 0x7B87, KANJI_STANDARD, // 箇 + 0x82B1, KANJI_STANDARD, // 花 + 0x82DB, KANJI_STANDARD, // 苛 + 0x8304, KANJI_STANDARD, // 茄 + 0x8377, KANJI_STANDARD, // 荷 + 0x83EF, KANJI_STANDARD, // 華 + 0x83D3, KANJI_STANDARD, // 菓 + 0x8766, KANJI_STANDARD, // 蝊 + 0x8AB2, KANJI_STANDARD, // 課 + 0x5629, KANJI_STANDARD, // 嘩 + 0x8CA8, KANJI_STANDARD, // 貚 + 0x8FE6, KANJI_STANDARD, // 迊 + 0x904E, KANJI_STANDARD, // 過 + 0x971E, KANJI_STANDARD, // 霞 + 0x868A, KANJI_STANDARD, // 蚊 + 0x4FC4, KANJI_STANDARD, // 俄 + 0x5CE8, KANJI_STANDARD, // 峚 + 0x6211, KANJI_STANDARD, // 我 + 0x7259, KANJI_STANDARD, // 牙 + 0x753B, KANJI_STANDARD, // 画 + 0x81E5, KANJI_STANDARD, // 臥 + 0x82BD, KANJI_STANDARD, // 芜 + 0x86FE, KANJI_STANDARD, // 蛟 + 0x8CC0, KANJI_STANDARD, // 賀 + 0x96C5, KANJI_STANDARD, // 雅 + 0x9913, KANJI_STANDARD, // 逓 + 0x99D5, KANJI_STANDARD, // 駕 + 0x4ECB, KANJI_STANDARD, // 介 + 0x4F1A, KANJI_STANDARD, // 䌚 + 0x89E3, KANJI_STANDARD, // è§£ + 0x56DE, KANJI_STANDARD, // 回 + 0x584A, KANJI_STANDARD, // 塊 + 0x58CA, KANJI_STANDARD, // 壊 + 0x5EFB, KANJI_STANDARD, // å»» + 0x5FEB, KANJI_STANDARD, // å¿« + 0x602A, KANJI_STANDARD, // 怪 + 0x6094, KANJI_STANDARD, // 悔 + 0x6062, KANJI_STANDARD, // 恢 + 0x61D0, KANJI_STANDARD, // 懐 + 0x6212, KANJI_STANDARD, // 戒 + 0x62D0, KANJI_STANDARD, // 拐 + 0x6539, KANJI_STANDARD, // 改 + 0x9B41, KANJI_STANDARD, // 魁 + 0x6666, KANJI_STANDARD, // 晊 + 0x68B0, KANJI_STANDARD, // 械 + 0x6D77, KANJI_STANDARD, // æµ· + 0x7070, KANJI_STANDARD, // 灰 + 0x754C, KANJI_STANDARD, // 界 + 0x7686, KANJI_STANDARD, // 皆 + 0x7D75, KANJI_STANDARD, // çµµ + 0x82A5, KANJI_STANDARD, // 芥 + 0x87F9, KANJI_STANDARD, // 蟹 + 0x958B, KANJI_STANDARD, // 開 + 0x968E, KANJI_STANDARD, // 階 + 0x8C9D, KANJI_STANDARD, // 貝 + 0x51F1, KANJI_STANDARD, // 凱 + 0x52BE, KANJI_STANDARD, // 功 + 0x5916, KANJI_STANDARD, // 倖 + 0x54B3, KANJI_STANDARD, // 咳 + 0x5BB3, KANJI_STANDARD, // 害 + 0x5D16, KANJI_STANDARD, // 厖 + 0x6168, KANJI_STANDARD, // æ…š + 0x6982, KANJI_STANDARD, // 抂 + 0x6DAF, KANJI_STANDARD, // 涯 + 0x788D, KANJI_STANDARD, // 碍 + 0x84CB, KANJI_STANDARD, // 蓋 + 0x8857, KANJI_STANDARD, // 街 + 0x8A72, KANJI_STANDARD, // 該 + 0x93A7, KANJI_STANDARD, // 鎧 + 0x9AB8, KANJI_STANDARD, // 骞 + 0x6D6C, KANJI_STANDARD, // 浬 + 0x99A8, KANJI_STANDARD, // 銚 + 0x86D9, KANJI_STANDARD, // 蛙 + 0x57A3, KANJI_STANDARD, // 垣 + 0x67FF, KANJI_STANDARD, // 柿 + 0x86CE, KANJI_STANDARD, // 蛎 + 0x920E, KANJI_STANDARD, // 鈎 + 0x5283, KANJI_STANDARD, // 劃 + 0x5687, KANJI_STANDARD, // 嚇 + 0x5404, KANJI_STANDARD, // 各 + 0x5ED3, KANJI_STANDARD, // 廓 + 0x62E1, KANJI_STANDARD, // 拡 + 0x64B9, KANJI_STANDARD, // 撹 + 0x683C, KANJI_STANDARD, // æ Œ + 0x6838, KANJI_STANDARD, // æ ž + 0x6BBB, KANJI_STANDARD, // æ®» + 0x7372, KANJI_STANDARD, // 獲 + 0x78BA, KANJI_STANDARD, // 確 + 0x7A6B, KANJI_STANDARD, // ç©« + 0x899A, KANJI_STANDARD, // 芚 + 0x89D2, KANJI_STANDARD, // 角 + 0x8D6B, KANJI_STANDARD, // 赫 + 0x8F03, KANJI_STANDARD, // 范 + 0x90ED, KANJI_STANDARD, // 郭 + 0x95A3, KANJI_STANDARD, // 閣 + 0x9694, KANJI_STANDARD, // 隔 + 0x9769, KANJI_STANDARD, // 革 + 0x5B66, KANJI_STANDARD, // å­Š + 0x5CB3, KANJI_STANDARD, // å²³ + 0x697D, KANJI_STANDARD, // 楜 + 0x984D, KANJI_STANDARD, // 額 + 0x984E, KANJI_STANDARD, // 顎 + 0x639B, KANJI_STANDARD, // 掛 + 0x7B20, KANJI_STANDARD, // 笠 + 0x6A2B, KANJI_STANDARD, // æš« + 0x6A7F, KANJI_STANDARD, // æ©¿ + 0x68B6, KANJI_STANDARD, // 梶 + 0x9C0D, KANJI_STANDARD, // 鰍 + 0x6F5F, KANJI_STANDARD, // 期 + 0x5272, KANJI_STANDARD, // 割 + 0x559D, KANJI_STANDARD, // 喝 + 0x6070, KANJI_STANDARD, // 恰 + 0x62EC, KANJI_STANDARD, // 括 + 0x6D3B, KANJI_STANDARD, // 掻 + 0x6E07, KANJI_STANDARD, // 枇 + 0x6ED1, KANJI_STANDARD, // 滑 + 0x845B, KANJI_STANDARD, // 葛 + 0x8910, KANJI_STANDARD, // 耐 + 0x8F44, KANJI_STANDARD, // 蜄 + 0x4E14, KANJI_STANDARD, // 侔 + 0x9C39, KANJI_STANDARD, // é°¹ + 0x53F6, KANJI_STANDARD, // 叶 + 0x691B, KANJI_STANDARD, // 怛 + 0x6A3A, KANJI_STANDARD, // 暺 + 0x9784, KANJI_STANDARD, // 鞄 + 0x682A, KANJI_STANDARD, // æ ª + 0x515C, KANJI_STANDARD, // 兜 + 0x7AC3, KANJI_STANDARD, // 竃 + 0x84B2, KANJI_STANDARD, // 蒲 + 0x91DC, KANJI_STANDARD, // 釜 + 0x938C, KANJI_STANDARD, // 鎌 + 0x565B, KANJI_STANDARD, // 噛 + 0x9D28, KANJI_STANDARD, // 鎚 + 0x6822, KANJI_STANDARD, // æ ¢ + 0x8305, KANJI_STANDARD, // 茅 + 0x8431, KANJI_STANDARD, // 萱 + 0x7CA5, KANJI_STANDARD, // ç²¥ + 0x5208, KANJI_STANDARD, // 刈 + 0x82C5, KANJI_STANDARD, // 苅 + 0x74E6, KANJI_STANDARD, // 瓩 + 0x4E7E, KANJI_STANDARD, // 也 + 0x4F83, KANJI_STANDARD, // 䟃 + 0x51A0, KANJI_STANDARD, // 冠 + 0x5BD2, KANJI_STANDARD, // 寒 + 0x520A, KANJI_STANDARD, // 刊 + 0x52D8, KANJI_STANDARD, // 勘 + 0x52E7, KANJI_STANDARD, // 勧 + 0x5DFB, KANJI_STANDARD, // å·» + 0x559A, KANJI_STANDARD, // 喚 + 0x582A, KANJI_STANDARD, // å ª + 0x59E6, KANJI_STANDARD, // å§Š + 0x5B8C, KANJI_STANDARD, // 完 + 0x5B98, KANJI_STANDARD, // 官 + 0x5BDB, KANJI_STANDARD, // 寛 + 0x5E72, KANJI_STANDARD, // å¹² + 0x5E79, KANJI_STANDARD, // å¹¹ + 0x60A3, KANJI_STANDARD, // 患 + 0x611F, KANJI_STANDARD, // 感 + 0x6163, KANJI_STANDARD, // 慣 + 0x61BE, KANJI_STANDARD, // 憟 + 0x63DB, KANJI_STANDARD, // 換 + 0x6562, KANJI_STANDARD, // 敢 + 0x67D1, KANJI_STANDARD, // 柑 + 0x6853, KANJI_STANDARD, // 桓 + 0x68FA, KANJI_STANDARD, // 棺 + 0x6B3E, KANJI_STANDARD, // 欟 + 0x6B53, KANJI_STANDARD, // 歓 + 0x6C57, KANJI_STANDARD, // 汗 + 0x6F22, KANJI_STANDARD, // 挢 + 0x6F97, KANJI_STANDARD, // 柗 + 0x6F45, KANJI_STANDARD, // 朅 + 0x74B0, KANJI_STANDARD, // 環 + 0x7518, KANJI_STANDARD, // 甘 + 0x76E3, KANJI_STANDARD, // 監 + 0x770B, KANJI_STANDARD, // 看 + 0x7AFF, KANJI_STANDARD, // ç«¿ + 0x7BA1, KANJI_STANDARD, // 管 + 0x7C21, KANJI_STANDARD, // ç°¡ + 0x7DE9, KANJI_STANDARD, // ç·© + 0x7F36, KANJI_STANDARD, // 猶 + 0x7FF0, KANJI_STANDARD, // ç¿° + 0x809D, KANJI_STANDARD, // 肝 + 0x8266, KANJI_STANDARD, // 艊 + 0x839E, KANJI_STANDARD, // 莞 + 0x89B3, KANJI_STANDARD, // 芳 + 0x8ACC, KANJI_STANDARD, // 諌 + 0x8CAB, KANJI_STANDARD, // 貫 + 0x9084, KANJI_STANDARD, // 還 + 0x9451, KANJI_STANDARD, // 鑑 + 0x9593, KANJI_STANDARD, // 間 + 0x9591, KANJI_STANDARD, // 閑 + 0x95A2, KANJI_STANDARD, // 関 + 0x9665, KANJI_STANDARD, // 陥 + 0x97D3, KANJI_STANDARD, // 韓 + 0x9928, KANJI_STANDARD, // 通 + 0x8218, KANJI_STANDARD, // 舘 + 0x4E38, KANJI_STANDARD, // äžž + 0x542B, KANJI_STANDARD, // 含 + 0x5CB8, KANJI_STANDARD, // 岞 + 0x5DCC, KANJI_STANDARD, // 巌 + 0x73A9, KANJI_STANDARD, // 玩 + 0x764C, KANJI_STANDARD, // 癌 + 0x773C, KANJI_STANDARD, // 県 + 0x5CA9, KANJI_STANDARD, // 岩 + 0x7FEB, KANJI_STANDARD, // ç¿« + 0x8D0B, KANJI_STANDARD, // 莋 + 0x96C1, KANJI_STANDARD, // 雁 + 0x9811, KANJI_STANDARD, // 頑 + 0x9854, KANJI_STANDARD, // 顔 + 0x9858, KANJI_STANDARD, // 願 + 0x4F01, KANJI_STANDARD, // 䌁 + 0x4F0E, KANJI_STANDARD, // 䌎 + 0x5371, KANJI_STANDARD, // 危 + 0x559C, KANJI_STANDARD, // 喜 + 0x5668, KANJI_STANDARD, // 噚 + 0x57FA, KANJI_STANDARD, // 基 + 0x5947, KANJI_STANDARD, // 奇 + 0x5B09, KANJI_STANDARD, // 嬉 + 0x5BC4, KANJI_STANDARD, // 寄 + 0x5C90, KANJI_STANDARD, // 岐 + 0x5E0C, KANJI_STANDARD, // 垌 + 0x5E7E, KANJI_STANDARD, // 幟 + 0x5FCC, KANJI_STANDARD, // 忌 + 0x63EE, KANJI_STANDARD, // 揮 + 0x673A, KANJI_STANDARD, // 机 + 0x65D7, KANJI_STANDARD, // 旗 + 0x65E2, KANJI_STANDARD, // 既 + 0x671F, KANJI_STANDARD, // 期 + 0x68CB, KANJI_STANDARD, // 棋 + 0x68C4, KANJI_STANDARD, // 棄 + 0x6A5F, KANJI_STANDARD, // 機 + 0x5E30, KANJI_STANDARD, // åž° + 0x6BC5, KANJI_STANDARD, // 毅 + 0x6C17, KANJI_STANDARD, // 気 + 0x6C7D, KANJI_STANDARD, // 汜 + 0x757F, KANJI_STANDARD, // 畿 + 0x7948, KANJI_STANDARD, // 祈 + 0x5B63, KANJI_STANDARD, // å­£ + 0x7A00, KANJI_STANDARD, // 繀 + 0x7D00, KANJI_STANDARD, // 简 + 0x5FBD, KANJI_STANDARD, // 埜 + 0x898F, KANJI_STANDARD, // 芏 + 0x8A18, KANJI_STANDARD, // 蚘 + 0x8CB4, KANJI_STANDARD, // 貎 + 0x8D77, KANJI_STANDARD, // èµ· + 0x8ECC, KANJI_STANDARD, // 軌 + 0x8F1D, KANJI_STANDARD, // 茝 + 0x98E2, KANJI_STANDARD, // 飢 + 0x9A0E, KANJI_STANDARD, // 階 + 0x9B3C, KANJI_STANDARD, // 鬌 + 0x4E80, KANJI_STANDARD, // 亀 + 0x507D, KANJI_STANDARD, // 停 + 0x5100, KANJI_STANDARD, // 儀 + 0x5993, KANJI_STANDARD, // 劓 + 0x5B9C, KANJI_STANDARD, // 宜 + 0x622F, KANJI_STANDARD, // 戯 + 0x6280, KANJI_STANDARD, // 技 + 0x64EC, KANJI_STANDARD, // 擬 + 0x6B3A, KANJI_STANDARD, // 欺 + 0x72A0, KANJI_STANDARD, // 犠 + 0x7591, KANJI_STANDARD, // 疑 + 0x7947, KANJI_STANDARD, // 祇 + 0x7FA9, KANJI_STANDARD, // 矩 + 0x87FB, KANJI_STANDARD, // 蟻 + 0x8ABC, KANJI_STANDARD, // 誌 + 0x8B70, KANJI_STANDARD, // è­° + 0x63AC, KANJI_STANDARD, // 掬 + 0x83CA, KANJI_STANDARD, // 菊 + 0x97A0, KANJI_STANDARD, // 鞠 + 0x5409, KANJI_STANDARD, // 吉 + 0x5403, KANJI_STANDARD, // 吃 + 0x55AB, KANJI_STANDARD, // 喫 + 0x6854, KANJI_STANDARD, // 桔 + 0x6A58, KANJI_STANDARD, // 橘 + 0x8A70, KANJI_STANDARD, // è©° + 0x7827, KANJI_STANDARD, // ç § + 0x6775, KANJI_STANDARD, // 杵 + 0x9ECD, KANJI_STANDARD, // 黍 + 0x5374, KANJI_STANDARD, // 华 + 0x5BA2, KANJI_STANDARD, // 客 + 0x811A, KANJI_STANDARD, // 脚 + 0x8650, KANJI_STANDARD, // 虐 + 0x9006, KANJI_STANDARD, // 逆 + 0x4E18, KANJI_STANDARD, // 䞘 + 0x4E45, KANJI_STANDARD, // 久 + 0x4EC7, KANJI_STANDARD, // 仇 + 0x4F11, KANJI_STANDARD, // 䌑 + 0x53CA, KANJI_STANDARD, // 及 + 0x5438, KANJI_STANDARD, // 吞 + 0x5BAE, KANJI_STANDARD, // å®® + 0x5F13, KANJI_STANDARD, // 匓 + 0x6025, KANJI_STANDARD, // 急 + 0x6551, KANJI_STANDARD, // 救 + 0x673D, KANJI_STANDARD, // 朜 + 0x6C42, KANJI_STANDARD, // 求 + 0x6C72, KANJI_STANDARD, // æ±² + 0x6CE3, KANJI_STANDARD, // æ³£ + 0x7078, KANJI_STANDARD, // 灞 + 0x7403, KANJI_STANDARD, // 球 + 0x7A76, KANJI_STANDARD, // ç©¶ + 0x7AAE, KANJI_STANDARD, // 窮 + 0x7B08, KANJI_STANDARD, // 笈 + 0x7D1A, KANJI_STANDARD, // 箚 + 0x7CFE, KANJI_STANDARD, // 糟 + 0x7D66, KANJI_STANDARD, // 絊 + 0x65E7, KANJI_STANDARD, // 旧 + 0x725B, KANJI_STANDARD, // 牛 + 0x53BB, KANJI_STANDARD, // 去 + 0x5C45, KANJI_STANDARD, // 居 + 0x5DE8, KANJI_STANDARD, // å·š + 0x62D2, KANJI_STANDARD, // 拒 + 0x62E0, KANJI_STANDARD, // 拠 + 0x6319, KANJI_STANDARD, // 挙 + 0x6E20, KANJI_STANDARD, // æž  + 0x865A, KANJI_STANDARD, // 虚 + 0x8A31, KANJI_STANDARD, // èš± + 0x8DDD, KANJI_STANDARD, // 距 + 0x92F8, KANJI_STANDARD, // 鋾 + 0x6F01, KANJI_STANDARD, // 持 + 0x79A6, KANJI_STANDARD, // 犊 + 0x9B5A, KANJI_STANDARD, // 魚 + 0x4EA8, KANJI_STANDARD, // 亚 + 0x4EAB, KANJI_STANDARD, // 享 + 0x4EAC, KANJI_STANDARD, // 京 + 0x4F9B, KANJI_STANDARD, // 䟛 + 0x4FA0, KANJI_STANDARD, // 䟠 + 0x50D1, KANJI_STANDARD, // 僑 + 0x5147, KANJI_STANDARD, // 兇 + 0x7AF6, KANJI_STANDARD, // ç«¶ + 0x5171, KANJI_STANDARD, // 共 + 0x51F6, KANJI_STANDARD, // 凶 + 0x5354, KANJI_STANDARD, // 協 + 0x5321, KANJI_STANDARD, // 匡 + 0x537F, KANJI_STANDARD, // 卿 + 0x53EB, KANJI_STANDARD, // 叫 + 0x55AC, KANJI_STANDARD, // 喬 + 0x5883, KANJI_STANDARD, // 境 + 0x5CE1, KANJI_STANDARD, // 峡 + 0x5F37, KANJI_STANDARD, // 匷 + 0x5F4A, KANJI_STANDARD, // 圊 + 0x602F, KANJI_STANDARD, // 怯 + 0x6050, KANJI_STANDARD, // 恐 + 0x606D, KANJI_STANDARD, // 恭 + 0x631F, KANJI_STANDARD, // 挟 + 0x6559, KANJI_STANDARD, // 教 + 0x6A4B, KANJI_STANDARD, // 橋 + 0x6CC1, KANJI_STANDARD, // 況 + 0x72C2, KANJI_STANDARD, // 狂 + 0x72ED, KANJI_STANDARD, // 狭 + 0x77EF, KANJI_STANDARD, // 矯 + 0x80F8, KANJI_STANDARD, // 胞 + 0x8105, KANJI_STANDARD, // 脅 + 0x8208, KANJI_STANDARD, // 興 + 0x854E, KANJI_STANDARD, // 蕎 + 0x90F7, KANJI_STANDARD, // 郷 + 0x93E1, KANJI_STANDARD, // 鏡 + 0x97FF, KANJI_STANDARD, // 響 + 0x9957, KANJI_STANDARD, // 饗 + 0x9A5A, KANJI_STANDARD, // 驚 + 0x4EF0, KANJI_STANDARD, // ä»° + 0x51DD, KANJI_STANDARD, // 凝 + 0x5C2D, KANJI_STANDARD, // å°­ + 0x6681, KANJI_STANDARD, // 暁 + 0x696D, KANJI_STANDARD, // 業 + 0x5C40, KANJI_STANDARD, // 局 + 0x66F2, KANJI_STANDARD, // 曲 + 0x6975, KANJI_STANDARD, // 極 + 0x7389, KANJI_STANDARD, // 玉 + 0x6850, KANJI_STANDARD, // 桐 + 0x7C81, KANJI_STANDARD, // 粁 + 0x50C5, KANJI_STANDARD, // 僅 + 0x52E4, KANJI_STANDARD, // å‹€ + 0x5747, KANJI_STANDARD, // 均 + 0x5DFE, KANJI_STANDARD, // å·Ÿ + 0x9326, KANJI_STANDARD, // 錩 + 0x65A4, KANJI_STANDARD, // æ–€ + 0x6B23, KANJI_STANDARD, // 欣 + 0x6B3D, KANJI_STANDARD, // 欜 + 0x7434, KANJI_STANDARD, // 琎 + 0x7981, KANJI_STANDARD, // 犁 + 0x79BD, KANJI_STANDARD, // 犜 + 0x7B4B, KANJI_STANDARD, // 筋 + 0x7DCA, KANJI_STANDARD, // 緊 + 0x82B9, KANJI_STANDARD, // 芹 + 0x83CC, KANJI_STANDARD, // 菌 + 0x887F, KANJI_STANDARD, // è¡¿ + 0x895F, KANJI_STANDARD, // 襟 + 0x8B39, KANJI_STANDARD, // 謹 + 0x8FD1, KANJI_STANDARD, // 近 + 0x91D1, KANJI_STANDARD, // 金 + 0x541F, KANJI_STANDARD, // 吟 + 0x9280, KANJI_STANDARD, // 銀 + 0x4E5D, KANJI_STANDARD, // 九 + 0x5036, KANJI_STANDARD, // 倶 + 0x53E5, KANJI_STANDARD, // 句 + 0x533A, KANJI_STANDARD, // 区 + 0x72D7, KANJI_STANDARD, // 狗 + 0x7396, KANJI_STANDARD, // 玖 + 0x77E9, KANJI_STANDARD, // 矩 + 0x82E6, KANJI_STANDARD, // 苊 + 0x8EAF, KANJI_STANDARD, // 躯 + 0x99C6, KANJI_STANDARD, // 駆 + 0x99C8, KANJI_STANDARD, // 駈 + 0x99D2, KANJI_STANDARD, // 駒 + 0x5177, KANJI_STANDARD, // 具 + 0x611A, KANJI_STANDARD, // 愚 + 0x865E, KANJI_STANDARD, // 虞 + 0x55B0, KANJI_STANDARD, // 喰 + 0x7A7A, KANJI_STANDARD, // 空 + 0x5076, KANJI_STANDARD, // 偶 + 0x5BD3, KANJI_STANDARD, // 寓 + 0x9047, KANJI_STANDARD, // 遇 + 0x9685, KANJI_STANDARD, // 隅 + 0x4E32, KANJI_STANDARD, // äž² + 0x6ADB, KANJI_STANDARD, // 櫛 + 0x91E7, KANJI_STANDARD, // 釧 + 0x5C51, KANJI_STANDARD, // 屑 + 0x5C48, KANJI_STANDARD, // 屈 + 0x6398, KANJI_STANDARD, // 掘 + 0x7A9F, KANJI_STANDARD, // 窟 + 0x6C93, KANJI_STANDARD, // 沓 + 0x9774, KANJI_STANDARD, // 靎 + 0x8F61, KANJI_STANDARD, // 蜡 + 0x7AAA, KANJI_STANDARD, // 窪 + 0x718A, KANJI_STANDARD, // 熊 + 0x9688, KANJI_STANDARD, // 隈 + 0x7C82, KANJI_STANDARD, // 粂 + 0x6817, KANJI_STANDARD, // 栗 + 0x7E70, KANJI_STANDARD, // ç¹° + 0x6851, KANJI_STANDARD, // 桑 + 0x936C, KANJI_STANDARD, // 鍬 + 0x52F2, KANJI_STANDARD, // 勲 + 0x541B, KANJI_STANDARD, // 君 + 0x85AB, KANJI_STANDARD, // 薫 + 0x8A13, KANJI_STANDARD, // èš“ + 0x7FA4, KANJI_STANDARD, // 矀 + 0x8ECD, KANJI_STANDARD, // 軍 + 0x90E1, KANJI_STANDARD, // 郡 + 0x5366, KANJI_STANDARD, // 半 + 0x8888, KANJI_STANDARD, // 袈 + 0x7941, KANJI_STANDARD, // 祁 + 0x4FC2, KANJI_STANDARD, // 係 + 0x50BE, KANJI_STANDARD, // 傟 + 0x5211, KANJI_STANDARD, // 刑 + 0x5144, KANJI_STANDARD, // 兄 + 0x5553, KANJI_STANDARD, // 啓 + 0x572D, KANJI_STANDARD, // 圭 + 0x73EA, KANJI_STANDARD, // 珪 + 0x578B, KANJI_STANDARD, // 型 + 0x5951, KANJI_STANDARD, // 契 + 0x5F62, KANJI_STANDARD, // 圢 + 0x5F84, KANJI_STANDARD, // 埄 + 0x6075, KANJI_STANDARD, // 恵 + 0x6176, KANJI_STANDARD, // 慶 + 0x6167, KANJI_STANDARD, // 慧 + 0x61A9, KANJI_STANDARD, // 憩 + 0x63B2, KANJI_STANDARD, // 掲 + 0x643A, KANJI_STANDARD, // 携 + 0x656C, KANJI_STANDARD, // 敬 + 0x666F, KANJI_STANDARD, // 景 + 0x6842, KANJI_STANDARD, // 桂 + 0x6E13, KANJI_STANDARD, // æž“ + 0x7566, KANJI_STANDARD, // 畩 + 0x7A3D, KANJI_STANDARD, // çšœ + 0x7CFB, KANJI_STANDARD, // ç³» + 0x7D4C, KANJI_STANDARD, // 経 + 0x7D99, KANJI_STANDARD, // 継 + 0x7E4B, KANJI_STANDARD, // 繋 + 0x7F6B, KANJI_STANDARD, // 眫 + 0x830E, KANJI_STANDARD, // 茎 + 0x834A, KANJI_STANDARD, // 荊 + 0x86CD, KANJI_STANDARD, // 蛍 + 0x8A08, KANJI_STANDARD, // 蚈 + 0x8A63, KANJI_STANDARD, // è©£ + 0x8B66, KANJI_STANDARD, // è­Š + 0x8EFD, KANJI_STANDARD, // 軜 + 0x981A, KANJI_STANDARD, // 頚 + 0x9D8F, KANJI_STANDARD, // 鶏 + 0x82B8, KANJI_STANDARD, // 芞 + 0x8FCE, KANJI_STANDARD, // 迎 + 0x9BE8, KANJI_STANDARD, // 鯚 + 0x5287, KANJI_STANDARD, // 劇 + 0x621F, KANJI_STANDARD, // 戟 + 0x6483, KANJI_STANDARD, // 撃 + 0x6FC0, KANJI_STANDARD, // 激 + 0x9699, KANJI_STANDARD, // 隙 + 0x6841, KANJI_STANDARD, // 桁 + 0x5091, KANJI_STANDARD, // 傑 + 0x6B20, KANJI_STANDARD, // 欠 + 0x6C7A, KANJI_STANDARD, // 決 + 0x6F54, KANJI_STANDARD, // 朔 + 0x7A74, KANJI_STANDARD, // 穎 + 0x7D50, KANJI_STANDARD, // 結 + 0x8840, KANJI_STANDARD, // 血 + 0x8A23, KANJI_STANDARD, // 蚣 + 0x6708, KANJI_STANDARD, // 月 + 0x4EF6, KANJI_STANDARD, // ä»¶ + 0x5039, KANJI_STANDARD, // 倹 + 0x5026, KANJI_STANDARD, // 倊 + 0x5065, KANJI_STANDARD, // 健 + 0x517C, KANJI_STANDARD, // å…Œ + 0x5238, KANJI_STANDARD, // 刞 + 0x5263, KANJI_STANDARD, // 剣 + 0x55A7, KANJI_STANDARD, // 喧 + 0x570F, KANJI_STANDARD, // 圏 + 0x5805, KANJI_STANDARD, // 堅 + 0x5ACC, KANJI_STANDARD, // 嫌 + 0x5EFA, KANJI_STANDARD, // 建 + 0x61B2, KANJI_STANDARD, // 憲 + 0x61F8, KANJI_STANDARD, // 懞 + 0x62F3, KANJI_STANDARD, // 拳 + 0x6372, KANJI_STANDARD, // 捲 + 0x691C, KANJI_STANDARD, // 怜 + 0x6A29, KANJI_STANDARD, // æš© + 0x727D, KANJI_STANDARD, // 牜 + 0x72AC, KANJI_STANDARD, // 犬 + 0x732E, KANJI_STANDARD, // 献 + 0x7814, KANJI_STANDARD, // 研 + 0x786F, KANJI_STANDARD, // 硯 + 0x7D79, KANJI_STANDARD, // çµ¹ + 0x770C, KANJI_STANDARD, // 県 + 0x80A9, KANJI_STANDARD, // 肩 + 0x898B, KANJI_STANDARD, // 芋 + 0x8B19, KANJI_STANDARD, // 謙 + 0x8CE2, KANJI_STANDARD, // è³¢ + 0x8ED2, KANJI_STANDARD, // 軒 + 0x9063, KANJI_STANDARD, // 遣 + 0x9375, KANJI_STANDARD, // 鍵 + 0x967A, KANJI_STANDARD, // 険 + 0x9855, KANJI_STANDARD, // 顕 + 0x9A13, KANJI_STANDARD, // 鹓 + 0x9E78, KANJI_STANDARD, // 鹞 + 0x5143, KANJI_STANDARD, // 元 + 0x539F, KANJI_STANDARD, // 原 + 0x53B3, KANJI_STANDARD, // 厳 + 0x5E7B, KANJI_STANDARD, // å¹» + 0x5F26, KANJI_STANDARD, // 匊 + 0x6E1B, KANJI_STANDARD, // æž› + 0x6E90, KANJI_STANDARD, // 源 + 0x7384, KANJI_STANDARD, // 玄 + 0x73FE, KANJI_STANDARD, // 珟 + 0x7D43, KANJI_STANDARD, // 絃 + 0x8237, KANJI_STANDARD, // 舷 + 0x8A00, KANJI_STANDARD, // 蚀 + 0x8AFA, KANJI_STANDARD, // 諺 + 0x9650, KANJI_STANDARD, // 限 + 0x4E4E, KANJI_STANDARD, // 乎 + 0x500B, KANJI_STANDARD, // 個 + 0x53E4, KANJI_STANDARD, // 叀 + 0x547C, KANJI_STANDARD, // 呌 + 0x56FA, KANJI_STANDARD, // 固 + 0x59D1, KANJI_STANDARD, // 姑 + 0x5B64, KANJI_STANDARD, // å­€ + 0x5DF1, KANJI_STANDARD, // å·± + 0x5EAB, KANJI_STANDARD, // 庫 + 0x5F27, KANJI_STANDARD, // 匧 + 0x6238, KANJI_STANDARD, // 戞 + 0x6545, KANJI_STANDARD, // 故 + 0x67AF, KANJI_STANDARD, // 枯 + 0x6E56, KANJI_STANDARD, // 湖 + 0x72D0, KANJI_STANDARD, // 狐 + 0x7CCA, KANJI_STANDARD, // 糊 + 0x88B4, KANJI_STANDARD, // 袎 + 0x80A1, KANJI_STANDARD, // 股 + 0x80E1, KANJI_STANDARD, // 胡 + 0x83F0, KANJI_STANDARD, // 菰 + 0x864E, KANJI_STANDARD, // 虎 + 0x8A87, KANJI_STANDARD, // 誇 + 0x8DE8, KANJI_STANDARD, // è·š + 0x9237, KANJI_STANDARD, // 鈷 + 0x96C7, KANJI_STANDARD, // 雇 + 0x9867, KANJI_STANDARD, // é¡§ + 0x9F13, KANJI_STANDARD, // 錓 + 0x4E94, KANJI_STANDARD, // 五 + 0x4E92, KANJI_STANDARD, // 互 + 0x4F0D, KANJI_STANDARD, // 䌍 + 0x5348, KANJI_STANDARD, // 午 + 0x5449, KANJI_STANDARD, // 呉 + 0x543E, KANJI_STANDARD, // 吟 + 0x5A2F, KANJI_STANDARD, // 嚯 + 0x5F8C, KANJI_STANDARD, // 埌 + 0x5FA1, KANJI_STANDARD, // 埡 + 0x609F, KANJI_STANDARD, // 悟 + 0x68A7, KANJI_STANDARD, // 梧 + 0x6A8E, KANJI_STANDARD, // 檎 + 0x745A, KANJI_STANDARD, // 瑚 + 0x7881, KANJI_STANDARD, // 碁 + 0x8A9E, KANJI_STANDARD, // 語 + 0x8AA4, KANJI_STANDARD, // 誀 + 0x8B77, KANJI_STANDARD, // è­· + 0x9190, KANJI_STANDARD, // 醐 + 0x4E5E, KANJI_STANDARD, // 乞 + 0x9BC9, KANJI_STANDARD, // 鯉 + 0x4EA4, KANJI_STANDARD, // 亀 + 0x4F7C, KANJI_STANDARD, // 䜌 + 0x4FAF, KANJI_STANDARD, // 䟯 + 0x5019, KANJI_STANDARD, // 候 + 0x5016, KANJI_STANDARD, // 倖 + 0x5149, KANJI_STANDARD, // 光 + 0x516C, KANJI_STANDARD, // 公 + 0x529F, KANJI_STANDARD, // 功 + 0x52B9, KANJI_STANDARD, // 効 + 0x52FE, KANJI_STANDARD, // 募 + 0x539A, KANJI_STANDARD, // 厚 + 0x53E3, KANJI_STANDARD, // 口 + 0x5411, KANJI_STANDARD, // 向 + 0x540E, KANJI_STANDARD, // 后 + 0x5589, KANJI_STANDARD, // 喉 + 0x5751, KANJI_STANDARD, // 坑 + 0x57A2, KANJI_STANDARD, // 垢 + 0x597D, KANJI_STANDARD, // 奜 + 0x5B54, KANJI_STANDARD, // 孔 + 0x5B5D, KANJI_STANDARD, // 孝 + 0x5B8F, KANJI_STANDARD, // 宏 + 0x5DE5, KANJI_STANDARD, // å·¥ + 0x5DE7, KANJI_STANDARD, // å·§ + 0x5DF7, KANJI_STANDARD, // å·· + 0x5E78, KANJI_STANDARD, // 幞 + 0x5E83, KANJI_STANDARD, // 広 + 0x5E9A, KANJI_STANDARD, // 庚 + 0x5EB7, KANJI_STANDARD, // 康 + 0x5F18, KANJI_STANDARD, // 匘 + 0x6052, KANJI_STANDARD, // 恒 + 0x614C, KANJI_STANDARD, // 慌 + 0x6297, KANJI_STANDARD, // 抗 + 0x62D8, KANJI_STANDARD, // 拘 + 0x63A7, KANJI_STANDARD, // 控 + 0x653B, KANJI_STANDARD, // 攻 + 0x6602, KANJI_STANDARD, // 昂 + 0x6643, KANJI_STANDARD, // 晃 + 0x66F4, KANJI_STANDARD, // 曎 + 0x676D, KANJI_STANDARD, // 杭 + 0x6821, KANJI_STANDARD, // æ ¡ + 0x6897, KANJI_STANDARD, // 梗 + 0x69CB, KANJI_STANDARD, // 構 + 0x6C5F, KANJI_STANDARD, // 江 + 0x6D2A, KANJI_STANDARD, // 措 + 0x6D69, KANJI_STANDARD, // 浩 + 0x6E2F, KANJI_STANDARD, // 枯 + 0x6E9D, KANJI_STANDARD, // 溝 + 0x7532, KANJI_STANDARD, // 甲 + 0x7687, KANJI_STANDARD, // 皇 + 0x786C, KANJI_STANDARD, // 硬 + 0x7A3F, KANJI_STANDARD, // çš¿ + 0x7CE0, KANJI_STANDARD, // ç³  + 0x7D05, KANJI_STANDARD, // 箅 + 0x7D18, KANJI_STANDARD, // 玘 + 0x7D5E, KANJI_STANDARD, // 絞 + 0x7DB1, KANJI_STANDARD, // ç¶± + 0x8015, KANJI_STANDARD, // 耕 + 0x8003, KANJI_STANDARD, // 考 + 0x80AF, KANJI_STANDARD, // 肯 + 0x80B1, KANJI_STANDARD, // 肱 + 0x8154, KANJI_STANDARD, // 腔 + 0x818F, KANJI_STANDARD, // 膏 + 0x822A, KANJI_STANDARD, // 航 + 0x8352, KANJI_STANDARD, // 荒 + 0x884C, KANJI_STANDARD, // 行 + 0x8861, KANJI_STANDARD, // è¡¡ + 0x8B1B, KANJI_STANDARD, // 講 + 0x8CA2, KANJI_STANDARD, // è²¢ + 0x8CFC, KANJI_STANDARD, // 賌 + 0x90CA, KANJI_STANDARD, // 郊 + 0x9175, KANJI_STANDARD, // 酵 + 0x9271, KANJI_STANDARD, // 鉱 + 0x783F, KANJI_STANDARD, // ç ¿ + 0x92FC, KANJI_STANDARD, // 鋌 + 0x95A4, KANJI_STANDARD, // é–€ + 0x964D, KANJI_STANDARD, // 降 + 0x9805, KANJI_STANDARD, // 項 + 0x9999, KANJI_STANDARD, // 驙 + 0x9AD8, KANJI_STANDARD, // 高 + 0x9D3B, KANJI_STANDARD, // 鎻 + 0x525B, KANJI_STANDARD, // 剛 + 0x52AB, KANJI_STANDARD, // 劫 + 0x53F7, KANJI_STANDARD, // 号 + 0x5408, KANJI_STANDARD, // 合 + 0x58D5, KANJI_STANDARD, // 壕 + 0x62F7, KANJI_STANDARD, // 拷 + 0x6FE0, KANJI_STANDARD, // æ¿  + 0x8C6A, KANJI_STANDARD, // 豪 + 0x8F5F, KANJI_STANDARD, // 蜟 + 0x9EB9, KANJI_STANDARD, // 麹 + 0x514B, KANJI_STANDARD, // 克 + 0x523B, KANJI_STANDARD, // 刻 + 0x544A, KANJI_STANDARD, // 告 + 0x56FD, KANJI_STANDARD, // 囜 + 0x7A40, KANJI_STANDARD, // 穀 + 0x9177, KANJI_STANDARD, // 酷 + 0x9D60, KANJI_STANDARD, // éµ  + 0x9ED2, KANJI_STANDARD, // 黒 + 0x7344, KANJI_STANDARD, // 獄 + 0x6F09, KANJI_STANDARD, // 按 + 0x8170, KANJI_STANDARD, // 腰 + 0x7511, KANJI_STANDARD, // 甑 + 0x5FFD, KANJI_STANDARD, // 応 + 0x60DA, KANJI_STANDARD, // 惚 + 0x9AA8, KANJI_STANDARD, // 骚 + 0x72DB, KANJI_STANDARD, // 狛 + 0x8FBC, KANJI_STANDARD, // 蟌 + 0x6B64, KANJI_STANDARD, // æ­€ + 0x9803, KANJI_STANDARD, // 頃 + 0x4ECA, KANJI_STANDARD, // 今 + 0x56F0, KANJI_STANDARD, // 困 + 0x5764, KANJI_STANDARD, // 址 + 0x58BE, KANJI_STANDARD, // 墟 + 0x5A5A, KANJI_STANDARD, // 婚 + 0x6068, KANJI_STANDARD, // 恚 + 0x61C7, KANJI_STANDARD, // 懇 + 0x660F, KANJI_STANDARD, // 昏 + 0x6606, KANJI_STANDARD, // 昆 + 0x6839, KANJI_STANDARD, // æ ¹ + 0x68B1, KANJI_STANDARD, // 梱 + 0x6DF7, KANJI_STANDARD, // æ·· + 0x75D5, KANJI_STANDARD, // 痕 + 0x7D3A, KANJI_STANDARD, // 玺 + 0x826E, KANJI_STANDARD, // 艮 + 0x9B42, KANJI_STANDARD, // 魂 + 0x4E9B, KANJI_STANDARD, // 些 + 0x4F50, KANJI_STANDARD, // 䜐 + 0x53C9, KANJI_STANDARD, // 叉 + 0x5506, KANJI_STANDARD, // 唆 + 0x5D6F, KANJI_STANDARD, // 嵯 + 0x5DE6, KANJI_STANDARD, // å·Š + 0x5DEE, KANJI_STANDARD, // å·® + 0x67FB, KANJI_STANDARD, // 査 + 0x6C99, KANJI_STANDARD, // 沙 + 0x7473, KANJI_STANDARD, // 瑳 + 0x7802, KANJI_STANDARD, // 砂 + 0x8A50, KANJI_STANDARD, // 詐 + 0x9396, KANJI_STANDARD, // 鎖 + 0x88DF, KANJI_STANDARD, // 裟 + 0x5750, KANJI_STANDARD, // 坐 + 0x5EA7, KANJI_STANDARD, // 座 + 0x632B, KANJI_STANDARD, // 挫 + 0x50B5, KANJI_STANDARD, // 債 + 0x50AC, KANJI_STANDARD, // 催 + 0x518D, KANJI_STANDARD, // 再 + 0x6700, KANJI_STANDARD, // 最 + 0x54C9, KANJI_STANDARD, // 哉 + 0x585E, KANJI_STANDARD, // 塞 + 0x59BB, KANJI_STANDARD, // 劻 + 0x5BB0, KANJI_STANDARD, // å®° + 0x5F69, KANJI_STANDARD, // 圩 + 0x624D, KANJI_STANDARD, // 才 + 0x63A1, KANJI_STANDARD, // 採 + 0x683D, KANJI_STANDARD, // æ œ + 0x6B73, KANJI_STANDARD, // æ­³ + 0x6E08, KANJI_STANDARD, // 枈 + 0x707D, KANJI_STANDARD, // 灜 + 0x91C7, KANJI_STANDARD, // 采 + 0x7280, KANJI_STANDARD, // 犀 + 0x7815, KANJI_STANDARD, // 砕 + 0x7826, KANJI_STANDARD, // ç Š + 0x796D, KANJI_STANDARD, // 祭 + 0x658E, KANJI_STANDARD, // 斎 + 0x7D30, KANJI_STANDARD, // 现 + 0x83DC, KANJI_STANDARD, // 菜 + 0x88C1, KANJI_STANDARD, // 裁 + 0x8F09, KANJI_STANDARD, // 茉 + 0x969B, KANJI_STANDARD, // 際 + 0x5264, KANJI_STANDARD, // 剀 + 0x5728, KANJI_STANDARD, // 圚 + 0x6750, KANJI_STANDARD, // 材 + 0x7F6A, KANJI_STANDARD, // 眪 + 0x8CA1, KANJI_STANDARD, // 財 + 0x51B4, KANJI_STANDARD, // 冎 + 0x5742, KANJI_STANDARD, // 坂 + 0x962A, KANJI_STANDARD, // 阪 + 0x583A, KANJI_STANDARD, // å º + 0x698A, KANJI_STANDARD, // 把 + 0x80B4, KANJI_STANDARD, // 肎 + 0x54B2, KANJI_STANDARD, // 咲 + 0x5D0E, KANJI_STANDARD, // 厎 + 0x57FC, KANJI_STANDARD, // 埌 + 0x7895, KANJI_STANDARD, // 碕 + 0x9DFA, KANJI_STANDARD, // é·º + 0x4F5C, KANJI_STANDARD, // 䜜 + 0x524A, KANJI_STANDARD, // 削 + 0x548B, KANJI_STANDARD, // 咋 + 0x643E, KANJI_STANDARD, // 搟 + 0x6628, KANJI_STANDARD, // 昚 + 0x6714, KANJI_STANDARD, // 朔 + 0x67F5, KANJI_STANDARD, // 柵 + 0x7A84, KANJI_STANDARD, // 窄 + 0x7B56, KANJI_STANDARD, // 策 + 0x7D22, KANJI_STANDARD, // 玢 + 0x932F, KANJI_STANDARD, // 錯 + 0x685C, KANJI_STANDARD, // 桜 + 0x9BAD, KANJI_STANDARD, // é®­ + 0x7B39, KANJI_STANDARD, // 笹 + 0x5319, KANJI_STANDARD, // 匙 + 0x518A, KANJI_STANDARD, // 冊 + 0x5237, KANJI_STANDARD, // 刷 + 0x5BDF, KANJI_STANDARD, // 察 + 0x62F6, KANJI_STANDARD, // 拶 + 0x64AE, KANJI_STANDARD, // 撮 + 0x64E6, KANJI_STANDARD, // 擊 + 0x672D, KANJI_STANDARD, // 札 + 0x6BBA, KANJI_STANDARD, // 殺 + 0x85A9, KANJI_STANDARD, // 薩 + 0x96D1, KANJI_STANDARD, // 雑 + 0x7690, KANJI_STANDARD, // 皐 + 0x9BD6, KANJI_STANDARD, // 鯖 + 0x634C, KANJI_STANDARD, // 捌 + 0x9306, KANJI_STANDARD, // 錆 + 0x9BAB, KANJI_STANDARD, // 鮫 + 0x76BF, KANJI_STANDARD, // 皿 + 0x6652, KANJI_STANDARD, // 晒 + 0x4E09, KANJI_STANDARD, // 侉 + 0x5098, KANJI_STANDARD, // 傘 + 0x53C2, KANJI_STANDARD, // 参 + 0x5C71, KANJI_STANDARD, // å±± + 0x60E8, KANJI_STANDARD, // 惚 + 0x6492, KANJI_STANDARD, // 撒 + 0x6563, KANJI_STANDARD, // 散 + 0x685F, KANJI_STANDARD, // 桟 + 0x71E6, KANJI_STANDARD, // 燩 + 0x73CA, KANJI_STANDARD, // 珊 + 0x7523, KANJI_STANDARD, // 産 + 0x7B97, KANJI_STANDARD, // 算 + 0x7E82, KANJI_STANDARD, // 纂 + 0x8695, KANJI_STANDARD, // 蚕 + 0x8B83, KANJI_STANDARD, // 讃 + 0x8CDB, KANJI_STANDARD, // 賛 + 0x9178, KANJI_STANDARD, // 酾 + 0x9910, KANJI_STANDARD, // 逐 + 0x65AC, KANJI_STANDARD, // 斬 + 0x66AB, KANJI_STANDARD, // 暫 + 0x6B8B, KANJI_STANDARD, // 残 + 0x4ED5, KANJI_STANDARD, // 仕 + 0x4ED4, KANJI_STANDARD, // 仔 + 0x4F3A, KANJI_STANDARD, // 䌺 + 0x4F7F, KANJI_STANDARD, // 䜿 + 0x523A, KANJI_STANDARD, // 刺 + 0x53F8, KANJI_STANDARD, // 叞 + 0x53F2, KANJI_STANDARD, // 史 + 0x55E3, KANJI_STANDARD, // 嗣 + 0x56DB, KANJI_STANDARD, // 四 + 0x58EB, KANJI_STANDARD, // 士 + 0x59CB, KANJI_STANDARD, // 始 + 0x59C9, KANJI_STANDARD, // 姉 + 0x59FF, KANJI_STANDARD, // å§¿ + 0x5B50, KANJI_STANDARD, // 子 + 0x5C4D, KANJI_STANDARD, // 屍 + 0x5E02, KANJI_STANDARD, // åž‚ + 0x5E2B, KANJI_STANDARD, // åž« + 0x5FD7, KANJI_STANDARD, // 志 + 0x601D, KANJI_STANDARD, // 思 + 0x6307, KANJI_STANDARD, // 指 + 0x652F, KANJI_STANDARD, // 支 + 0x5B5C, KANJI_STANDARD, // 孜 + 0x65AF, KANJI_STANDARD, // 斯 + 0x65BD, KANJI_STANDARD, // æ–œ + 0x65E8, KANJI_STANDARD, // æ—š + 0x679D, KANJI_STANDARD, // 枝 + 0x6B62, KANJI_STANDARD, // æ­¢ + 0x6B7B, KANJI_STANDARD, // æ­» + 0x6C0F, KANJI_STANDARD, // 氏 + 0x7345, KANJI_STANDARD, // 獅 + 0x7949, KANJI_STANDARD, // 祉 + 0x79C1, KANJI_STANDARD, // 私 + 0x7CF8, KANJI_STANDARD, // 糞 + 0x7D19, KANJI_STANDARD, // 箙 + 0x7D2B, KANJI_STANDARD, // 玫 + 0x80A2, KANJI_STANDARD, // 肢 + 0x8102, KANJI_STANDARD, // 脂 + 0x81F3, KANJI_STANDARD, // 至 + 0x8996, KANJI_STANDARD, // 芖 + 0x8A5E, KANJI_STANDARD, // 詞 + 0x8A69, KANJI_STANDARD, // è©© + 0x8A66, KANJI_STANDARD, // 詊 + 0x8A8C, KANJI_STANDARD, // 誌 + 0x8AEE, KANJI_STANDARD, // è«® + 0x8CC7, KANJI_STANDARD, // 資 + 0x8CDC, KANJI_STANDARD, // 賜 + 0x96CC, KANJI_STANDARD, // 雌 + 0x98FC, KANJI_STANDARD, // 飌 + 0x6B6F, KANJI_STANDARD, // æ­¯ + 0x4E8B, KANJI_STANDARD, // 事 + 0x4F3C, KANJI_STANDARD, // 䌌 + 0x4F8D, KANJI_STANDARD, // 䟍 + 0x5150, KANJI_STANDARD, // 児 + 0x5B57, KANJI_STANDARD, // 字 + 0x5BFA, KANJI_STANDARD, // 寺 + 0x6148, KANJI_STANDARD, // 慈 + 0x6301, KANJI_STANDARD, // 持 + 0x6642, KANJI_STANDARD, // 時 + 0x6B21, KANJI_STANDARD, // 次 + 0x6ECB, KANJI_STANDARD, // 滋 + 0x6CBB, KANJI_STANDARD, // æ²» + 0x723E, KANJI_STANDARD, // 爟 + 0x74BD, KANJI_STANDARD, // ç’œ + 0x75D4, KANJI_STANDARD, // 痔 + 0x78C1, KANJI_STANDARD, // 磁 + 0x793A, KANJI_STANDARD, // 瀺 + 0x800C, KANJI_STANDARD, // 而 + 0x8033, KANJI_STANDARD, // 耳 + 0x81EA, KANJI_STANDARD, // 自 + 0x8494, KANJI_STANDARD, // 蒔 + 0x8F9E, KANJI_STANDARD, // 蟞 + 0x6C50, KANJI_STANDARD, // 汐 + 0x9E7F, KANJI_STANDARD, // 鹿 + 0x5F0F, KANJI_STANDARD, // 匏 + 0x8B58, KANJI_STANDARD, // 識 + 0x9D2B, KANJI_STANDARD, // 鎫 + 0x7AFA, KANJI_STANDARD, // 竺 + 0x8EF8, KANJI_STANDARD, // 軞 + 0x5B8D, KANJI_STANDARD, // 宍 + 0x96EB, KANJI_STANDARD, // 雫 + 0x4E03, KANJI_STANDARD, // 䞃 + 0x53F1, KANJI_STANDARD, // 叱 + 0x57F7, KANJI_STANDARD, // 執 + 0x5931, KANJI_STANDARD, // 倱 + 0x5AC9, KANJI_STANDARD, // 嫉 + 0x5BA4, KANJI_STANDARD, // 宀 + 0x6089, KANJI_STANDARD, // 悉 + 0x6E7F, KANJI_STANDARD, // 湿 + 0x6F06, KANJI_STANDARD, // 挆 + 0x75BE, KANJI_STANDARD, // ç–Ÿ + 0x8CEA, KANJI_STANDARD, // 質 + 0x5B9F, KANJI_STANDARD, // 実 + 0x8500, KANJI_STANDARD, // 蔀 + 0x7BE0, KANJI_STANDARD, // 篠 + 0x5072, KANJI_STANDARD, // 偲 + 0x67F4, KANJI_STANDARD, // 柎 + 0x829D, KANJI_STANDARD, // 芝 + 0x5C61, KANJI_STANDARD, // 屡 + 0x854A, KANJI_STANDARD, // 蕊 + 0x7E1E, KANJI_STANDARD, // 羞 + 0x820E, KANJI_STANDARD, // 舎 + 0x5199, KANJI_STANDARD, // 写 + 0x5C04, KANJI_STANDARD, // 射 + 0x6368, KANJI_STANDARD, // 捚 + 0x8D66, KANJI_STANDARD, // 赊 + 0x659C, KANJI_STANDARD, // 斜 + 0x716E, KANJI_STANDARD, // 煮 + 0x793E, KANJI_STANDARD, // 瀟 + 0x7D17, KANJI_STANDARD, // 算 + 0x8005, KANJI_STANDARD, // 者 + 0x8B1D, KANJI_STANDARD, // 謝 + 0x8ECA, KANJI_STANDARD, // 車 + 0x906E, KANJI_STANDARD, // 遮 + 0x86C7, KANJI_STANDARD, // 蛇 + 0x90AA, KANJI_STANDARD, // 邪 + 0x501F, KANJI_STANDARD, // 借 + 0x52FA, KANJI_STANDARD, // 勺 + 0x5C3A, KANJI_STANDARD, // å°º + 0x6753, KANJI_STANDARD, // 杓 + 0x707C, KANJI_STANDARD, // 灌 + 0x7235, KANJI_STANDARD, // 爵 + 0x914C, KANJI_STANDARD, // 酌 + 0x91C8, KANJI_STANDARD, // 釈 + 0x932B, KANJI_STANDARD, // 錫 + 0x82E5, KANJI_STANDARD, // 若 + 0x5BC2, KANJI_STANDARD, // 寂 + 0x5F31, KANJI_STANDARD, // 匱 + 0x60F9, KANJI_STANDARD, // 惹 + 0x4E3B, KANJI_STANDARD, // äž» + 0x53D6, KANJI_STANDARD, // 取 + 0x5B88, KANJI_STANDARD, // 守 + 0x624B, KANJI_STANDARD, // 手 + 0x6731, KANJI_STANDARD, // 朱 + 0x6B8A, KANJI_STANDARD, // 殊 + 0x72E9, KANJI_STANDARD, // 狩 + 0x73E0, KANJI_STANDARD, // 珠 + 0x7A2E, KANJI_STANDARD, // çš® + 0x816B, KANJI_STANDARD, // 腫 + 0x8DA3, KANJI_STANDARD, // è¶£ + 0x9152, KANJI_STANDARD, // 酒 + 0x9996, KANJI_STANDARD, // 驖 + 0x5112, KANJI_STANDARD, // 儒 + 0x53D7, KANJI_STANDARD, // 受 + 0x546A, KANJI_STANDARD, // 呪 + 0x5BFF, KANJI_STANDARD, // 寿 + 0x6388, KANJI_STANDARD, // 授 + 0x6A39, KANJI_STANDARD, // æš¹ + 0x7DAC, KANJI_STANDARD, // 綬 + 0x9700, KANJI_STANDARD, // 需 + 0x56DA, KANJI_STANDARD, // 囚 + 0x53CE, KANJI_STANDARD, // 収 + 0x5468, KANJI_STANDARD, // 呚 + 0x5B97, KANJI_STANDARD, // 宗 + 0x5C31, KANJI_STANDARD, // å°± + 0x5DDE, KANJI_STANDARD, // 州 + 0x4FEE, KANJI_STANDARD, // ä¿® + 0x6101, KANJI_STANDARD, // 愁 + 0x62FE, KANJI_STANDARD, // 拟 + 0x6D32, KANJI_STANDARD, // 掲 + 0x79C0, KANJI_STANDARD, // 秀 + 0x79CB, KANJI_STANDARD, // 秋 + 0x7D42, KANJI_STANDARD, // 終 + 0x7E4D, KANJI_STANDARD, // 繍 + 0x7FD2, KANJI_STANDARD, // 習 + 0x81ED, KANJI_STANDARD, // 臭 + 0x821F, KANJI_STANDARD, // 舟 + 0x8490, KANJI_STANDARD, // 蒐 + 0x8846, KANJI_STANDARD, // 衆 + 0x8972, KANJI_STANDARD, // 襲 + 0x8B90, KANJI_STANDARD, // 讐 + 0x8E74, KANJI_STANDARD, // 蹎 + 0x8F2F, KANJI_STANDARD, // 茯 + 0x9031, KANJI_STANDARD, // 週 + 0x914B, KANJI_STANDARD, // 酋 + 0x916C, KANJI_STANDARD, // 酬 + 0x96C6, KANJI_STANDARD, // 集 + 0x919C, KANJI_STANDARD, // 醜 + 0x4EC0, KANJI_STANDARD, // 什 + 0x4F4F, KANJI_STANDARD, // 䜏 + 0x5145, KANJI_STANDARD, // 充 + 0x5341, KANJI_STANDARD, // 十 + 0x5F93, KANJI_STANDARD, // 埓 + 0x620E, KANJI_STANDARD, // 戎 + 0x67D4, KANJI_STANDARD, // 柔 + 0x6C41, KANJI_STANDARD, // 汁 + 0x6E0B, KANJI_STANDARD, // æž‹ + 0x7363, KANJI_STANDARD, // 獣 + 0x7E26, KANJI_STANDARD, // 瞊 + 0x91CD, KANJI_STANDARD, // 重 + 0x9283, KANJI_STANDARD, // 銃 + 0x53D4, KANJI_STANDARD, // 叔 + 0x5919, KANJI_STANDARD, // 候 + 0x5BBF, KANJI_STANDARD, // 宿 + 0x6DD1, KANJI_STANDARD, // 淑 + 0x795D, KANJI_STANDARD, // 祝 + 0x7E2E, KANJI_STANDARD, // çž® + 0x7C9B, KANJI_STANDARD, // 粛 + 0x587E, KANJI_STANDARD, // 塟 + 0x719F, KANJI_STANDARD, // 熟 + 0x51FA, KANJI_STANDARD, // 出 + 0x8853, KANJI_STANDARD, // 術 + 0x8FF0, KANJI_STANDARD, // è¿° + 0x4FCA, KANJI_STANDARD, // 俊 + 0x5CFB, KANJI_STANDARD, // å³» + 0x6625, KANJI_STANDARD, // 春 + 0x77AC, KANJI_STANDARD, // 瞬 + 0x7AE3, KANJI_STANDARD, // ç«£ + 0x821C, KANJI_STANDARD, // 舜 + 0x99FF, KANJI_STANDARD, // é§¿ + 0x51C6, KANJI_STANDARD, // 准 + 0x5FAA, KANJI_STANDARD, // 埪 + 0x65EC, KANJI_STANDARD, // 旬 + 0x696F, KANJI_STANDARD, // 楯 + 0x6B89, KANJI_STANDARD, // 殉 + 0x6DF3, KANJI_STANDARD, // æ·³ + 0x6E96, KANJI_STANDARD, // 準 + 0x6F64, KANJI_STANDARD, // 最 + 0x76FE, KANJI_STANDARD, // 盟 + 0x7D14, KANJI_STANDARD, // 箔 + 0x5DE1, KANJI_STANDARD, // å·¡ + 0x9075, KANJI_STANDARD, // 遵 + 0x9187, KANJI_STANDARD, // 醇 + 0x9806, KANJI_STANDARD, // 順 + 0x51E6, KANJI_STANDARD, // 凊 + 0x521D, KANJI_STANDARD, // 初 + 0x6240, KANJI_STANDARD, // 所 + 0x6691, KANJI_STANDARD, // 暑 + 0x66D9, KANJI_STANDARD, // 曙 + 0x6E1A, KANJI_STANDARD, // æžš + 0x5EB6, KANJI_STANDARD, // 庶 + 0x7DD2, KANJI_STANDARD, // 緒 + 0x7F72, KANJI_STANDARD, // 眲 + 0x66F8, KANJI_STANDARD, // 曞 + 0x85AF, KANJI_STANDARD, // 薯 + 0x85F7, KANJI_STANDARD, // 藷 + 0x8AF8, KANJI_STANDARD, // 諞 + 0x52A9, KANJI_STANDARD, // 助 + 0x53D9, KANJI_STANDARD, // 叙 + 0x5973, KANJI_STANDARD, // 女 + 0x5E8F, KANJI_STANDARD, // 序 + 0x5F90, KANJI_STANDARD, // 埐 + 0x6055, KANJI_STANDARD, // 恕 + 0x92E4, KANJI_STANDARD, // é‹€ + 0x9664, KANJI_STANDARD, // 陀 + 0x50B7, KANJI_STANDARD, // 傷 + 0x511F, KANJI_STANDARD, // 償 + 0x52DD, KANJI_STANDARD, // 勝 + 0x5320, KANJI_STANDARD, // 匠 + 0x5347, KANJI_STANDARD, // 升 + 0x53EC, KANJI_STANDARD, // 召 + 0x54E8, KANJI_STANDARD, // 哚 + 0x5546, KANJI_STANDARD, // 商 + 0x5531, KANJI_STANDARD, // 唱 + 0x5617, KANJI_STANDARD, // 嘗 + 0x5968, KANJI_STANDARD, // 奚 + 0x59BE, KANJI_STANDARD, // 功 + 0x5A3C, KANJI_STANDARD, // 嚌 + 0x5BB5, KANJI_STANDARD, // 宵 + 0x5C06, KANJI_STANDARD, // 将 + 0x5C0F, KANJI_STANDARD, // 小 + 0x5C11, KANJI_STANDARD, // 少 + 0x5C1A, KANJI_STANDARD, // 尚 + 0x5E84, KANJI_STANDARD, // 庄 + 0x5E8A, KANJI_STANDARD, // 床 + 0x5EE0, KANJI_STANDARD, // å»  + 0x5F70, KANJI_STANDARD, // 地 + 0x627F, KANJI_STANDARD, // 承 + 0x6284, KANJI_STANDARD, // 抄 + 0x62DB, KANJI_STANDARD, // 招 + 0x638C, KANJI_STANDARD, // 掌 + 0x6377, KANJI_STANDARD, // 捷 + 0x6607, KANJI_STANDARD, // 昇 + 0x660C, KANJI_STANDARD, // 昌 + 0x662D, KANJI_STANDARD, // 昭 + 0x6676, KANJI_STANDARD, // 晶 + 0x677E, KANJI_STANDARD, // 束 + 0x68A2, KANJI_STANDARD, // 梢 + 0x6A1F, KANJI_STANDARD, // 暟 + 0x6A35, KANJI_STANDARD, // æšµ + 0x6CBC, KANJI_STANDARD, // 沌 + 0x6D88, KANJI_STANDARD, // 消 + 0x6E09, KANJI_STANDARD, // 枉 + 0x6E58, KANJI_STANDARD, // 湘 + 0x713C, KANJI_STANDARD, // 焌 + 0x7126, KANJI_STANDARD, // 焩 + 0x7167, KANJI_STANDARD, // 照 + 0x75C7, KANJI_STANDARD, // 症 + 0x7701, KANJI_STANDARD, // 省 + 0x785D, KANJI_STANDARD, // 硝 + 0x7901, KANJI_STANDARD, // 瀁 + 0x7965, KANJI_STANDARD, // 祥 + 0x79F0, KANJI_STANDARD, // ç§° + 0x7AE0, KANJI_STANDARD, // ç«  + 0x7B11, KANJI_STANDARD, // 笑 + 0x7CA7, KANJI_STANDARD, // ç²§ + 0x7D39, KANJI_STANDARD, // 玹 + 0x8096, KANJI_STANDARD, // 肖 + 0x83D6, KANJI_STANDARD, // 菖 + 0x848B, KANJI_STANDARD, // 蒋 + 0x8549, KANJI_STANDARD, // 蕉 + 0x885D, KANJI_STANDARD, // 衝 + 0x88F3, KANJI_STANDARD, // 裳 + 0x8A1F, KANJI_STANDARD, // 蚟 + 0x8A3C, KANJI_STANDARD, // 蚌 + 0x8A54, KANJI_STANDARD, // 詔 + 0x8A73, KANJI_STANDARD, // 詳 + 0x8C61, KANJI_STANDARD, // 象 + 0x8CDE, KANJI_STANDARD, // 賞 + 0x91A4, KANJI_STANDARD, // 醀 + 0x9266, KANJI_STANDARD, // 鉩 + 0x937E, KANJI_STANDARD, // 鍟 + 0x9418, KANJI_STANDARD, // 鐘 + 0x969C, KANJI_STANDARD, // 障 + 0x9798, KANJI_STANDARD, // 鞘 + 0x4E0A, KANJI_STANDARD, // 侊 + 0x4E08, KANJI_STANDARD, // 䞈 + 0x4E1E, KANJI_STANDARD, // 侞 + 0x4E57, KANJI_STANDARD, // 乗 + 0x5197, KANJI_STANDARD, // 冗 + 0x5270, KANJI_STANDARD, // 剰 + 0x57CE, KANJI_STANDARD, // 城 + 0x5834, KANJI_STANDARD, // å Ž + 0x58CC, KANJI_STANDARD, // 壌 + 0x5B22, KANJI_STANDARD, // 嬢 + 0x5E38, KANJI_STANDARD, // åžž + 0x60C5, KANJI_STANDARD, // 情 + 0x64FE, KANJI_STANDARD, // 擟 + 0x6761, KANJI_STANDARD, // 条 + 0x6756, KANJI_STANDARD, // 杖 + 0x6D44, KANJI_STANDARD, // 浄 + 0x72B6, KANJI_STANDARD, // 状 + 0x7573, KANJI_STANDARD, // 畳 + 0x7A63, KANJI_STANDARD, // ç©£ + 0x84B8, KANJI_STANDARD, // è’ž + 0x8B72, KANJI_STANDARD, // è­² + 0x91B8, KANJI_STANDARD, // 醾 + 0x9320, KANJI_STANDARD, // 錠 + 0x5631, KANJI_STANDARD, // 嘱 + 0x57F4, KANJI_STANDARD, // 城 + 0x98FE, KANJI_STANDARD, // 食 + 0x62ED, KANJI_STANDARD, // 拭 + 0x690D, KANJI_STANDARD, // 怍 + 0x6B96, KANJI_STANDARD, // 殖 + 0x71ED, KANJI_STANDARD, // 燭 + 0x7E54, KANJI_STANDARD, // 織 + 0x8077, KANJI_STANDARD, // 職 + 0x8272, KANJI_STANDARD, // 色 + 0x89E6, KANJI_STANDARD, // è§Š + 0x98DF, KANJI_STANDARD, // 食 + 0x8755, KANJI_STANDARD, // 蝕 + 0x8FB1, KANJI_STANDARD, // 蟱 + 0x5C3B, KANJI_STANDARD, // å°» + 0x4F38, KANJI_STANDARD, // 䌞 + 0x4FE1, KANJI_STANDARD, // ä¿¡ + 0x4FB5, KANJI_STANDARD, // 䟵 + 0x5507, KANJI_STANDARD, // 唇 + 0x5A20, KANJI_STANDARD, // åš  + 0x5BDD, KANJI_STANDARD, // 寝 + 0x5BE9, KANJI_STANDARD, // 審 + 0x5FC3, KANJI_STANDARD, // 心 + 0x614E, KANJI_STANDARD, // 慎 + 0x632F, KANJI_STANDARD, // 振 + 0x65B0, KANJI_STANDARD, // 新 + 0x664B, KANJI_STANDARD, // 晋 + 0x68EE, KANJI_STANDARD, // 森 + 0x699B, KANJI_STANDARD, // 抛 + 0x6D78, KANJI_STANDARD, // 浞 + 0x6DF1, KANJI_STANDARD, // æ·± + 0x7533, KANJI_STANDARD, // 申 + 0x75B9, KANJI_STANDARD, // 疹 + 0x771F, KANJI_STANDARD, // 真 + 0x795E, KANJI_STANDARD, // 神 + 0x79E6, KANJI_STANDARD, // ç§Š + 0x7D33, KANJI_STANDARD, // 玳 + 0x81E3, KANJI_STANDARD, // 臣 + 0x82AF, KANJI_STANDARD, // 芯 + 0x85AA, KANJI_STANDARD, // 薪 + 0x89AA, KANJI_STANDARD, // 芪 + 0x8A3A, KANJI_STANDARD, // 蚺 + 0x8EAB, KANJI_STANDARD, // 身 + 0x8F9B, KANJI_STANDARD, // 蟛 + 0x9032, KANJI_STANDARD, // 進 + 0x91DD, KANJI_STANDARD, // 針 + 0x9707, KANJI_STANDARD, // 震 + 0x4EBA, KANJI_STANDARD, // 人 + 0x4EC1, KANJI_STANDARD, // 仁 + 0x5203, KANJI_STANDARD, // 刃 + 0x5875, KANJI_STANDARD, // 塵 + 0x58EC, KANJI_STANDARD, // 壬 + 0x5C0B, KANJI_STANDARD, // 尋 + 0x751A, KANJI_STANDARD, // 甚 + 0x5C3D, KANJI_STANDARD, // å°œ + 0x814E, KANJI_STANDARD, // 腎 + 0x8A0A, KANJI_STANDARD, // 蚊 + 0x8FC5, KANJI_STANDARD, // 迅 + 0x9663, KANJI_STANDARD, // 陣 + 0x976D, KANJI_STANDARD, // 靭 + 0x7B25, KANJI_STANDARD, // 笥 + 0x8ACF, KANJI_STANDARD, // 諏 + 0x9808, KANJI_STANDARD, // 須 + 0x9162, KANJI_STANDARD, // 酢 + 0x56F3, KANJI_STANDARD, // 図 + 0x53A8, KANJI_STANDARD, // 厚 + 0x9017, KANJI_STANDARD, // 逗 + 0x5439, KANJI_STANDARD, // 吹 + 0x5782, KANJI_STANDARD, // 垂 + 0x5E25, KANJI_STANDARD, // 垥 + 0x63A8, KANJI_STANDARD, // 掚 + 0x6C34, KANJI_STANDARD, // æ°Ž + 0x708A, KANJI_STANDARD, // 炊 + 0x7761, KANJI_STANDARD, // 睡 + 0x7C8B, KANJI_STANDARD, // 粋 + 0x7FE0, KANJI_STANDARD, // ç¿  + 0x8870, KANJI_STANDARD, // è¡° + 0x9042, KANJI_STANDARD, // 遂 + 0x9154, KANJI_STANDARD, // 酔 + 0x9310, KANJI_STANDARD, // 錐 + 0x9318, KANJI_STANDARD, // 錘 + 0x968F, KANJI_STANDARD, // 随 + 0x745E, KANJI_STANDARD, // 瑞 + 0x9AC4, KANJI_STANDARD, // 髄 + 0x5D07, KANJI_STANDARD, // 厇 + 0x5D69, KANJI_STANDARD, // 嵩 + 0x6570, KANJI_STANDARD, // 数 + 0x67A2, KANJI_STANDARD, // 枢 + 0x8DA8, KANJI_STANDARD, // è¶š + 0x96DB, KANJI_STANDARD, // 雛 + 0x636E, KANJI_STANDARD, // 据 + 0x6749, KANJI_STANDARD, // 杉 + 0x6919, KANJI_STANDARD, // 怙 + 0x83C5, KANJI_STANDARD, // 菅 + 0x9817, KANJI_STANDARD, // 頗 + 0x96C0, KANJI_STANDARD, // 雀 + 0x88FE, KANJI_STANDARD, // 裟 + 0x6F84, KANJI_STANDARD, // 柄 + 0x647A, KANJI_STANDARD, // 摺 + 0x5BF8, KANJI_STANDARD, // 寞 + 0x4E16, KANJI_STANDARD, // 侖 + 0x702C, KANJI_STANDARD, // 瀬 + 0x755D, KANJI_STANDARD, // 畝 + 0x662F, KANJI_STANDARD, // 是 + 0x51C4, KANJI_STANDARD, // 凄 + 0x5236, KANJI_STANDARD, // 制 + 0x52E2, KANJI_STANDARD, // 勢 + 0x59D3, KANJI_STANDARD, // 姓 + 0x5F81, KANJI_STANDARD, // 埁 + 0x6027, KANJI_STANDARD, // 性 + 0x6210, KANJI_STANDARD, // 成 + 0x653F, KANJI_STANDARD, // 政 + 0x6574, KANJI_STANDARD, // 敎 + 0x661F, KANJI_STANDARD, // 星 + 0x6674, KANJI_STANDARD, // 晎 + 0x68F2, KANJI_STANDARD, // 棲 + 0x6816, KANJI_STANDARD, // 栖 + 0x6B63, KANJI_STANDARD, // æ­£ + 0x6E05, KANJI_STANDARD, // æž… + 0x7272, KANJI_STANDARD, // 牲 + 0x751F, KANJI_STANDARD, // 生 + 0x76DB, KANJI_STANDARD, // 盛 + 0x7CBE, KANJI_STANDARD, // 粟 + 0x8056, KANJI_STANDARD, // 聖 + 0x58F0, KANJI_STANDARD, // 声 + 0x88FD, KANJI_STANDARD, // 補 + 0x897F, KANJI_STANDARD, // 西 + 0x8AA0, KANJI_STANDARD, // 誠 + 0x8A93, KANJI_STANDARD, // 誓 + 0x8ACB, KANJI_STANDARD, // 請 + 0x901D, KANJI_STANDARD, // 逝 + 0x9192, KANJI_STANDARD, // 醒 + 0x9752, KANJI_STANDARD, // 青 + 0x9759, KANJI_STANDARD, // 静 + 0x6589, KANJI_STANDARD, // 斉 + 0x7A0E, KANJI_STANDARD, // 皎 + 0x8106, KANJI_STANDARD, // 脆 + 0x96BB, KANJI_STANDARD, // 隻 + 0x5E2D, KANJI_STANDARD, // åž­ + 0x60DC, KANJI_STANDARD, // 惜 + 0x621A, KANJI_STANDARD, // 戚 + 0x65A5, KANJI_STANDARD, // 斥 + 0x6614, KANJI_STANDARD, // 昔 + 0x6790, KANJI_STANDARD, // 析 + 0x77F3, KANJI_STANDARD, // 石 + 0x7A4D, KANJI_STANDARD, // 積 + 0x7C4D, KANJI_STANDARD, // 籍 + 0x7E3E, KANJI_STANDARD, // 瞟 + 0x810A, KANJI_STANDARD, // 脊 + 0x8CAC, KANJI_STANDARD, // 責 + 0x8D64, KANJI_STANDARD, // èµ€ + 0x8DE1, KANJI_STANDARD, // è·¡ + 0x8E5F, KANJI_STANDARD, // 蹟 + 0x78A9, KANJI_STANDARD, // 碩 + 0x5207, KANJI_STANDARD, // 切 + 0x62D9, KANJI_STANDARD, // 拙 + 0x63A5, KANJI_STANDARD, // 接 + 0x6442, KANJI_STANDARD, // 摂 + 0x6298, KANJI_STANDARD, // 折 + 0x8A2D, KANJI_STANDARD, // èš­ + 0x7A83, KANJI_STANDARD, // 窃 + 0x7BC0, KANJI_STANDARD, // 節 + 0x8AAC, KANJI_STANDARD, // 説 + 0x96EA, KANJI_STANDARD, // 雪 + 0x7D76, KANJI_STANDARD, // çµ¶ + 0x820C, KANJI_STANDARD, // 舌 + 0x8749, KANJI_STANDARD, // 蝉 + 0x4ED9, KANJI_STANDARD, // 仙 + 0x5148, KANJI_STANDARD, // 先 + 0x5343, KANJI_STANDARD, // 千 + 0x5360, KANJI_STANDARD, // 占 + 0x5BA3, KANJI_STANDARD, // 宣 + 0x5C02, KANJI_STANDARD, // 専 + 0x5C16, KANJI_STANDARD, // 尖 + 0x5DDD, KANJI_STANDARD, // 川 + 0x6226, KANJI_STANDARD, // 戊 + 0x6247, KANJI_STANDARD, // 扇 + 0x64B0, KANJI_STANDARD, // 撰 + 0x6813, KANJI_STANDARD, // 栓 + 0x6834, KANJI_STANDARD, // æ Ž + 0x6CC9, KANJI_STANDARD, // 泉 + 0x6D45, KANJI_STANDARD, // 浅 + 0x6D17, KANJI_STANDARD, // 掗 + 0x67D3, KANJI_STANDARD, // 染 + 0x6F5C, KANJI_STANDARD, // 朜 + 0x714E, KANJI_STANDARD, // 煎 + 0x717D, KANJI_STANDARD, // ç…œ + 0x65CB, KANJI_STANDARD, // 旋 + 0x7A7F, KANJI_STANDARD, // ç©¿ + 0x7BAD, KANJI_STANDARD, // ç®­ + 0x7DDA, KANJI_STANDARD, // 線 + 0x7E4A, KANJI_STANDARD, // 繊 + 0x7FA8, KANJI_STANDARD, // 矚 + 0x817A, KANJI_STANDARD, // 腺 + 0x821B, KANJI_STANDARD, // 舛 + 0x8239, KANJI_STANDARD, // 船 + 0x85A6, KANJI_STANDARD, // è–Š + 0x8A6E, KANJI_STANDARD, // è©® + 0x8CCE, KANJI_STANDARD, // 賎 + 0x8DF5, KANJI_STANDARD, // è·µ + 0x9078, KANJI_STANDARD, // 遞 + 0x9077, KANJI_STANDARD, // 遷 + 0x92AD, KANJI_STANDARD, // 銭 + 0x9291, KANJI_STANDARD, // 銑 + 0x9583, KANJI_STANDARD, // 閃 + 0x9BAE, KANJI_STANDARD, // é®® + 0x524D, KANJI_STANDARD, // 前 + 0x5584, KANJI_STANDARD, // 善 + 0x6F38, KANJI_STANDARD, // 挞 + 0x7136, KANJI_STANDARD, // 然 + 0x5168, KANJI_STANDARD, // å…š + 0x7985, KANJI_STANDARD, // 穅 + 0x7E55, KANJI_STANDARD, // 繕 + 0x81B3, KANJI_STANDARD, // 膳 + 0x7CCE, KANJI_STANDARD, // 糎 + 0x564C, KANJI_STANDARD, // 噌 + 0x5851, KANJI_STANDARD, // 塑 + 0x5CA8, KANJI_STANDARD, // 岚 + 0x63AA, KANJI_STANDARD, // 措 + 0x66FE, KANJI_STANDARD, // 曟 + 0x66FD, KANJI_STANDARD, // 曜 + 0x695A, KANJI_STANDARD, // 楚 + 0x72D9, KANJI_STANDARD, // 狙 + 0x758F, KANJI_STANDARD, // 疏 + 0x758E, KANJI_STANDARD, // 疎 + 0x790E, KANJI_STANDARD, // 瀎 + 0x7956, KANJI_STANDARD, // 祖 + 0x79DF, KANJI_STANDARD, // 租 + 0x7C97, KANJI_STANDARD, // 粗 + 0x7D20, KANJI_STANDARD, // 玠 + 0x7D44, KANJI_STANDARD, // 組 + 0x8607, KANJI_STANDARD, // 蘇 + 0x8A34, KANJI_STANDARD, // 蚎 + 0x963B, KANJI_STANDARD, // 阻 + 0x9061, KANJI_STANDARD, // 遡 + 0x9F20, KANJI_STANDARD, // 錠 + 0x50E7, KANJI_STANDARD, // 僧 + 0x5275, KANJI_STANDARD, // 創 + 0x53CC, KANJI_STANDARD, // 双 + 0x53E2, KANJI_STANDARD, // 叢 + 0x5009, KANJI_STANDARD, // 倉 + 0x55AA, KANJI_STANDARD, // 喪 + 0x58EE, KANJI_STANDARD, // 壮 + 0x594F, KANJI_STANDARD, // 奏 + 0x723D, KANJI_STANDARD, // 爜 + 0x5B8B, KANJI_STANDARD, // 宋 + 0x5C64, KANJI_STANDARD, // å±€ + 0x531D, KANJI_STANDARD, // 匝 + 0x60E3, KANJI_STANDARD, // 惣 + 0x60F3, KANJI_STANDARD, // 想 + 0x635C, KANJI_STANDARD, // 捜 + 0x6383, KANJI_STANDARD, // 掃 + 0x633F, KANJI_STANDARD, // 挿 + 0x63BB, KANJI_STANDARD, // 掻 + 0x64CD, KANJI_STANDARD, // 操 + 0x65E9, KANJI_STANDARD, // 早 + 0x66F9, KANJI_STANDARD, // 曹 + 0x5DE3, KANJI_STANDARD, // å·£ + 0x69CD, KANJI_STANDARD, // 槍 + 0x69FD, KANJI_STANDARD, // æ§œ + 0x6F15, KANJI_STANDARD, // 挕 + 0x71E5, KANJI_STANDARD, // 燥 + 0x4E89, KANJI_STANDARD, // 争 + 0x75E9, KANJI_STANDARD, // 痩 + 0x76F8, KANJI_STANDARD, // 盾 + 0x7A93, KANJI_STANDARD, // 窓 + 0x7CDF, KANJI_STANDARD, // 糟 + 0x7DCF, KANJI_STANDARD, // 総 + 0x7D9C, KANJI_STANDARD, // 綜 + 0x8061, KANJI_STANDARD, // 聡 + 0x8349, KANJI_STANDARD, // 草 + 0x8358, KANJI_STANDARD, // 荘 + 0x846C, KANJI_STANDARD, // 葬 + 0x84BC, KANJI_STANDARD, // è’Œ + 0x85FB, KANJI_STANDARD, // 藻 + 0x88C5, KANJI_STANDARD, // 装 + 0x8D70, KANJI_STANDARD, // èµ° + 0x9001, KANJI_STANDARD, // 送 + 0x906D, KANJI_STANDARD, // 遭 + 0x9397, KANJI_STANDARD, // 鎗 + 0x971C, KANJI_STANDARD, // 霜 + 0x9A12, KANJI_STANDARD, // 鹒 + 0x50CF, KANJI_STANDARD, // 像 + 0x5897, KANJI_STANDARD, // 増 + 0x618E, KANJI_STANDARD, // 憎 + 0x81D3, KANJI_STANDARD, // 臓 + 0x8535, KANJI_STANDARD, // 蔵 + 0x8D08, KANJI_STANDARD, // 莈 + 0x9020, KANJI_STANDARD, // 造 + 0x4FC3, KANJI_STANDARD, // 促 + 0x5074, KANJI_STANDARD, // 偎 + 0x5247, KANJI_STANDARD, // 則 + 0x5373, KANJI_STANDARD, // 即 + 0x606F, KANJI_STANDARD, // 息 + 0x6349, KANJI_STANDARD, // 捉 + 0x675F, KANJI_STANDARD, // 束 + 0x6E2C, KANJI_STANDARD, // 枬 + 0x8DB3, KANJI_STANDARD, // è¶³ + 0x901F, KANJI_STANDARD, // 速 + 0x4FD7, KANJI_STANDARD, // 俗 + 0x5C5E, KANJI_STANDARD, // 属 + 0x8CCA, KANJI_STANDARD, // 賊 + 0x65CF, KANJI_STANDARD, // 族 + 0x7D9A, KANJI_STANDARD, // 続 + 0x5352, KANJI_STANDARD, // 卒 + 0x8896, KANJI_STANDARD, // 袖 + 0x5176, KANJI_STANDARD, // 其 + 0x63C3, KANJI_STANDARD, // 揃 + 0x5B58, KANJI_STANDARD, // 存 + 0x5B6B, KANJI_STANDARD, // å­« + 0x5C0A, KANJI_STANDARD, // 尊 + 0x640D, KANJI_STANDARD, // 損 + 0x6751, KANJI_STANDARD, // 村 + 0x905C, KANJI_STANDARD, // 遜 + 0x4ED6, KANJI_STANDARD, // 他 + 0x591A, KANJI_STANDARD, // 倚 + 0x592A, KANJI_STANDARD, // 倪 + 0x6C70, KANJI_STANDARD, // æ±° + 0x8A51, KANJI_STANDARD, // 詑 + 0x553E, KANJI_STANDARD, // 唟 + 0x5815, KANJI_STANDARD, // 堕 + 0x59A5, KANJI_STANDARD, // 劥 + 0x60F0, KANJI_STANDARD, // 惰 + 0x6253, KANJI_STANDARD, // 打 + 0x67C1, KANJI_STANDARD, // 柁 + 0x8235, KANJI_STANDARD, // 舵 + 0x6955, KANJI_STANDARD, // 楕 + 0x9640, KANJI_STANDARD, // 陀 + 0x99C4, KANJI_STANDARD, // 駄 + 0x9A28, KANJI_STANDARD, // éšš + 0x4F53, KANJI_STANDARD, // 䜓 + 0x5806, KANJI_STANDARD, // 堆 + 0x5BFE, KANJI_STANDARD, // 察 + 0x8010, KANJI_STANDARD, // 耐 + 0x5CB1, KANJI_STANDARD, // å²± + 0x5E2F, KANJI_STANDARD, // 垯 + 0x5F85, KANJI_STANDARD, // 埅 + 0x6020, KANJI_STANDARD, // 怠 + 0x614B, KANJI_STANDARD, // 態 + 0x6234, KANJI_STANDARD, // 戎 + 0x66FF, KANJI_STANDARD, // 替 + 0x6CF0, KANJI_STANDARD, // æ³° + 0x6EDE, KANJI_STANDARD, // 滞 + 0x80CE, KANJI_STANDARD, // 胎 + 0x817F, KANJI_STANDARD, // 腿 + 0x82D4, KANJI_STANDARD, // 苔 + 0x888B, KANJI_STANDARD, // 袋 + 0x8CB8, KANJI_STANDARD, // 貞 + 0x9000, KANJI_STANDARD, // 退 + 0x902E, KANJI_STANDARD, // 逮 + 0x968A, KANJI_STANDARD, // 隊 + 0x9EDB, KANJI_STANDARD, // 黛 + 0x9BDB, KANJI_STANDARD, // 鯛 + 0x4EE3, KANJI_STANDARD, // 代 + 0x53F0, KANJI_STANDARD, // 台 + 0x5927, KANJI_STANDARD, // 倧 + 0x7B2C, KANJI_STANDARD, // 第 + 0x918D, KANJI_STANDARD, // 醍 + 0x984C, KANJI_STANDARD, // 題 + 0x9DF9, KANJI_STANDARD, // é·¹ + 0x6EDD, KANJI_STANDARD, // 滝 + 0x7027, KANJI_STANDARD, // 瀧 + 0x5353, KANJI_STANDARD, // 卓 + 0x5544, KANJI_STANDARD, // 啄 + 0x5B85, KANJI_STANDARD, // 宅 + 0x6258, KANJI_STANDARD, // 托 + 0x629E, KANJI_STANDARD, // 択 + 0x62D3, KANJI_STANDARD, // 拓 + 0x6CA2, KANJI_STANDARD, // æ²¢ + 0x6FEF, KANJI_STANDARD, // 濯 + 0x7422, KANJI_STANDARD, // 琢 + 0x8A17, KANJI_STANDARD, // èš— + 0x9438, KANJI_STANDARD, // 鐞 + 0x6FC1, KANJI_STANDARD, // 濁 + 0x8AFE, KANJI_STANDARD, // 諟 + 0x8338, KANJI_STANDARD, // 茞 + 0x51E7, KANJI_STANDARD, // 凧 + 0x86F8, KANJI_STANDARD, // 蛞 + 0x53EA, KANJI_STANDARD, // 只 + 0x53E9, KANJI_STANDARD, // 叩 + 0x4F46, KANJI_STANDARD, // 䜆 + 0x9054, KANJI_STANDARD, // 達 + 0x8FB0, KANJI_STANDARD, // 蟰 + 0x596A, KANJI_STANDARD, // 奪 + 0x8131, KANJI_STANDARD, // 脱 + 0x5DFD, KANJI_STANDARD, // å·œ + 0x7AEA, KANJI_STANDARD, // 竪 + 0x8FBF, KANJI_STANDARD, // 蟿 + 0x68DA, KANJI_STANDARD, // 棚 + 0x8C37, KANJI_STANDARD, // è°· + 0x72F8, KANJI_STANDARD, // 狾 + 0x9C48, KANJI_STANDARD, // 鱈 + 0x6A3D, KANJI_STANDARD, // æšœ + 0x8AB0, KANJI_STANDARD, // 誰 + 0x4E39, KANJI_STANDARD, // äž¹ + 0x5358, KANJI_STANDARD, // 単 + 0x5606, KANJI_STANDARD, // 嘆 + 0x5766, KANJI_STANDARD, // 坊 + 0x62C5, KANJI_STANDARD, // 担 + 0x63A2, KANJI_STANDARD, // 探 + 0x65E6, KANJI_STANDARD, // æ—Š + 0x6B4E, KANJI_STANDARD, // 歎 + 0x6DE1, KANJI_STANDARD, // æ·¡ + 0x6E5B, KANJI_STANDARD, // 湛 + 0x70AD, KANJI_STANDARD, // 炭 + 0x77ED, KANJI_STANDARD, // 短 + 0x7AEF, KANJI_STANDARD, // 端 + 0x7BAA, KANJI_STANDARD, // 箪 + 0x7DBB, KANJI_STANDARD, // ç¶» + 0x803D, KANJI_STANDARD, // 耜 + 0x80C6, KANJI_STANDARD, // 胆 + 0x86CB, KANJI_STANDARD, // 蛋 + 0x8A95, KANJI_STANDARD, // 誕 + 0x935B, KANJI_STANDARD, // 鍛 + 0x56E3, KANJI_STANDARD, // 団 + 0x58C7, KANJI_STANDARD, // 壇 + 0x5F3E, KANJI_STANDARD, // 匟 + 0x65AD, KANJI_STANDARD, // 断 + 0x6696, KANJI_STANDARD, // 暖 + 0x6A80, KANJI_STANDARD, // 檀 + 0x6BB5, KANJI_STANDARD, // 段 + 0x7537, KANJI_STANDARD, // 男 + 0x8AC7, KANJI_STANDARD, // 談 + 0x5024, KANJI_STANDARD, // 倀 + 0x77E5, KANJI_STANDARD, // 知 + 0x5730, KANJI_STANDARD, // 地 + 0x5F1B, KANJI_STANDARD, // 匛 + 0x6065, KANJI_STANDARD, // 恥 + 0x667A, KANJI_STANDARD, // 智 + 0x6C60, KANJI_STANDARD, // æ±  + 0x75F4, KANJI_STANDARD, // 痮 + 0x7A1A, KANJI_STANDARD, // 繚 + 0x7F6E, KANJI_STANDARD, // 眮 + 0x81F4, KANJI_STANDARD, // 臎 + 0x8718, KANJI_STANDARD, // 蜘 + 0x9045, KANJI_STANDARD, // 遅 + 0x99B3, KANJI_STANDARD, // 銳 + 0x7BC9, KANJI_STANDARD, // 築 + 0x755C, KANJI_STANDARD, // 畜 + 0x7AF9, KANJI_STANDARD, // 竹 + 0x7B51, KANJI_STANDARD, // 筑 + 0x84C4, KANJI_STANDARD, // 蓄 + 0x9010, KANJI_STANDARD, // 逐 + 0x79E9, KANJI_STANDARD, // ç§© + 0x7A92, KANJI_STANDARD, // 窒 + 0x8336, KANJI_STANDARD, // 茶 + 0x5AE1, KANJI_STANDARD, // å«¡ + 0x7740, KANJI_STANDARD, // 着 + 0x4E2D, KANJI_STANDARD, // äž­ + 0x4EF2, KANJI_STANDARD, // 仲 + 0x5B99, KANJI_STANDARD, // 宙 + 0x5FE0, KANJI_STANDARD, // å¿  + 0x62BD, KANJI_STANDARD, // 抜 + 0x663C, KANJI_STANDARD, // 昌 + 0x67F1, KANJI_STANDARD, // 柱 + 0x6CE8, KANJI_STANDARD, // 泚 + 0x866B, KANJI_STANDARD, // 虫 + 0x8877, KANJI_STANDARD, // è¡· + 0x8A3B, KANJI_STANDARD, // èš» + 0x914E, KANJI_STANDARD, // 酎 + 0x92F3, KANJI_STANDARD, // 鋳 + 0x99D0, KANJI_STANDARD, // 駐 + 0x6A17, KANJI_STANDARD, // æš— + 0x7026, KANJI_STANDARD, // 瀩 + 0x732A, KANJI_STANDARD, // 猪 + 0x82E7, KANJI_STANDARD, // 苧 + 0x8457, KANJI_STANDARD, // 著 + 0x8CAF, KANJI_STANDARD, // 貯 + 0x4E01, KANJI_STANDARD, // 䞁 + 0x5146, KANJI_STANDARD, // 兆 + 0x51CB, KANJI_STANDARD, // 凋 + 0x558B, KANJI_STANDARD, // 喋 + 0x5BF5, KANJI_STANDARD, // 寵 + 0x5E16, KANJI_STANDARD, // åž– + 0x5E33, KANJI_STANDARD, // åž³ + 0x5E81, KANJI_STANDARD, // 庁 + 0x5F14, KANJI_STANDARD, // 匔 + 0x5F35, KANJI_STANDARD, // 匵 + 0x5F6B, KANJI_STANDARD, // 圫 + 0x5FB4, KANJI_STANDARD, // 城 + 0x61F2, KANJI_STANDARD, // 懲 + 0x6311, KANJI_STANDARD, // 挑 + 0x66A2, KANJI_STANDARD, // 暢 + 0x671D, KANJI_STANDARD, // 朝 + 0x6F6E, KANJI_STANDARD, // 朮 + 0x7252, KANJI_STANDARD, // 牒 + 0x753A, KANJI_STANDARD, // 町 + 0x773A, KANJI_STANDARD, // 眺 + 0x8074, KANJI_STANDARD, // 聎 + 0x8139, KANJI_STANDARD, // 脹 + 0x8178, KANJI_STANDARD, // è…ž + 0x8776, KANJI_STANDARD, // 蝶 + 0x8ABF, KANJI_STANDARD, // 調 + 0x8ADC, KANJI_STANDARD, // 諜 + 0x8D85, KANJI_STANDARD, // 超 + 0x8DF3, KANJI_STANDARD, // è·³ + 0x929A, KANJI_STANDARD, // 銚 + 0x9577, KANJI_STANDARD, // 長 + 0x9802, KANJI_STANDARD, // 頂 + 0x9CE5, KANJI_STANDARD, // é³¥ + 0x52C5, KANJI_STANDARD, // 勅 + 0x6357, KANJI_STANDARD, // 捗 + 0x76F4, KANJI_STANDARD, // 目 + 0x6715, KANJI_STANDARD, // 朕 + 0x6C88, KANJI_STANDARD, // 沈 + 0x73CD, KANJI_STANDARD, // 珍 + 0x8CC3, KANJI_STANDARD, // 賃 + 0x93AE, KANJI_STANDARD, // 鎮 + 0x9673, KANJI_STANDARD, // 陳 + 0x6D25, KANJI_STANDARD, // 接 + 0x589C, KANJI_STANDARD, // 墜 + 0x690E, KANJI_STANDARD, // 怎 + 0x69CC, KANJI_STANDARD, // 槌 + 0x8FFD, KANJI_STANDARD, // 远 + 0x939A, KANJI_STANDARD, // 鎚 + 0x75DB, KANJI_STANDARD, // 痛 + 0x901A, KANJI_STANDARD, // 通 + 0x585A, KANJI_STANDARD, // 塚 + 0x6802, KANJI_STANDARD, // 栂 + 0x63B4, KANJI_STANDARD, // 掎 + 0x69FB, KANJI_STANDARD, // æ§» + 0x4F43, KANJI_STANDARD, // 䜃 + 0x6F2C, KANJI_STANDARD, // 挬 + 0x67D8, KANJI_STANDARD, // 柘 + 0x8FBB, KANJI_STANDARD, // 蟻 + 0x8526, KANJI_STANDARD, // 蔊 + 0x7DB4, KANJI_STANDARD, // ç¶Ž + 0x9354, KANJI_STANDARD, // 鍔 + 0x693F, KANJI_STANDARD, // 怿 + 0x6F70, KANJI_STANDARD, // 朰 + 0x576A, KANJI_STANDARD, // 坪 + 0x58F7, KANJI_STANDARD, // 壷 + 0x5B2C, KANJI_STANDARD, // 嬬 + 0x7D2C, KANJI_STANDARD, // 玬 + 0x722A, KANJI_STANDARD, // 爪 + 0x540A, KANJI_STANDARD, // 吊 + 0x91E3, KANJI_STANDARD, // 釣 + 0x9DB4, KANJI_STANDARD, // é¶Ž + 0x4EAD, KANJI_STANDARD, // 亭 + 0x4F4E, KANJI_STANDARD, // 䜎 + 0x505C, KANJI_STANDARD, // 停 + 0x5075, KANJI_STANDARD, // 偵 + 0x5243, KANJI_STANDARD, // 剃 + 0x8C9E, KANJI_STANDARD, // 貞 + 0x5448, KANJI_STANDARD, // 呈 + 0x5824, KANJI_STANDARD, // å € + 0x5B9A, KANJI_STANDARD, // 定 + 0x5E1D, KANJI_STANDARD, // 垝 + 0x5E95, KANJI_STANDARD, // 底 + 0x5EAD, KANJI_STANDARD, // 庭 + 0x5EF7, KANJI_STANDARD, // å»· + 0x5F1F, KANJI_STANDARD, // 匟 + 0x608C, KANJI_STANDARD, // 悌 + 0x62B5, KANJI_STANDARD, // 抵 + 0x633A, KANJI_STANDARD, // 挺 + 0x63D0, KANJI_STANDARD, // 提 + 0x68AF, KANJI_STANDARD, // 梯 + 0x6C40, KANJI_STANDARD, // 汀 + 0x7887, KANJI_STANDARD, // 碇 + 0x798E, KANJI_STANDARD, // 犎 + 0x7A0B, KANJI_STANDARD, // 繋 + 0x7DE0, KANJI_STANDARD, // ç·  + 0x8247, KANJI_STANDARD, // 艇 + 0x8A02, KANJI_STANDARD, // èš‚ + 0x8AE6, KANJI_STANDARD, // 諊 + 0x8E44, KANJI_STANDARD, // 蹄 + 0x9013, KANJI_STANDARD, // 逓 + 0x90B8, KANJI_STANDARD, // 邾 + 0x912D, KANJI_STANDARD, // 鄭 + 0x91D8, KANJI_STANDARD, // 釘 + 0x9F0E, KANJI_STANDARD, // 錎 + 0x6CE5, KANJI_STANDARD, // æ³¥ + 0x6458, KANJI_STANDARD, // 摘 + 0x64E2, KANJI_STANDARD, // 擢 + 0x6575, KANJI_STANDARD, // 敵 + 0x6EF4, KANJI_STANDARD, // 滎 + 0x7684, KANJI_STANDARD, // 的 + 0x7B1B, KANJI_STANDARD, // 笛 + 0x9069, KANJI_STANDARD, // 適 + 0x93D1, KANJI_STANDARD, // 鏑 + 0x6EBA, KANJI_STANDARD, // 溺 + 0x54F2, KANJI_STANDARD, // 哲 + 0x5FB9, KANJI_STANDARD, // 培 + 0x64A4, KANJI_STANDARD, // æ’€ + 0x8F4D, KANJI_STANDARD, // 蜍 + 0x8FED, KANJI_STANDARD, // è¿­ + 0x9244, KANJI_STANDARD, // 鉄 + 0x5178, KANJI_STANDARD, // å…ž + 0x586B, KANJI_STANDARD, // å¡« + 0x5929, KANJI_STANDARD, // 倩 + 0x5C55, KANJI_STANDARD, // 展 + 0x5E97, KANJI_STANDARD, // 店 + 0x6DFB, KANJI_STANDARD, // æ·» + 0x7E8F, KANJI_STANDARD, // 纏 + 0x751C, KANJI_STANDARD, // 甜 + 0x8CBC, KANJI_STANDARD, // 貌 + 0x8EE2, KANJI_STANDARD, // 転 + 0x985B, KANJI_STANDARD, // 顛 + 0x70B9, KANJI_STANDARD, // 点 + 0x4F1D, KANJI_STANDARD, // 䌝 + 0x6BBF, KANJI_STANDARD, // 殿 + 0x6FB1, KANJI_STANDARD, // 柱 + 0x7530, KANJI_STANDARD, // 田 + 0x96FB, KANJI_STANDARD, // 電 + 0x514E, KANJI_STANDARD, // 兎 + 0x5410, KANJI_STANDARD, // 吐 + 0x5835, KANJI_STANDARD, // å µ + 0x5857, KANJI_STANDARD, // 塗 + 0x59AC, KANJI_STANDARD, // 劬 + 0x5C60, KANJI_STANDARD, // å±  + 0x5F92, KANJI_STANDARD, // 埒 + 0x6597, KANJI_STANDARD, // 斗 + 0x675C, KANJI_STANDARD, // 杜 + 0x6E21, KANJI_STANDARD, // æž¡ + 0x767B, KANJI_STANDARD, // 登 + 0x83DF, KANJI_STANDARD, // 菟 + 0x8CED, KANJI_STANDARD, // è³­ + 0x9014, KANJI_STANDARD, // 途 + 0x90FD, KANJI_STANDARD, // 郜 + 0x934D, KANJI_STANDARD, // 鍍 + 0x7825, KANJI_STANDARD, // ç ¥ + 0x783A, KANJI_STANDARD, // ç º + 0x52AA, KANJI_STANDARD, // 努 + 0x5EA6, KANJI_STANDARD, // 床 + 0x571F, KANJI_STANDARD, // 土 + 0x5974, KANJI_STANDARD, // 奎 + 0x6012, KANJI_STANDARD, // 怒 + 0x5012, KANJI_STANDARD, // 倒 + 0x515A, KANJI_STANDARD, // 党 + 0x51AC, KANJI_STANDARD, // 冬 + 0x51CD, KANJI_STANDARD, // 凍 + 0x5200, KANJI_STANDARD, // 刀 + 0x5510, KANJI_STANDARD, // 唐 + 0x5854, KANJI_STANDARD, // 塔 + 0x5858, KANJI_STANDARD, // 塘 + 0x5957, KANJI_STANDARD, // 套 + 0x5B95, KANJI_STANDARD, // 宕 + 0x5CF6, KANJI_STANDARD, // å³¶ + 0x5D8B, KANJI_STANDARD, // 嶋 + 0x60BC, KANJI_STANDARD, // 悌 + 0x6295, KANJI_STANDARD, // 投 + 0x642D, KANJI_STANDARD, // 搭 + 0x6771, KANJI_STANDARD, // 東 + 0x6843, KANJI_STANDARD, // 桃 + 0x68BC, KANJI_STANDARD, // 梌 + 0x68DF, KANJI_STANDARD, // 棟 + 0x76D7, KANJI_STANDARD, // 盗 + 0x6DD8, KANJI_STANDARD, // 淘 + 0x6E6F, KANJI_STANDARD, // 湯 + 0x6D9B, KANJI_STANDARD, // 涛 + 0x706F, KANJI_STANDARD, // 灯 + 0x71C8, KANJI_STANDARD, // 燈 + 0x5F53, KANJI_STANDARD, // 圓 + 0x75D8, KANJI_STANDARD, // 痘 + 0x7977, KANJI_STANDARD, // 祷 + 0x7B49, KANJI_STANDARD, // 等 + 0x7B54, KANJI_STANDARD, // 答 + 0x7B52, KANJI_STANDARD, // 筒 + 0x7CD6, KANJI_STANDARD, // 糖 + 0x7D71, KANJI_STANDARD, // çµ± + 0x5230, KANJI_STANDARD, // 到 + 0x8463, KANJI_STANDARD, // 董 + 0x8569, KANJI_STANDARD, // 蕩 + 0x85E4, KANJI_STANDARD, // è—€ + 0x8A0E, KANJI_STANDARD, // 蚎 + 0x8B04, KANJI_STANDARD, // 謄 + 0x8C46, KANJI_STANDARD, // 豆 + 0x8E0F, KANJI_STANDARD, // 螏 + 0x9003, KANJI_STANDARD, // 逃 + 0x900F, KANJI_STANDARD, // 透 + 0x9419, KANJI_STANDARD, // 鐙 + 0x9676, KANJI_STANDARD, // 陶 + 0x982D, KANJI_STANDARD, // é ­ + 0x9A30, KANJI_STANDARD, // éš° + 0x95D8, KANJI_STANDARD, // 闘 + 0x50CD, KANJI_STANDARD, // 働 + 0x52D5, KANJI_STANDARD, // 動 + 0x540C, KANJI_STANDARD, // 同 + 0x5802, KANJI_STANDARD, // 堂 + 0x5C0E, KANJI_STANDARD, // 導 + 0x61A7, KANJI_STANDARD, // 憧 + 0x649E, KANJI_STANDARD, // 撞 + 0x6D1E, KANJI_STANDARD, // 掞 + 0x77B3, KANJI_STANDARD, // 瞳 + 0x7AE5, KANJI_STANDARD, // ç«¥ + 0x80F4, KANJI_STANDARD, // 胎 + 0x8404, KANJI_STANDARD, // 萄 + 0x9053, KANJI_STANDARD, // 道 + 0x9285, KANJI_STANDARD, // 銅 + 0x5CE0, KANJI_STANDARD, // å³  + 0x9D07, KANJI_STANDARD, // 鮇 + 0x533F, KANJI_STANDARD, // 匿 + 0x5F97, KANJI_STANDARD, // 埗 + 0x5FB3, KANJI_STANDARD, // 埳 + 0x6D9C, KANJI_STANDARD, // 涜 + 0x7279, KANJI_STANDARD, // 特 + 0x7763, KANJI_STANDARD, // 督 + 0x79BF, KANJI_STANDARD, // 犿 + 0x7BE4, KANJI_STANDARD, // 節 + 0x6BD2, KANJI_STANDARD, // 毒 + 0x72EC, KANJI_STANDARD, // 独 + 0x8AAD, KANJI_STANDARD, // 読 + 0x6803, KANJI_STANDARD, // 栃 + 0x6A61, KANJI_STANDARD, // æ©¡ + 0x51F8, KANJI_STANDARD, // 凞 + 0x7A81, KANJI_STANDARD, // 突 + 0x6934, KANJI_STANDARD, // 怎 + 0x5C4A, KANJI_STANDARD, // 届 + 0x9CF6, KANJI_STANDARD, // é³¶ + 0x82EB, KANJI_STANDARD, // 苫 + 0x5BC5, KANJI_STANDARD, // 寅 + 0x9149, KANJI_STANDARD, // 酉 + 0x701E, KANJI_STANDARD, // 瀞 + 0x5678, KANJI_STANDARD, // 噞 + 0x5C6F, KANJI_STANDARD, // 屯 + 0x60C7, KANJI_STANDARD, // 惇 + 0x6566, KANJI_STANDARD, // 敊 + 0x6C8C, KANJI_STANDARD, // 沌 + 0x8C5A, KANJI_STANDARD, // 豚 + 0x9041, KANJI_STANDARD, // 遁 + 0x9813, KANJI_STANDARD, // 頓 + 0x5451, KANJI_STANDARD, // 呑 + 0x66C7, KANJI_STANDARD, // 曇 + 0x920D, KANJI_STANDARD, // 鈍 + 0x5948, KANJI_STANDARD, // 奈 + 0x90A3, KANJI_STANDARD, // 那 + 0x5185, KANJI_STANDARD, // 内 + 0x4E4D, KANJI_STANDARD, // 乍 + 0x51EA, KANJI_STANDARD, // 凪 + 0x8599, KANJI_STANDARD, // 薙 + 0x8B0E, KANJI_STANDARD, // 謎 + 0x7058, KANJI_STANDARD, // 灘 + 0x637A, KANJI_STANDARD, // 捺 + 0x934B, KANJI_STANDARD, // 鍋 + 0x6962, KANJI_STANDARD, // 楢 + 0x99B4, KANJI_STANDARD, // 銎 + 0x7E04, KANJI_STANDARD, // 羄 + 0x7577, KANJI_STANDARD, // 畷 + 0x5357, KANJI_STANDARD, // 南 + 0x6960, KANJI_STANDARD, // 楠 + 0x8EDF, KANJI_STANDARD, // 軟 + 0x96E3, KANJI_STANDARD, // 難 + 0x6C5D, KANJI_STANDARD, // 汝 + 0x4E8C, KANJI_STANDARD, // 二 + 0x5C3C, KANJI_STANDARD, // å°Œ + 0x5F10, KANJI_STANDARD, // 匐 + 0x8FE9, KANJI_STANDARD, // è¿© + 0x5302, KANJI_STANDARD, // 匂 + 0x8CD1, KANJI_STANDARD, // 賑 + 0x8089, KANJI_STANDARD, // 肉 + 0x8679, KANJI_STANDARD, // 虹 + 0x5EFF, KANJI_STANDARD, // 廿 + 0x65E5, KANJI_STANDARD, // 日 + 0x4E73, KANJI_STANDARD, // ä¹³ + 0x5165, KANJI_STANDARD, // 入 + 0x5982, KANJI_STANDARD, // 劂 + 0x5C3F, KANJI_STANDARD, // å°¿ + 0x97EE, KANJI_STANDARD, // 韮 + 0x4EFB, KANJI_STANDARD, // ä»» + 0x598A, KANJI_STANDARD, // 劊 + 0x5FCD, KANJI_STANDARD, // 忍 + 0x8A8D, KANJI_STANDARD, // 認 + 0x6FE1, KANJI_STANDARD, // æ¿¡ + 0x79B0, KANJI_STANDARD, // 犰 + 0x7962, KANJI_STANDARD, // 祢 + 0x5BE7, KANJI_STANDARD, // 寧 + 0x8471, KANJI_STANDARD, // 葱 + 0x732B, KANJI_STANDARD, // 猫 + 0x71B1, KANJI_STANDARD, // 熱 + 0x5E74, KANJI_STANDARD, // 幎 + 0x5FF5, KANJI_STANDARD, // 念 + 0x637B, KANJI_STANDARD, // 捻 + 0x649A, KANJI_STANDARD, // 撚 + 0x71C3, KANJI_STANDARD, // 燃 + 0x7C98, KANJI_STANDARD, // 粘 + 0x4E43, KANJI_STANDARD, // 乃 + 0x5EFC, KANJI_STANDARD, // 廌 + 0x4E4B, KANJI_STANDARD, // 之 + 0x57DC, KANJI_STANDARD, // 埜 + 0x56A2, KANJI_STANDARD, // 嚢 + 0x60A9, KANJI_STANDARD, // 悩 + 0x6FC3, KANJI_STANDARD, // 濃 + 0x7D0D, KANJI_STANDARD, // 玍 + 0x80FD, KANJI_STANDARD, // 胜 + 0x8133, KANJI_STANDARD, // 脳 + 0x81BF, KANJI_STANDARD, // 膿 + 0x8FB2, KANJI_STANDARD, // 蟲 + 0x8997, KANJI_STANDARD, // 芗 + 0x86A4, KANJI_STANDARD, // 蚀 + 0x5DF4, KANJI_STANDARD, // å·Ž + 0x628A, KANJI_STANDARD, // 把 + 0x64AD, KANJI_STANDARD, // 播 + 0x8987, KANJI_STANDARD, // 芇 + 0x6777, KANJI_STANDARD, // 杷 + 0x6CE2, KANJI_STANDARD, // æ³¢ + 0x6D3E, KANJI_STANDARD, // 掟 + 0x7436, KANJI_STANDARD, // 琶 + 0x7834, KANJI_STANDARD, // ç Ž + 0x5A46, KANJI_STANDARD, // 婆 + 0x7F75, KANJI_STANDARD, // 眵 + 0x82AD, KANJI_STANDARD, // 芭 + 0x99AC, KANJI_STANDARD, // 銬 + 0x4FF3, KANJI_STANDARD, // 俳 + 0x5EC3, KANJI_STANDARD, // 廃 + 0x62DD, KANJI_STANDARD, // 拝 + 0x6392, KANJI_STANDARD, // 排 + 0x6557, KANJI_STANDARD, // 敗 + 0x676F, KANJI_STANDARD, // 杯 + 0x76C3, KANJI_STANDARD, // 盃 + 0x724C, KANJI_STANDARD, // 牌 + 0x80CC, KANJI_STANDARD, // 背 + 0x80BA, KANJI_STANDARD, // 肺 + 0x8F29, KANJI_STANDARD, // 茩 + 0x914D, KANJI_STANDARD, // 配 + 0x500D, KANJI_STANDARD, // 倍 + 0x57F9, KANJI_STANDARD, // 培 + 0x5A92, KANJI_STANDARD, // 媒 + 0x6885, KANJI_STANDARD, // 梅 + 0x6973, KANJI_STANDARD, // 楳 + 0x7164, KANJI_STANDARD, // ç…€ + 0x72FD, KANJI_STANDARD, // 狜 + 0x8CB7, KANJI_STANDARD, // è²· + 0x58F2, KANJI_STANDARD, // 売 + 0x8CE0, KANJI_STANDARD, // è³  + 0x966A, KANJI_STANDARD, // 陪 + 0x9019, KANJI_STANDARD, // 這 + 0x877F, KANJI_STANDARD, // 蝿 + 0x79E4, KANJI_STANDARD, // ç§€ + 0x77E7, KANJI_STANDARD, // 矧 + 0x8429, KANJI_STANDARD, // 萩 + 0x4F2F, KANJI_STANDARD, // 䌯 + 0x5265, KANJI_STANDARD, // 剥 + 0x535A, KANJI_STANDARD, // 博 + 0x62CD, KANJI_STANDARD, // 拍 + 0x67CF, KANJI_STANDARD, // 柏 + 0x6CCA, KANJI_STANDARD, // 泊 + 0x767D, KANJI_STANDARD, // 癜 + 0x7B94, KANJI_STANDARD, // 箔 + 0x7C95, KANJI_STANDARD, // 粕 + 0x8236, KANJI_STANDARD, // 舶 + 0x8584, KANJI_STANDARD, // 薄 + 0x8FEB, KANJI_STANDARD, // è¿« + 0x66DD, KANJI_STANDARD, // 曝 + 0x6F20, KANJI_STANDARD, // 挠 + 0x7206, KANJI_STANDARD, // 爆 + 0x7E1B, KANJI_STANDARD, // 羛 + 0x83AB, KANJI_STANDARD, // 莫 + 0x99C1, KANJI_STANDARD, // 駁 + 0x9EA6, KANJI_STANDARD, // 麊 + 0x51FD, KANJI_STANDARD, // 凜 + 0x7BB1, KANJI_STANDARD, // ç®± + 0x7872, KANJI_STANDARD, // 硲 + 0x7BB8, KANJI_STANDARD, // 箞 + 0x8087, KANJI_STANDARD, // 肇 + 0x7B48, KANJI_STANDARD, // 筈 + 0x6AE8, KANJI_STANDARD, // 櫚 + 0x5E61, KANJI_STANDARD, // 幡 + 0x808C, KANJI_STANDARD, // 肌 + 0x7551, KANJI_STANDARD, // 畑 + 0x7560, KANJI_STANDARD, // 畠 + 0x516B, KANJI_STANDARD, // 八 + 0x9262, KANJI_STANDARD, // 鉢 + 0x6E8C, KANJI_STANDARD, // 溌 + 0x767A, KANJI_STANDARD, // 発 + 0x9197, KANJI_STANDARD, // 醗 + 0x9AEA, KANJI_STANDARD, // 髪 + 0x4F10, KANJI_STANDARD, // 䌐 + 0x7F70, KANJI_STANDARD, // 眰 + 0x629C, KANJI_STANDARD, // 抜 + 0x7B4F, KANJI_STANDARD, // 筏 + 0x95A5, KANJI_STANDARD, // 閥 + 0x9CE9, KANJI_STANDARD, // 鳩 + 0x567A, KANJI_STANDARD, // 噺 + 0x5859, KANJI_STANDARD, // 塙 + 0x86E4, KANJI_STANDARD, // 蛀 + 0x96BC, KANJI_STANDARD, // 隌 + 0x4F34, KANJI_STANDARD, // 䌎 + 0x5224, KANJI_STANDARD, // 刀 + 0x534A, KANJI_STANDARD, // 半 + 0x53CD, KANJI_STANDARD, // 反 + 0x53DB, KANJI_STANDARD, // 叛 + 0x5E06, KANJI_STANDARD, // 垆 + 0x642C, KANJI_STANDARD, // 搬 + 0x6591, KANJI_STANDARD, // 斑 + 0x677F, KANJI_STANDARD, // 板 + 0x6C3E, KANJI_STANDARD, // æ°Ÿ + 0x6C4E, KANJI_STANDARD, // 汎 + 0x7248, KANJI_STANDARD, // 版 + 0x72AF, KANJI_STANDARD, // 犯 + 0x73ED, KANJI_STANDARD, // 班 + 0x7554, KANJI_STANDARD, // 畔 + 0x7E41, KANJI_STANDARD, // 繁 + 0x822C, KANJI_STANDARD, // 般 + 0x85E9, KANJI_STANDARD, // 藩 + 0x8CA9, KANJI_STANDARD, // 販 + 0x7BC4, KANJI_STANDARD, // 範 + 0x91C6, KANJI_STANDARD, // 釆 + 0x7169, KANJI_STANDARD, // 煩 + 0x9812, KANJI_STANDARD, // 頒 + 0x98EF, KANJI_STANDARD, // 飯 + 0x633D, KANJI_STANDARD, // 挜 + 0x6669, KANJI_STANDARD, // 晩 + 0x756A, KANJI_STANDARD, // 番 + 0x76E4, KANJI_STANDARD, // 盀 + 0x78D0, KANJI_STANDARD, // 磐 + 0x8543, KANJI_STANDARD, // 蕃 + 0x86EE, KANJI_STANDARD, // 蛮 + 0x532A, KANJI_STANDARD, // 匪 + 0x5351, KANJI_STANDARD, // 卑 + 0x5426, KANJI_STANDARD, // 吊 + 0x5983, KANJI_STANDARD, // 劃 + 0x5E87, KANJI_STANDARD, // 庇 + 0x5F7C, KANJI_STANDARD, // 圌 + 0x60B2, KANJI_STANDARD, // 悲 + 0x6249, KANJI_STANDARD, // 扉 + 0x6279, KANJI_STANDARD, // 批 + 0x62AB, KANJI_STANDARD, // 披 + 0x6590, KANJI_STANDARD, // 斐 + 0x6BD4, KANJI_STANDARD, // 比 + 0x6CCC, KANJI_STANDARD, // 泌 + 0x75B2, KANJI_STANDARD, // 疲 + 0x76AE, KANJI_STANDARD, // 皮 + 0x7891, KANJI_STANDARD, // 碑 + 0x79D8, KANJI_STANDARD, // 秘 + 0x7DCB, KANJI_STANDARD, // 緋 + 0x7F77, KANJI_STANDARD, // 眷 + 0x80A5, KANJI_STANDARD, // 肥 + 0x88AB, KANJI_STANDARD, // 被 + 0x8AB9, KANJI_STANDARD, // 誹 + 0x8CBB, KANJI_STANDARD, // è²» + 0x907F, KANJI_STANDARD, // 避 + 0x975E, KANJI_STANDARD, // 非 + 0x98DB, KANJI_STANDARD, // 飛 + 0x6A0B, KANJI_STANDARD, // æš‹ + 0x7C38, KANJI_STANDARD, // ç°ž + 0x5099, KANJI_STANDARD, // 備 + 0x5C3E, KANJI_STANDARD, // å°Ÿ + 0x5FAE, KANJI_STANDARD, // 埮 + 0x6787, KANJI_STANDARD, // 枇 + 0x6BD8, KANJI_STANDARD, // 毘 + 0x7435, KANJI_STANDARD, // 琵 + 0x7709, KANJI_STANDARD, // 眉 + 0x7F8E, KANJI_STANDARD, // 矎 + 0x9F3B, KANJI_STANDARD, // 錻 + 0x67CA, KANJI_STANDARD, // 柊 + 0x7A17, KANJI_STANDARD, // 繗 + 0x5339, KANJI_STANDARD, // 匹 + 0x758B, KANJI_STANDARD, // 疋 + 0x9AED, KANJI_STANDARD, // é«­ + 0x5F66, KANJI_STANDARD, // 圊 + 0x819D, KANJI_STANDARD, // 膝 + 0x83F1, KANJI_STANDARD, // 菱 + 0x8098, KANJI_STANDARD, // 肘 + 0x5F3C, KANJI_STANDARD, // 匌 + 0x5FC5, KANJI_STANDARD, // 必 + 0x7562, KANJI_STANDARD, // 畢 + 0x7B46, KANJI_STANDARD, // 筆 + 0x903C, KANJI_STANDARD, // 逌 + 0x6867, KANJI_STANDARD, // æ¡§ + 0x59EB, KANJI_STANDARD, // å§« + 0x5A9B, KANJI_STANDARD, // 媛 + 0x7D10, KANJI_STANDARD, // 玐 + 0x767E, KANJI_STANDARD, // 癟 + 0x8B2C, KANJI_STANDARD, // 謬 + 0x4FF5, KANJI_STANDARD, // 俵 + 0x5F6A, KANJI_STANDARD, // 圪 + 0x6A19, KANJI_STANDARD, // æš™ + 0x6C37, KANJI_STANDARD, // æ°· + 0x6F02, KANJI_STANDARD, // 挂 + 0x74E2, KANJI_STANDARD, // 瓢 + 0x7968, KANJI_STANDARD, // 祚 + 0x8868, KANJI_STANDARD, // 衚 + 0x8A55, KANJI_STANDARD, // 評 + 0x8C79, KANJI_STANDARD, // è±¹ + 0x5EDF, KANJI_STANDARD, // 廟 + 0x63CF, KANJI_STANDARD, // 描 + 0x75C5, KANJI_STANDARD, // 病 + 0x79D2, KANJI_STANDARD, // 秒 + 0x82D7, KANJI_STANDARD, // 苗 + 0x9328, KANJI_STANDARD, // 錹 + 0x92F2, KANJI_STANDARD, // 鋲 + 0x849C, KANJI_STANDARD, // 蒜 + 0x86ED, KANJI_STANDARD, // 蛭 + 0x9C2D, KANJI_STANDARD, // é°­ + 0x54C1, KANJI_STANDARD, // 品 + 0x5F6C, KANJI_STANDARD, // 圬 + 0x658C, KANJI_STANDARD, // 斌 + 0x6D5C, KANJI_STANDARD, // 浜 + 0x7015, KANJI_STANDARD, // 瀕 + 0x8CA7, KANJI_STANDARD, // è²§ + 0x8CD3, KANJI_STANDARD, // 賓 + 0x983B, KANJI_STANDARD, // é » + 0x654F, KANJI_STANDARD, // 敏 + 0x74F6, KANJI_STANDARD, // 瓶 + 0x4E0D, KANJI_STANDARD, // 䞍 + 0x4ED8, KANJI_STANDARD, // 付 + 0x57E0, KANJI_STANDARD, // 埠 + 0x592B, KANJI_STANDARD, // 倫 + 0x5A66, KANJI_STANDARD, // 婊 + 0x5BCC, KANJI_STANDARD, // 富 + 0x51A8, KANJI_STANDARD, // 冚 + 0x5E03, KANJI_STANDARD, // 垃 + 0x5E9C, KANJI_STANDARD, // 府 + 0x6016, KANJI_STANDARD, // 怖 + 0x6276, KANJI_STANDARD, // 扶 + 0x6577, KANJI_STANDARD, // 敷 + 0x65A7, KANJI_STANDARD, // 斧 + 0x666E, KANJI_STANDARD, // 普 + 0x6D6E, KANJI_STANDARD, // æµ® + 0x7236, KANJI_STANDARD, // 父 + 0x7B26, KANJI_STANDARD, // 笊 + 0x8150, KANJI_STANDARD, // 腐 + 0x819A, KANJI_STANDARD, // 膚 + 0x8299, KANJI_STANDARD, // 芙 + 0x8B5C, KANJI_STANDARD, // 譜 + 0x8CA0, KANJI_STANDARD, // è²  + 0x8CE6, KANJI_STANDARD, // 賊 + 0x8D74, KANJI_STANDARD, // 赎 + 0x961C, KANJI_STANDARD, // 阜 + 0x9644, KANJI_STANDARD, // 附 + 0x4FAE, KANJI_STANDARD, // 䟮 + 0x64AB, KANJI_STANDARD, // 撫 + 0x6B66, KANJI_STANDARD, // æ­Š + 0x821E, KANJI_STANDARD, // 舞 + 0x8461, KANJI_STANDARD, // 葡 + 0x856A, KANJI_STANDARD, // 蕪 + 0x90E8, KANJI_STANDARD, // 郚 + 0x5C01, KANJI_STANDARD, // 封 + 0x6953, KANJI_STANDARD, // 楓 + 0x98A8, KANJI_STANDARD, // 颚 + 0x847A, KANJI_STANDARD, // 葺 + 0x8557, KANJI_STANDARD, // 蕗 + 0x4F0F, KANJI_STANDARD, // 䌏 + 0x526F, KANJI_STANDARD, // 副 + 0x5FA9, KANJI_STANDARD, // 埩 + 0x5E45, KANJI_STANDARD, // 幅 + 0x670D, KANJI_STANDARD, // 服 + 0x798F, KANJI_STANDARD, // 犏 + 0x8179, KANJI_STANDARD, // 腹 + 0x8907, KANJI_STANDARD, // 耇 + 0x8986, KANJI_STANDARD, // 芆 + 0x6DF5, KANJI_STANDARD, // æ·µ + 0x5F17, KANJI_STANDARD, // 北 + 0x6255, KANJI_STANDARD, // 払 + 0x6CB8, KANJI_STANDARD, // 沞 + 0x4ECF, KANJI_STANDARD, // 仏 + 0x7269, KANJI_STANDARD, // 物 + 0x9B92, KANJI_STANDARD, // 鮒 + 0x5206, KANJI_STANDARD, // 分 + 0x543B, KANJI_STANDARD, // 吻 + 0x5674, KANJI_STANDARD, // 噎 + 0x58B3, KANJI_STANDARD, // 墳 + 0x61A4, KANJI_STANDARD, // 憀 + 0x626E, KANJI_STANDARD, // 扮 + 0x711A, KANJI_STANDARD, // 焚 + 0x596E, KANJI_STANDARD, // 奮 + 0x7C89, KANJI_STANDARD, // 粉 + 0x7CDE, KANJI_STANDARD, // 糞 + 0x7D1B, KANJI_STANDARD, // 箛 + 0x96F0, KANJI_STANDARD, // 雰 + 0x6587, KANJI_STANDARD, // 文 + 0x805E, KANJI_STANDARD, // 聞 + 0x4E19, KANJI_STANDARD, // 侙 + 0x4F75, KANJI_STANDARD, // 䜵 + 0x5175, KANJI_STANDARD, // 兵 + 0x5840, KANJI_STANDARD, // 塀 + 0x5E63, KANJI_STANDARD, // å¹£ + 0x5E73, KANJI_STANDARD, // å¹³ + 0x5F0A, KANJI_STANDARD, // 匊 + 0x67C4, KANJI_STANDARD, // 柄 + 0x4E26, KANJI_STANDARD, // 䞊 + 0x853D, KANJI_STANDARD, // 蔜 + 0x9589, KANJI_STANDARD, // 閉 + 0x965B, KANJI_STANDARD, // 陛 + 0x7C73, KANJI_STANDARD, // ç±³ + 0x9801, KANJI_STANDARD, // 頁 + 0x50FB, KANJI_STANDARD, // 僻 + 0x58C1, KANJI_STANDARD, // 壁 + 0x7656, KANJI_STANDARD, // 癖 + 0x78A7, KANJI_STANDARD, // 碧 + 0x5225, KANJI_STANDARD, // 別 + 0x77A5, KANJI_STANDARD, // 瞥 + 0x8511, KANJI_STANDARD, // 蔑 + 0x7B86, KANJI_STANDARD, // 箆 + 0x504F, KANJI_STANDARD, // 偏 + 0x5909, KANJI_STANDARD, // 倉 + 0x7247, KANJI_STANDARD, // 片 + 0x7BC7, KANJI_STANDARD, // 篇 + 0x7DE8, KANJI_STANDARD, // ç·š + 0x8FBA, KANJI_STANDARD, // 蟺 + 0x8FD4, KANJI_STANDARD, // 返 + 0x904D, KANJI_STANDARD, // 遍 + 0x4FBF, KANJI_STANDARD, // 䟿 + 0x52C9, KANJI_STANDARD, // 勉 + 0x5A29, KANJI_STANDARD, // åš© + 0x5F01, KANJI_STANDARD, // 匁 + 0x97AD, KANJI_STANDARD, // 鞭 + 0x4FDD, KANJI_STANDARD, // 保 + 0x8217, KANJI_STANDARD, // 舗 + 0x92EA, KANJI_STANDARD, // 鋪 + 0x5703, KANJI_STANDARD, // 圃 + 0x6355, KANJI_STANDARD, // 捕 + 0x6B69, KANJI_STANDARD, // æ­© + 0x752B, KANJI_STANDARD, // 甫 + 0x88DC, KANJI_STANDARD, // 補 + 0x8F14, KANJI_STANDARD, // 茔 + 0x7A42, KANJI_STANDARD, // 穂 + 0x52DF, KANJI_STANDARD, // 募 + 0x5893, KANJI_STANDARD, // 墓 + 0x6155, KANJI_STANDARD, // 慕 + 0x620A, KANJI_STANDARD, // 戊 + 0x66AE, KANJI_STANDARD, // 暮 + 0x6BCD, KANJI_STANDARD, // 母 + 0x7C3F, KANJI_STANDARD, // ç°¿ + 0x83E9, KANJI_STANDARD, // 菩 + 0x5023, KANJI_STANDARD, // 倣 + 0x4FF8, KANJI_STANDARD, // 俞 + 0x5305, KANJI_STANDARD, // 包 + 0x5446, KANJI_STANDARD, // 呆 + 0x5831, KANJI_STANDARD, // å ± + 0x5949, KANJI_STANDARD, // 奉 + 0x5B9D, KANJI_STANDARD, // 宝 + 0x5CF0, KANJI_STANDARD, // å³° + 0x5CEF, KANJI_STANDARD, // 峯 + 0x5D29, KANJI_STANDARD, // 厩 + 0x5E96, KANJI_STANDARD, // 庖 + 0x62B1, KANJI_STANDARD, // 抱 + 0x6367, KANJI_STANDARD, // 捧 + 0x653E, KANJI_STANDARD, // 攟 + 0x65B9, KANJI_STANDARD, // 方 + 0x670B, KANJI_STANDARD, // 朋 + 0x6CD5, KANJI_STANDARD, // 法 + 0x6CE1, KANJI_STANDARD, // 泡 + 0x70F9, KANJI_STANDARD, // 烹 + 0x7832, KANJI_STANDARD, // ç ² + 0x7E2B, KANJI_STANDARD, // çž« + 0x80DE, KANJI_STANDARD, // 胞 + 0x82B3, KANJI_STANDARD, // 芳 + 0x840C, KANJI_STANDARD, // 萌 + 0x84EC, KANJI_STANDARD, // 蓬 + 0x8702, KANJI_STANDARD, // 蜂 + 0x8912, KANJI_STANDARD, // 耒 + 0x8A2A, KANJI_STANDARD, // 蚪 + 0x8C4A, KANJI_STANDARD, // 豊 + 0x90A6, KANJI_STANDARD, // 邩 + 0x92D2, KANJI_STANDARD, // 鋒 + 0x98FD, KANJI_STANDARD, // 飜 + 0x9CF3, KANJI_STANDARD, // é³³ + 0x9D6C, KANJI_STANDARD, // 鵬 + 0x4E4F, KANJI_STANDARD, // 乏 + 0x4EA1, KANJI_STANDARD, // 亡 + 0x508D, KANJI_STANDARD, // 傍 + 0x5256, KANJI_STANDARD, // 剖 + 0x574A, KANJI_STANDARD, // 坊 + 0x59A8, KANJI_STANDARD, // 劚 + 0x5E3D, KANJI_STANDARD, // åžœ + 0x5FD8, KANJI_STANDARD, // 忘 + 0x5FD9, KANJI_STANDARD, // 忙 + 0x623F, KANJI_STANDARD, // 房 + 0x66B4, KANJI_STANDARD, // 暎 + 0x671B, KANJI_STANDARD, // 望 + 0x67D0, KANJI_STANDARD, // 某 + 0x68D2, KANJI_STANDARD, // 棒 + 0x5192, KANJI_STANDARD, // 冒 + 0x7D21, KANJI_STANDARD, // 玡 + 0x80AA, KANJI_STANDARD, // 肪 + 0x81A8, KANJI_STANDARD, // 膚 + 0x8B00, KANJI_STANDARD, // 謀 + 0x8C8C, KANJI_STANDARD, // 貌 + 0x8CBF, KANJI_STANDARD, // 貿 + 0x927E, KANJI_STANDARD, // 鉟 + 0x9632, KANJI_STANDARD, // 防 + 0x5420, KANJI_STANDARD, // 吠 + 0x982C, KANJI_STANDARD, // é ¬ + 0x5317, KANJI_STANDARD, // 北 + 0x50D5, KANJI_STANDARD, // 僕 + 0x535C, KANJI_STANDARD, // 卜 + 0x58A8, KANJI_STANDARD, // 墚 + 0x64B2, KANJI_STANDARD, // 撲 + 0x6734, KANJI_STANDARD, // 朎 + 0x7267, KANJI_STANDARD, // 牧 + 0x7766, KANJI_STANDARD, // 睊 + 0x7A46, KANJI_STANDARD, // 穆 + 0x91E6, KANJI_STANDARD, // 釩 + 0x52C3, KANJI_STANDARD, // 勃 + 0x6CA1, KANJI_STANDARD, // 没 + 0x6B86, KANJI_STANDARD, // 殆 + 0x5800, KANJI_STANDARD, // 堀 + 0x5E4C, KANJI_STANDARD, // 幌 + 0x5954, KANJI_STANDARD, // 奔 + 0x672C, KANJI_STANDARD, // 本 + 0x7FFB, KANJI_STANDARD, // ç¿» + 0x51E1, KANJI_STANDARD, // 凡 + 0x76C6, KANJI_STANDARD, // 盆 + 0x6469, KANJI_STANDARD, // 摩 + 0x78E8, KANJI_STANDARD, // 磚 + 0x9B54, KANJI_STANDARD, // 魔 + 0x9EBB, KANJI_STANDARD, // 麻 + 0x57CB, KANJI_STANDARD, // 埋 + 0x59B9, KANJI_STANDARD, // 効 + 0x6627, KANJI_STANDARD, // 昧 + 0x679A, KANJI_STANDARD, // 枚 + 0x6BCE, KANJI_STANDARD, // 毎 + 0x54E9, KANJI_STANDARD, // 哩 + 0x69D9, KANJI_STANDARD, // 槙 + 0x5E55, KANJI_STANDARD, // 幕 + 0x819C, KANJI_STANDARD, // 膜 + 0x6795, KANJI_STANDARD, // 枕 + 0x9BAA, KANJI_STANDARD, // 鮪 + 0x67FE, KANJI_STANDARD, // 柟 + 0x9C52, KANJI_STANDARD, // 鱒 + 0x685D, KANJI_STANDARD, // 桝 + 0x4EA6, KANJI_STANDARD, // 亊 + 0x4FE3, KANJI_STANDARD, // ä¿£ + 0x53C8, KANJI_STANDARD, // 又 + 0x62B9, KANJI_STANDARD, // 抹 + 0x672B, KANJI_STANDARD, // 末 + 0x6CAB, KANJI_STANDARD, // 沫 + 0x8FC4, KANJI_STANDARD, // 迄 + 0x4FAD, KANJI_STANDARD, // 䟭 + 0x7E6D, KANJI_STANDARD, // ç¹­ + 0x9EBF, KANJI_STANDARD, // 麿 + 0x4E07, KANJI_STANDARD, // 侇 + 0x6162, KANJI_STANDARD, // 慢 + 0x6E80, KANJI_STANDARD, // 満 + 0x6F2B, KANJI_STANDARD, // 挫 + 0x8513, KANJI_STANDARD, // 蔓 + 0x5473, KANJI_STANDARD, // 味 + 0x672A, KANJI_STANDARD, // 未 + 0x9B45, KANJI_STANDARD, // 魅 + 0x5DF3, KANJI_STANDARD, // å·³ + 0x7B95, KANJI_STANDARD, // 箕 + 0x5CAC, KANJI_STANDARD, // 岬 + 0x5BC6, KANJI_STANDARD, // 密 + 0x871C, KANJI_STANDARD, // 蜜 + 0x6E4A, KANJI_STANDARD, // 湊 + 0x84D1, KANJI_STANDARD, // 蓑 + 0x7A14, KANJI_STANDARD, // 織 + 0x8108, KANJI_STANDARD, // 脈 + 0x5999, KANJI_STANDARD, // 劙 + 0x7C8D, KANJI_STANDARD, // 粍 + 0x6C11, KANJI_STANDARD, // 民 + 0x7720, KANJI_STANDARD, // 眠 + 0x52D9, KANJI_STANDARD, // 務 + 0x5922, KANJI_STANDARD, // 倢 + 0x7121, KANJI_STANDARD, // 無 + 0x725F, KANJI_STANDARD, // 牟 + 0x77DB, KANJI_STANDARD, // 矛 + 0x9727, KANJI_STANDARD, // 霧 + 0x9D61, KANJI_STANDARD, // 鵡 + 0x690B, KANJI_STANDARD, // 怋 + 0x5A7F, KANJI_STANDARD, // å©¿ + 0x5A18, KANJI_STANDARD, // 嚘 + 0x51A5, KANJI_STANDARD, // 冥 + 0x540D, KANJI_STANDARD, // 名 + 0x547D, KANJI_STANDARD, // 呜 + 0x660E, KANJI_STANDARD, // 明 + 0x76DF, KANJI_STANDARD, // 盟 + 0x8FF7, KANJI_STANDARD, // è¿· + 0x9298, KANJI_STANDARD, // 銘 + 0x9CF4, KANJI_STANDARD, // 鳎 + 0x59EA, KANJI_STANDARD, // 姪 + 0x725D, KANJI_STANDARD, // 牝 + 0x6EC5, KANJI_STANDARD, // 滅 + 0x514D, KANJI_STANDARD, // 免 + 0x68C9, KANJI_STANDARD, // 棉 + 0x7DBF, KANJI_STANDARD, // ç¶¿ + 0x7DEC, KANJI_STANDARD, // ç·¬ + 0x9762, KANJI_STANDARD, // 面 + 0x9EBA, KANJI_STANDARD, // 麺 + 0x6478, KANJI_STANDARD, // 摞 + 0x6A21, KANJI_STANDARD, // æš¡ + 0x8302, KANJI_STANDARD, // 茂 + 0x5984, KANJI_STANDARD, // 劄 + 0x5B5F, KANJI_STANDARD, // 孟 + 0x6BDB, KANJI_STANDARD, // 毛 + 0x731B, KANJI_STANDARD, // 猛 + 0x76F2, KANJI_STANDARD, // 盲 + 0x7DB2, KANJI_STANDARD, // ç¶² + 0x8017, KANJI_STANDARD, // 耗 + 0x8499, KANJI_STANDARD, // 蒙 + 0x5132, KANJI_STANDARD, // 儲 + 0x6728, KANJI_STANDARD, // 朚 + 0x9ED9, KANJI_STANDARD, // 黙 + 0x76EE, KANJI_STANDARD, // 目 + 0x6762, KANJI_STANDARD, // 杢 + 0x52FF, KANJI_STANDARD, // 勿 + 0x9905, KANJI_STANDARD, // 逅 + 0x5C24, KANJI_STANDARD, // å°€ + 0x623B, KANJI_STANDARD, // 戻 + 0x7C7E, KANJI_STANDARD, // 籟 + 0x8CB0, KANJI_STANDARD, // è²° + 0x554F, KANJI_STANDARD, // 問 + 0x60B6, KANJI_STANDARD, // 悶 + 0x7D0B, KANJI_STANDARD, // 箋 + 0x9580, KANJI_STANDARD, // 門 + 0x5301, KANJI_STANDARD, // 匁 + 0x4E5F, KANJI_STANDARD, // 也 + 0x51B6, KANJI_STANDARD, // 冶 + 0x591C, KANJI_STANDARD, // 倜 + 0x723A, KANJI_STANDARD, // 爺 + 0x8036, KANJI_STANDARD, // 耶 + 0x91CE, KANJI_STANDARD, // 野 + 0x5F25, KANJI_STANDARD, // 匥 + 0x77E2, KANJI_STANDARD, // 矢 + 0x5384, KANJI_STANDARD, // 厄 + 0x5F79, KANJI_STANDARD, // 圹 + 0x7D04, KANJI_STANDARD, // 箄 + 0x85AC, KANJI_STANDARD, // 薬 + 0x8A33, KANJI_STANDARD, // èš³ + 0x8E8D, KANJI_STANDARD, // 躍 + 0x9756, KANJI_STANDARD, // 靖 + 0x67F3, KANJI_STANDARD, // 柳 + 0x85AE, KANJI_STANDARD, // 薮 + 0x9453, KANJI_STANDARD, // 鑓 + 0x6109, KANJI_STANDARD, // 愉 + 0x6108, KANJI_STANDARD, // 愈 + 0x6CB9, KANJI_STANDARD, // æ²¹ + 0x7652, KANJI_STANDARD, // 癒 + 0x8AED, KANJI_STANDARD, // è«­ + 0x8F38, KANJI_STANDARD, // 茞 + 0x552F, KANJI_STANDARD, // 唯 + 0x4F51, KANJI_STANDARD, // 䜑 + 0x512A, KANJI_STANDARD, // 優 + 0x52C7, KANJI_STANDARD, // 勇 + 0x53CB, KANJI_STANDARD, // 友 + 0x5BA5, KANJI_STANDARD, // 宥 + 0x5E7D, KANJI_STANDARD, // 幜 + 0x60A0, KANJI_STANDARD, // 悠 + 0x6182, KANJI_STANDARD, // 憂 + 0x63D6, KANJI_STANDARD, // 揖 + 0x6709, KANJI_STANDARD, // 有 + 0x67DA, KANJI_STANDARD, // 柚 + 0x6E67, KANJI_STANDARD, // æ¹§ + 0x6D8C, KANJI_STANDARD, // 涌 + 0x7336, KANJI_STANDARD, // 猶 + 0x7337, KANJI_STANDARD, // 猷 + 0x7531, KANJI_STANDARD, // 由 + 0x7950, KANJI_STANDARD, // 祐 + 0x88D5, KANJI_STANDARD, // 裕 + 0x8A98, KANJI_STANDARD, // 誘 + 0x904A, KANJI_STANDARD, // 遊 + 0x9091, KANJI_STANDARD, // 邑 + 0x90F5, KANJI_STANDARD, // 郵 + 0x96C4, KANJI_STANDARD, // 雄 + 0x878D, KANJI_STANDARD, // 融 + 0x5915, KANJI_STANDARD, // 倕 + 0x4E88, KANJI_STANDARD, // 予 + 0x4F59, KANJI_STANDARD, // 䜙 + 0x4E0E, KANJI_STANDARD, // 侎 + 0x8A89, KANJI_STANDARD, // 誉 + 0x8F3F, KANJI_STANDARD, // 茿 + 0x9810, KANJI_STANDARD, // 預 + 0x50AD, KANJI_STANDARD, // 傭 + 0x5E7C, KANJI_STANDARD, // 幌 + 0x5996, KANJI_STANDARD, // 劖 + 0x5BB9, KANJI_STANDARD, // 容 + 0x5EB8, KANJI_STANDARD, // 庞 + 0x63DA, KANJI_STANDARD, // 揚 + 0x63FA, KANJI_STANDARD, // 揺 + 0x64C1, KANJI_STANDARD, // 擁 + 0x66DC, KANJI_STANDARD, // 曜 + 0x694A, KANJI_STANDARD, // 楊 + 0x69D8, KANJI_STANDARD, // 様 + 0x6D0B, KANJI_STANDARD, // 掋 + 0x6EB6, KANJI_STANDARD, // 溶 + 0x7194, KANJI_STANDARD, // 熔 + 0x7528, KANJI_STANDARD, // 甹 + 0x7AAF, KANJI_STANDARD, // 窯 + 0x7F8A, KANJI_STANDARD, // 矊 + 0x8000, KANJI_STANDARD, // 耀 + 0x8449, KANJI_STANDARD, // 葉 + 0x84C9, KANJI_STANDARD, // 蓉 + 0x8981, KANJI_STANDARD, // 芁 + 0x8B21, KANJI_STANDARD, // 謡 + 0x8E0A, KANJI_STANDARD, // 螊 + 0x9065, KANJI_STANDARD, // 遥 + 0x967D, KANJI_STANDARD, // 陜 + 0x990A, KANJI_STANDARD, // 逊 + 0x617E, KANJI_STANDARD, // æ…Ÿ + 0x6291, KANJI_STANDARD, // 抑 + 0x6B32, KANJI_STANDARD, // 欲 + 0x6C83, KANJI_STANDARD, // 沃 + 0x6D74, KANJI_STANDARD, // 济 + 0x7FCC, KANJI_STANDARD, // 翌 + 0x7FFC, KANJI_STANDARD, // 翌 + 0x6DC0, KANJI_STANDARD, // 淀 + 0x7F85, KANJI_STANDARD, // 矅 + 0x87BA, KANJI_STANDARD, // 螺 + 0x88F8, KANJI_STANDARD, // 裞 + 0x6765, KANJI_STANDARD, // 来 + 0x83B1, KANJI_STANDARD, // 莱 + 0x983C, KANJI_STANDARD, // é Œ + 0x96F7, KANJI_STANDARD, // 雷 + 0x6D1B, KANJI_STANDARD, // 掛 + 0x7D61, KANJI_STANDARD, // 絡 + 0x843D, KANJI_STANDARD, // 萜 + 0x916A, KANJI_STANDARD, // 酪 + 0x4E71, KANJI_STANDARD, // ä¹± + 0x5375, KANJI_STANDARD, // 卵 + 0x5D50, KANJI_STANDARD, // 嵐 + 0x6B04, KANJI_STANDARD, // 欄 + 0x6FEB, KANJI_STANDARD, // æ¿« + 0x85CD, KANJI_STANDARD, // 藍 + 0x862D, KANJI_STANDARD, // 蘭 + 0x89A7, KANJI_STANDARD, // 芧 + 0x5229, KANJI_STANDARD, // 利 + 0x540F, KANJI_STANDARD, // 吏 + 0x5C65, KANJI_STANDARD, // å±¥ + 0x674E, KANJI_STANDARD, // 李 + 0x68A8, KANJI_STANDARD, // 梚 + 0x7406, KANJI_STANDARD, // 理 + 0x7483, KANJI_STANDARD, // 璃 + 0x75E2, KANJI_STANDARD, // 痢 + 0x88CF, KANJI_STANDARD, // 裏 + 0x88E1, KANJI_STANDARD, // 裡 + 0x91CC, KANJI_STANDARD, // 里 + 0x96E2, KANJI_STANDARD, // 離 + 0x9678, KANJI_STANDARD, // 陾 + 0x5F8B, KANJI_STANDARD, // 埋 + 0x7387, KANJI_STANDARD, // 率 + 0x7ACB, KANJI_STANDARD, // 立 + 0x844E, KANJI_STANDARD, // 葎 + 0x63A0, KANJI_STANDARD, // 掠 + 0x7565, KANJI_STANDARD, // 略 + 0x5289, KANJI_STANDARD, // 劉 + 0x6D41, KANJI_STANDARD, // 流 + 0x6E9C, KANJI_STANDARD, // 溜 + 0x7409, KANJI_STANDARD, // 琉 + 0x7559, KANJI_STANDARD, // 留 + 0x786B, KANJI_STANDARD, // ç¡« + 0x7C92, KANJI_STANDARD, // 粒 + 0x9686, KANJI_STANDARD, // 隆 + 0x7ADC, KANJI_STANDARD, // 竜 + 0x9F8D, KANJI_STANDARD, // 韍 + 0x4FB6, KANJI_STANDARD, // 䟶 + 0x616E, KANJI_STANDARD, // 慮 + 0x65C5, KANJI_STANDARD, // 旅 + 0x865C, KANJI_STANDARD, // 虜 + 0x4E86, KANJI_STANDARD, // 了 + 0x4EAE, KANJI_STANDARD, // 亮 + 0x50DA, KANJI_STANDARD, // 僚 + 0x4E21, KANJI_STANDARD, // äž¡ + 0x51CC, KANJI_STANDARD, // 凌 + 0x5BEE, KANJI_STANDARD, // 寮 + 0x6599, KANJI_STANDARD, // 料 + 0x6881, KANJI_STANDARD, // 梁 + 0x6DBC, KANJI_STANDARD, // æ¶Œ + 0x731F, KANJI_STANDARD, // 猟 + 0x7642, KANJI_STANDARD, // 療 + 0x77AD, KANJI_STANDARD, // 瞭 + 0x7A1C, KANJI_STANDARD, // 繜 + 0x7CE7, KANJI_STANDARD, // ç³§ + 0x826F, KANJI_STANDARD, // 良 + 0x8AD2, KANJI_STANDARD, // 諒 + 0x907C, KANJI_STANDARD, // 遌 + 0x91CF, KANJI_STANDARD, // 量 + 0x9675, KANJI_STANDARD, // 陵 + 0x9818, KANJI_STANDARD, // 領 + 0x529B, KANJI_STANDARD, // 力 + 0x7DD1, KANJI_STANDARD, // 緑 + 0x502B, KANJI_STANDARD, // 倫 + 0x5398, KANJI_STANDARD, // 厘 + 0x6797, KANJI_STANDARD, // 林 + 0x6DCB, KANJI_STANDARD, // 淋 + 0x71D0, KANJI_STANDARD, // 燐 + 0x7433, KANJI_STANDARD, // 琳 + 0x81E8, KANJI_STANDARD, // 臚 + 0x8F2A, KANJI_STANDARD, // 茪 + 0x96A3, KANJI_STANDARD, // 隣 + 0x9C57, KANJI_STANDARD, // 鱗 + 0x9E9F, KANJI_STANDARD, // 麟 + 0x7460, KANJI_STANDARD, // 瑠 + 0x5841, KANJI_STANDARD, // 塁 + 0x6D99, KANJI_STANDARD, // 涙 + 0x7D2F, KANJI_STANDARD, // 环 + 0x985E, KANJI_STANDARD, // 類 + 0x4EE4, KANJI_STANDARD, // 什 + 0x4F36, KANJI_STANDARD, // 䌶 + 0x4F8B, KANJI_STANDARD, // 䟋 + 0x51B7, KANJI_STANDARD, // 冷 + 0x52B1, KANJI_STANDARD, // 励 + 0x5DBA, KANJI_STANDARD, // 嶺 + 0x601C, KANJI_STANDARD, // 怜 + 0x73B2, KANJI_STANDARD, // 玲 + 0x793C, KANJI_STANDARD, // 瀌 + 0x82D3, KANJI_STANDARD, // 苓 + 0x9234, KANJI_STANDARD, // 鈎 + 0x96B7, KANJI_STANDARD, // 隷 + 0x96F6, KANJI_STANDARD, // 零 + 0x970A, KANJI_STANDARD, // 霊 + 0x9E97, KANJI_STANDARD, // 麗 + 0x9F62, KANJI_STANDARD, // 霢 + 0x66A6, KANJI_STANDARD, // 暊 + 0x6B74, KANJI_STANDARD, // æ­Ž + 0x5217, KANJI_STANDARD, // 列 + 0x52A3, KANJI_STANDARD, // 劣 + 0x70C8, KANJI_STANDARD, // 烈 + 0x88C2, KANJI_STANDARD, // 裂 + 0x5EC9, KANJI_STANDARD, // 廉 + 0x604B, KANJI_STANDARD, // 恋 + 0x6190, KANJI_STANDARD, // 憐 + 0x6F23, KANJI_STANDARD, // 挣 + 0x7149, KANJI_STANDARD, // 煉 + 0x7C3E, KANJI_STANDARD, // ç°Ÿ + 0x7DF4, KANJI_STANDARD, // ç·Ž + 0x806F, KANJI_STANDARD, // 聯 + 0x84EE, KANJI_STANDARD, // 蓮 + 0x9023, KANJI_STANDARD, // 連 + 0x932C, KANJI_STANDARD, // 錬 + 0x5442, KANJI_STANDARD, // 呂 + 0x9B6F, KANJI_STANDARD, // é­¯ + 0x6AD3, KANJI_STANDARD, // 櫓 + 0x7089, KANJI_STANDARD, // 炉 + 0x8CC2, KANJI_STANDARD, // 賂 + 0x8DEF, KANJI_STANDARD, // è·¯ + 0x9732, KANJI_STANDARD, // 露 + 0x52B4, KANJI_STANDARD, // 劎 + 0x5A41, KANJI_STANDARD, // 婁 + 0x5ECA, KANJI_STANDARD, // 廊 + 0x5F04, KANJI_STANDARD, // 匄 + 0x6717, KANJI_STANDARD, // 朗 + 0x697C, KANJI_STANDARD, // 楌 + 0x6994, KANJI_STANDARD, // 抔 + 0x6D6A, KANJI_STANDARD, // 浪 + 0x6F0F, KANJI_STANDARD, // 挏 + 0x7262, KANJI_STANDARD, // 牢 + 0x72FC, KANJI_STANDARD, // 狌 + 0x7BED, KANJI_STANDARD, // 篭 + 0x8001, KANJI_STANDARD, // 老 + 0x807E, KANJI_STANDARD, // 聟 + 0x874B, KANJI_STANDARD, // 蝋 + 0x90CE, KANJI_STANDARD, // 郎 + 0x516D, KANJI_STANDARD, // 六 + 0x9E93, KANJI_STANDARD, // 麓 + 0x7984, KANJI_STANDARD, // 穄 + 0x808B, KANJI_STANDARD, // 肋 + 0x9332, KANJI_STANDARD, // 録 + 0x8AD6, KANJI_STANDARD, // 論 + 0x502D, KANJI_STANDARD, // 倭 + 0x548C, KANJI_STANDARD, // 和 + 0x8A71, KANJI_STANDARD, // 話 + 0x6B6A, KANJI_STANDARD, // æ­ª + 0x8CC4, KANJI_STANDARD, // 賄 + 0x8107, KANJI_STANDARD, // 脇 + 0x60D1, KANJI_STANDARD, // 惑 + 0x67A0, KANJI_STANDARD, // 枠 + 0x9DF2, KANJI_STANDARD, // é·² + 0x4E99, KANJI_STANDARD, // 亙 + 0x4E98, KANJI_STANDARD, // 亘 + 0x9C10, KANJI_STANDARD, // 鰐 + 0x8A6B, KANJI_STANDARD, // è©« + 0x85C1, KANJI_STANDARD, // 藁 + 0x8568, KANJI_STANDARD, // 蕚 + 0x6900, KANJI_STANDARD, // 怀 + 0x6E7E, KANJI_STANDARD, // 湟 + 0x7897, KANJI_STANDARD, // 碗 + 0x8155, KANJI_STANDARD, // 腕 + 0x5F0C, KANJI_STANDARD, // 匌 + 0x4E10, KANJI_STANDARD, // 䞐 + 0x4E15, KANJI_STANDARD, // 侕 + 0x4E2A, KANJI_STANDARD, // 䞪 + 0x4E31, KANJI_STANDARD, // äž± + 0x4E36, KANJI_STANDARD, // äž¶ + 0x4E3C, KANJI_STANDARD, // 䞌 + 0x4E3F, KANJI_STANDARD, // äž¿ + 0x4E42, KANJI_STANDARD, // 乂 + 0x4E56, KANJI_STANDARD, // 乖 + 0x4E58, KANJI_STANDARD, // 乘 + 0x4E82, KANJI_STANDARD, // 亂 + 0x4E85, KANJI_STANDARD, // 亅 + 0x8C6B, KANJI_STANDARD, // 豫 + 0x4E8A, KANJI_STANDARD, // 亊 + 0x8212, KANJI_STANDARD, // 舒 + 0x5F0D, KANJI_STANDARD, // 匍 + 0x4E8E, KANJI_STANDARD, // 于 + 0x4E9E, KANJI_STANDARD, // 亞 + 0x4E9F, KANJI_STANDARD, // 亟 + 0x4EA0, KANJI_STANDARD, // 亠 + 0x4EA2, KANJI_STANDARD, // 亢 + 0x4EB0, KANJI_STANDARD, // 亰 + 0x4EB3, KANJI_STANDARD, // 亳 + 0x4EB6, KANJI_STANDARD, // 亶 + 0x4ECE, KANJI_STANDARD, // 从 + 0x4ECD, KANJI_STANDARD, // 仍 + 0x4EC4, KANJI_STANDARD, // 仄 + 0x4EC6, KANJI_STANDARD, // 仆 + 0x4EC2, KANJI_STANDARD, // 仂 + 0x4ED7, KANJI_STANDARD, // 仗 + 0x4EDE, KANJI_STANDARD, // 仞 + 0x4EED, KANJI_STANDARD, // ä»­ + 0x4EDF, KANJI_STANDARD, // 仟 + 0x4EF7, KANJI_STANDARD, // ä»· + 0x4F09, KANJI_STANDARD, // 䌉 + 0x4F5A, KANJI_STANDARD, // 䜚 + 0x4F30, KANJI_STANDARD, // 䌰 + 0x4F5B, KANJI_STANDARD, // 䜛 + 0x4F5D, KANJI_STANDARD, // 䜝 + 0x4F57, KANJI_STANDARD, // 䜗 + 0x4F47, KANJI_STANDARD, // 䜇 + 0x4F76, KANJI_STANDARD, // 䜶 + 0x4F88, KANJI_STANDARD, // 䟈 + 0x4F8F, KANJI_STANDARD, // 䟏 + 0x4F98, KANJI_STANDARD, // 䟘 + 0x4F7B, KANJI_STANDARD, // 䜻 + 0x4F69, KANJI_STANDARD, // 䜩 + 0x4F70, KANJI_STANDARD, // 䜰 + 0x4F91, KANJI_STANDARD, // 䟑 + 0x4F6F, KANJI_STANDARD, // 䜯 + 0x4F86, KANJI_STANDARD, // 䟆 + 0x4F96, KANJI_STANDARD, // 䟖 + 0x5118, KANJI_STANDARD, // 儘 + 0x4FD4, KANJI_STANDARD, // 俔 + 0x4FDF, KANJI_STANDARD, // 俟 + 0x4FCE, KANJI_STANDARD, // 俎 + 0x4FD8, KANJI_STANDARD, // 俘 + 0x4FDB, KANJI_STANDARD, // 俛 + 0x4FD1, KANJI_STANDARD, // 俑 + 0x4FDA, KANJI_STANDARD, // 俚 + 0x4FD0, KANJI_STANDARD, // 俐 + 0x4FE4, KANJI_STANDARD, // ä¿€ + 0x4FE5, KANJI_STANDARD, // ä¿¥ + 0x501A, KANJI_STANDARD, // 倚 + 0x5028, KANJI_STANDARD, // 倚 + 0x5014, KANJI_STANDARD, // 倔 + 0x502A, KANJI_STANDARD, // 倪 + 0x5025, KANJI_STANDARD, // 倥 + 0x5005, KANJI_STANDARD, // 倅 + 0x4F1C, KANJI_STANDARD, // 䌜 + 0x4FF6, KANJI_STANDARD, // ä¿¶ + 0x5021, KANJI_STANDARD, // 倡 + 0x5029, KANJI_STANDARD, // 倩 + 0x502C, KANJI_STANDARD, // 倬 + 0x4FFE, KANJI_STANDARD, // 俟 + 0x4FEF, KANJI_STANDARD, // 俯 + 0x5011, KANJI_STANDARD, // 們 + 0x5006, KANJI_STANDARD, // 倆 + 0x5043, KANJI_STANDARD, // 偃 + 0x5047, KANJI_STANDARD, // 假 + 0x6703, KANJI_STANDARD, // 會 + 0x5055, KANJI_STANDARD, // 偕 + 0x5050, KANJI_STANDARD, // 偐 + 0x5048, KANJI_STANDARD, // 偈 + 0x505A, KANJI_STANDARD, // 做 + 0x5056, KANJI_STANDARD, // 偖 + 0x506C, KANJI_STANDARD, // 偬 + 0x5078, KANJI_STANDARD, // 偞 + 0x5080, KANJI_STANDARD, // 傀 + 0x509A, KANJI_STANDARD, // 傚 + 0x5085, KANJI_STANDARD, // 傅 + 0x50B4, KANJI_STANDARD, // 傎 + 0x50B2, KANJI_STANDARD, // 傲 + 0x50C9, KANJI_STANDARD, // 僉 + 0x50CA, KANJI_STANDARD, // 僊 + 0x50B3, KANJI_STANDARD, // 傳 + 0x50C2, KANJI_STANDARD, // 僂 + 0x50D6, KANJI_STANDARD, // 僖 + 0x50DE, KANJI_STANDARD, // 僞 + 0x50E5, KANJI_STANDARD, // 僥 + 0x50ED, KANJI_STANDARD, // 僭 + 0x50E3, KANJI_STANDARD, // 僣 + 0x50EE, KANJI_STANDARD, // 僮 + 0x50F9, KANJI_STANDARD, // 價 + 0x50F5, KANJI_STANDARD, // 僵 + 0x5109, KANJI_STANDARD, // 儉 + 0x5101, KANJI_STANDARD, // 儁 + 0x5102, KANJI_STANDARD, // 儂 + 0x5116, KANJI_STANDARD, // 儖 + 0x5115, KANJI_STANDARD, // 儕 + 0x5114, KANJI_STANDARD, // 儔 + 0x511A, KANJI_STANDARD, // 儚 + 0x5121, KANJI_STANDARD, // 儡 + 0x513A, KANJI_STANDARD, // 儺 + 0x5137, KANJI_STANDARD, // 儷 + 0x513C, KANJI_STANDARD, // 儌 + 0x513B, KANJI_STANDARD, // 儻 + 0x513F, KANJI_STANDARD, // 儿 + 0x5140, KANJI_STANDARD, // 兀 + 0x5152, KANJI_STANDARD, // 兒 + 0x514C, KANJI_STANDARD, // 兌 + 0x5154, KANJI_STANDARD, // 兔 + 0x5162, KANJI_STANDARD, // 兢 + 0x7AF8, KANJI_STANDARD, // 竞 + 0x5169, KANJI_STANDARD, // 兩 + 0x516A, KANJI_STANDARD, // 兪 + 0x516E, KANJI_STANDARD, // 兮 + 0x5180, KANJI_STANDARD, // 冀 + 0x5182, KANJI_STANDARD, // 冂 + 0x56D8, KANJI_STANDARD, // 囘 + 0x518C, KANJI_STANDARD, // 册 + 0x5189, KANJI_STANDARD, // 冉 + 0x518F, KANJI_STANDARD, // 冏 + 0x5191, KANJI_STANDARD, // 冑 + 0x5193, KANJI_STANDARD, // 冓 + 0x5195, KANJI_STANDARD, // 冕 + 0x5196, KANJI_STANDARD, // 冖 + 0x51A4, KANJI_STANDARD, // 冀 + 0x51A6, KANJI_STANDARD, // 冊 + 0x51A2, KANJI_STANDARD, // 冢 + 0x51A9, KANJI_STANDARD, // 冩 + 0x51AA, KANJI_STANDARD, // 冪 + 0x51AB, KANJI_STANDARD, // 冫 + 0x51B3, KANJI_STANDARD, // 决 + 0x51B1, KANJI_STANDARD, // 冱 + 0x51B2, KANJI_STANDARD, // 冲 + 0x51B0, KANJI_STANDARD, // 冰 + 0x51B5, KANJI_STANDARD, // 况 + 0x51BD, KANJI_STANDARD, // 农 + 0x51C5, KANJI_STANDARD, // 凅 + 0x51C9, KANJI_STANDARD, // 凉 + 0x51DB, KANJI_STANDARD, // 凛 + 0x51E0, KANJI_STANDARD, // 几 + 0x8655, KANJI_STANDARD, // 處 + 0x51E9, KANJI_STANDARD, // 凩 + 0x51ED, KANJI_STANDARD, // 凭 + 0x51F0, KANJI_STANDARD, // 凰 + 0x51F5, KANJI_STANDARD, // 凵 + 0x51FE, KANJI_STANDARD, // 凟 + 0x5204, KANJI_STANDARD, // 刄 + 0x520B, KANJI_STANDARD, // 刋 + 0x5214, KANJI_STANDARD, // 刔 + 0x520E, KANJI_STANDARD, // 刎 + 0x5227, KANJI_STANDARD, // 刧 + 0x522A, KANJI_STANDARD, // 刪 + 0x522E, KANJI_STANDARD, // 刮 + 0x5233, KANJI_STANDARD, // 刳 + 0x5239, KANJI_STANDARD, // 刹 + 0x524F, KANJI_STANDARD, // 剏 + 0x5244, KANJI_STANDARD, // 剄 + 0x524B, KANJI_STANDARD, // 剋 + 0x524C, KANJI_STANDARD, // 剌 + 0x525E, KANJI_STANDARD, // 剞 + 0x5254, KANJI_STANDARD, // 剔 + 0x526A, KANJI_STANDARD, // 剪 + 0x5274, KANJI_STANDARD, // 剎 + 0x5269, KANJI_STANDARD, // 剩 + 0x5273, KANJI_STANDARD, // 剳 + 0x527F, KANJI_STANDARD, // 剿 + 0x527D, KANJI_STANDARD, // 剜 + 0x528D, KANJI_STANDARD, // 劍 + 0x5294, KANJI_STANDARD, // 劔 + 0x5292, KANJI_STANDARD, // 劒 + 0x5271, KANJI_STANDARD, // 剱 + 0x5288, KANJI_STANDARD, // 劈 + 0x5291, KANJI_STANDARD, // 劑 + 0x8FA8, KANJI_STANDARD, // 蟚 + 0x8FA7, KANJI_STANDARD, // 蟧 + 0x52AC, KANJI_STANDARD, // 劬 + 0x52AD, KANJI_STANDARD, // 劭 + 0x52BC, KANJI_STANDARD, // 劌 + 0x52B5, KANJI_STANDARD, // 劵 + 0x52C1, KANJI_STANDARD, // 勁 + 0x52CD, KANJI_STANDARD, // 勍 + 0x52D7, KANJI_STANDARD, // 勗 + 0x52DE, KANJI_STANDARD, // 勞 + 0x52E3, KANJI_STANDARD, // 勣 + 0x52E6, KANJI_STANDARD, // 勊 + 0x98ED, KANJI_STANDARD, // 飭 + 0x52E0, KANJI_STANDARD, // 勠 + 0x52F3, KANJI_STANDARD, // 勳 + 0x52F5, KANJI_STANDARD, // 勵 + 0x52F8, KANJI_STANDARD, // 勞 + 0x52F9, KANJI_STANDARD, // 勹 + 0x5306, KANJI_STANDARD, // 匆 + 0x5308, KANJI_STANDARD, // 匈 + 0x7538, KANJI_STANDARD, // 甾 + 0x530D, KANJI_STANDARD, // 匍 + 0x5310, KANJI_STANDARD, // 匐 + 0x530F, KANJI_STANDARD, // 匏 + 0x5315, KANJI_STANDARD, // 匕 + 0x531A, KANJI_STANDARD, // 匚 + 0x5323, KANJI_STANDARD, // 匣 + 0x532F, KANJI_STANDARD, // 匯 + 0x5331, KANJI_STANDARD, // 匱 + 0x5333, KANJI_STANDARD, // 匳 + 0x5338, KANJI_STANDARD, // 匞 + 0x5340, KANJI_STANDARD, // 區 + 0x5346, KANJI_STANDARD, // 卆 + 0x5345, KANJI_STANDARD, // 卅 + 0x4E17, KANJI_STANDARD, // 侗 + 0x5349, KANJI_STANDARD, // 卉 + 0x534D, KANJI_STANDARD, // 卍 + 0x51D6, KANJI_STANDARD, // 凖 + 0x535E, KANJI_STANDARD, // 卞 + 0x5369, KANJI_STANDARD, // 卩 + 0x536E, KANJI_STANDARD, // 卮 + 0x5918, KANJI_STANDARD, // 倘 + 0x537B, KANJI_STANDARD, // 卻 + 0x5377, KANJI_STANDARD, // 卷 + 0x5382, KANJI_STANDARD, // 厂 + 0x5396, KANJI_STANDARD, // 厖 + 0x53A0, KANJI_STANDARD, // 厠 + 0x53A6, KANJI_STANDARD, // 厊 + 0x53A5, KANJI_STANDARD, // 厥 + 0x53AE, KANJI_STANDARD, // 厮 + 0x53B0, KANJI_STANDARD, // 厰 + 0x53B6, KANJI_STANDARD, // 厶 + 0x53C3, KANJI_STANDARD, // 參 + 0x7C12, KANJI_STANDARD, // 簒 + 0x96D9, KANJI_STANDARD, // 雙 + 0x53DF, KANJI_STANDARD, // 叟 + 0x66FC, KANJI_STANDARD, // 曌 + 0x71EE, KANJI_STANDARD, // 燮 + 0x53EE, KANJI_STANDARD, // 叮 + 0x53E8, KANJI_STANDARD, // 叚 + 0x53ED, KANJI_STANDARD, // 叭 + 0x53FA, KANJI_STANDARD, // 叺 + 0x5401, KANJI_STANDARD, // 吁 + 0x543D, KANJI_STANDARD, // 吜 + 0x5440, KANJI_STANDARD, // 呀 + 0x542C, KANJI_STANDARD, // 听 + 0x542D, KANJI_STANDARD, // 吭 + 0x543C, KANJI_STANDARD, // 同 + 0x542E, KANJI_STANDARD, // 吮 + 0x5436, KANJI_STANDARD, // 吶 + 0x5429, KANJI_STANDARD, // 吩 + 0x541D, KANJI_STANDARD, // 吝 + 0x544E, KANJI_STANDARD, // 呎 + 0x548F, KANJI_STANDARD, // 咏 + 0x5475, KANJI_STANDARD, // 呵 + 0x548E, KANJI_STANDARD, // 咎 + 0x545F, KANJI_STANDARD, // 呟 + 0x5471, KANJI_STANDARD, // 呱 + 0x5477, KANJI_STANDARD, // 呷 + 0x5470, KANJI_STANDARD, // 呰 + 0x5492, KANJI_STANDARD, // 咒 + 0x547B, KANJI_STANDARD, // 呻 + 0x5480, KANJI_STANDARD, // 咀 + 0x5476, KANJI_STANDARD, // 呶 + 0x5484, KANJI_STANDARD, // 咄 + 0x5490, KANJI_STANDARD, // 咐 + 0x5486, KANJI_STANDARD, // 咆 + 0x54C7, KANJI_STANDARD, // 哇 + 0x54A2, KANJI_STANDARD, // 咢 + 0x54B8, KANJI_STANDARD, // å’ž + 0x54A5, KANJI_STANDARD, // 咥 + 0x54AC, KANJI_STANDARD, // 咬 + 0x54C4, KANJI_STANDARD, // 哄 + 0x54C8, KANJI_STANDARD, // 哈 + 0x54A8, KANJI_STANDARD, // å’š + 0x54AB, KANJI_STANDARD, // 咫 + 0x54C2, KANJI_STANDARD, // 哂 + 0x54A4, KANJI_STANDARD, // å’€ + 0x54BE, KANJI_STANDARD, // å’Ÿ + 0x54BC, KANJI_STANDARD, // å’Œ + 0x54D8, KANJI_STANDARD, // 哘 + 0x54E5, KANJI_STANDARD, // 哥 + 0x54E6, KANJI_STANDARD, // 哊 + 0x550F, KANJI_STANDARD, // 唏 + 0x5514, KANJI_STANDARD, // 唔 + 0x54FD, KANJI_STANDARD, // 哜 + 0x54EE, KANJI_STANDARD, // 哮 + 0x54ED, KANJI_STANDARD, // 哭 + 0x54FA, KANJI_STANDARD, // 哺 + 0x54E2, KANJI_STANDARD, // 哢 + 0x5539, KANJI_STANDARD, // 唹 + 0x5540, KANJI_STANDARD, // 啀 + 0x5563, KANJI_STANDARD, // 啣 + 0x554C, KANJI_STANDARD, // 啌 + 0x552E, KANJI_STANDARD, // 售 + 0x555C, KANJI_STANDARD, // 啜 + 0x5545, KANJI_STANDARD, // 啅 + 0x5556, KANJI_STANDARD, // 啖 + 0x5557, KANJI_STANDARD, // 啗 + 0x5538, KANJI_STANDARD, // 唞 + 0x5533, KANJI_STANDARD, // 唳 + 0x555D, KANJI_STANDARD, // 啝 + 0x5599, KANJI_STANDARD, // 喙 + 0x5580, KANJI_STANDARD, // 喀 + 0x54AF, KANJI_STANDARD, // 咯 + 0x558A, KANJI_STANDARD, // 喊 + 0x559F, KANJI_STANDARD, // 喟 + 0x557B, KANJI_STANDARD, // 啻 + 0x557E, KANJI_STANDARD, // 啟 + 0x5598, KANJI_STANDARD, // 喘 + 0x559E, KANJI_STANDARD, // 喞 + 0x55AE, KANJI_STANDARD, // 單 + 0x557C, KANJI_STANDARD, // 啌 + 0x5583, KANJI_STANDARD, // 喃 + 0x55A9, KANJI_STANDARD, // 喩 + 0x5587, KANJI_STANDARD, // 喇 + 0x55A8, KANJI_STANDARD, // å–š + 0x55DA, KANJI_STANDARD, // 嗚 + 0x55C5, KANJI_STANDARD, // 嗅 + 0x55DF, KANJI_STANDARD, // 嗟 + 0x55C4, KANJI_STANDARD, // 嗄 + 0x55DC, KANJI_STANDARD, // 嗜 + 0x55E4, KANJI_STANDARD, // å—€ + 0x55D4, KANJI_STANDARD, // 嗔 + 0x5614, KANJI_STANDARD, // 嘔 + 0x55F7, KANJI_STANDARD, // 嗷 + 0x5616, KANJI_STANDARD, // 嘖 + 0x55FE, KANJI_STANDARD, // å—Ÿ + 0x55FD, KANJI_STANDARD, // å—œ + 0x561B, KANJI_STANDARD, // 嘛 + 0x55F9, KANJI_STANDARD, // 嗹 + 0x564E, KANJI_STANDARD, // 噎 + 0x5650, KANJI_STANDARD, // 噐 + 0x71DF, KANJI_STANDARD, // 營 + 0x5634, KANJI_STANDARD, // 嘎 + 0x5636, KANJI_STANDARD, // 嘶 + 0x5632, KANJI_STANDARD, // 嘲 + 0x5638, KANJI_STANDARD, // 嘞 + 0x566B, KANJI_STANDARD, // 噫 + 0x5664, KANJI_STANDARD, // 噀 + 0x562F, KANJI_STANDARD, // 嘯 + 0x566C, KANJI_STANDARD, // 噬 + 0x566A, KANJI_STANDARD, // 噪 + 0x5686, KANJI_STANDARD, // 嚆 + 0x5680, KANJI_STANDARD, // 嚀 + 0x568A, KANJI_STANDARD, // 嚊 + 0x56A0, KANJI_STANDARD, // 嚠 + 0x5694, KANJI_STANDARD, // 嚔 + 0x568F, KANJI_STANDARD, // 嚏 + 0x56A5, KANJI_STANDARD, // 嚥 + 0x56AE, KANJI_STANDARD, // 嚮 + 0x56B6, KANJI_STANDARD, // 嚶 + 0x56B4, KANJI_STANDARD, // 嚎 + 0x56C2, KANJI_STANDARD, // 囂 + 0x56BC, KANJI_STANDARD, // 嚌 + 0x56C1, KANJI_STANDARD, // 囁 + 0x56C3, KANJI_STANDARD, // 囃 + 0x56C0, KANJI_STANDARD, // 囀 + 0x56C8, KANJI_STANDARD, // 囈 + 0x56CE, KANJI_STANDARD, // 囎 + 0x56D1, KANJI_STANDARD, // 囑 + 0x56D3, KANJI_STANDARD, // 囓 + 0x56D7, KANJI_STANDARD, // 囗 + 0x56EE, KANJI_STANDARD, // 囮 + 0x56F9, KANJI_STANDARD, // 囹 + 0x5700, KANJI_STANDARD, // 圀 + 0x56FF, KANJI_STANDARD, // 囿 + 0x5704, KANJI_STANDARD, // 圄 + 0x5709, KANJI_STANDARD, // 圉 + 0x5708, KANJI_STANDARD, // 圈 + 0x570B, KANJI_STANDARD, // 國 + 0x570D, KANJI_STANDARD, // 圍 + 0x5713, KANJI_STANDARD, // 圓 + 0x5718, KANJI_STANDARD, // 團 + 0x5716, KANJI_STANDARD, // 圖 + 0x55C7, KANJI_STANDARD, // 嗇 + 0x571C, KANJI_STANDARD, // 圜 + 0x5726, KANJI_STANDARD, // 圊 + 0x5737, KANJI_STANDARD, // 圷 + 0x5738, KANJI_STANDARD, // 圞 + 0x574E, KANJI_STANDARD, // 坎 + 0x573B, KANJI_STANDARD, // 圻 + 0x5740, KANJI_STANDARD, // 址 + 0x574F, KANJI_STANDARD, // 坏 + 0x5769, KANJI_STANDARD, // 坩 + 0x57C0, KANJI_STANDARD, // 埀 + 0x5788, KANJI_STANDARD, // 垈 + 0x5761, KANJI_STANDARD, // 坡 + 0x577F, KANJI_STANDARD, // 坿 + 0x5789, KANJI_STANDARD, // 垉 + 0x5793, KANJI_STANDARD, // 垓 + 0x57A0, KANJI_STANDARD, // 垠 + 0x57B3, KANJI_STANDARD, // 垳 + 0x57A4, KANJI_STANDARD, // 垀 + 0x57AA, KANJI_STANDARD, // 垪 + 0x57B0, KANJI_STANDARD, // 垰 + 0x57C3, KANJI_STANDARD, // 埃 + 0x57C6, KANJI_STANDARD, // 埆 + 0x57D4, KANJI_STANDARD, // 埔 + 0x57D2, KANJI_STANDARD, // 埒 + 0x57D3, KANJI_STANDARD, // 埓 + 0x580A, KANJI_STANDARD, // 堊 + 0x57D6, KANJI_STANDARD, // 埖 + 0x57E3, KANJI_STANDARD, // 埣 + 0x580B, KANJI_STANDARD, // 堋 + 0x5819, KANJI_STANDARD, // 堙 + 0x581D, KANJI_STANDARD, // 堝 + 0x5872, KANJI_STANDARD, // 塲 + 0x5821, KANJI_STANDARD, // å ¡ + 0x5862, KANJI_STANDARD, // å¡¢ + 0x584B, KANJI_STANDARD, // 塋 + 0x5870, KANJI_STANDARD, // å¡° + 0x6BC0, KANJI_STANDARD, // 毀 + 0x5852, KANJI_STANDARD, // 塒 + 0x583D, KANJI_STANDARD, // å œ + 0x5879, KANJI_STANDARD, // 塹 + 0x5885, KANJI_STANDARD, // 墅 + 0x58B9, KANJI_STANDARD, // 墹 + 0x589F, KANJI_STANDARD, // 墟 + 0x58AB, KANJI_STANDARD, // 墫 + 0x58BA, KANJI_STANDARD, // 墺 + 0x58DE, KANJI_STANDARD, // 壞 + 0x58BB, KANJI_STANDARD, // 墻 + 0x58B8, KANJI_STANDARD, // 增 + 0x58AE, KANJI_STANDARD, // 墮 + 0x58C5, KANJI_STANDARD, // 壅 + 0x58D3, KANJI_STANDARD, // 壓 + 0x58D1, KANJI_STANDARD, // 壑 + 0x58D7, KANJI_STANDARD, // 壗 + 0x58D9, KANJI_STANDARD, // 壙 + 0x58D8, KANJI_STANDARD, // 壘 + 0x58E5, KANJI_STANDARD, // 壥 + 0x58DC, KANJI_STANDARD, // 壜 + 0x58E4, KANJI_STANDARD, // 壀 + 0x58DF, KANJI_STANDARD, // 壟 + 0x58EF, KANJI_STANDARD, // 壯 + 0x58FA, KANJI_STANDARD, // 壺 + 0x58F9, KANJI_STANDARD, // 壹 + 0x58FB, KANJI_STANDARD, // 壻 + 0x58FC, KANJI_STANDARD, // 壌 + 0x58FD, KANJI_STANDARD, // 壜 + 0x5902, KANJI_STANDARD, // 倂 + 0x590A, KANJI_STANDARD, // 倊 + 0x5910, KANJI_STANDARD, // 倐 + 0x591B, KANJI_STANDARD, // 倛 + 0x68A6, KANJI_STANDARD, // 梊 + 0x5925, KANJI_STANDARD, // 倥 + 0x592C, KANJI_STANDARD, // 倬 + 0x592D, KANJI_STANDARD, // 倭 + 0x5932, KANJI_STANDARD, // 倲 + 0x5938, KANJI_STANDARD, // 倞 + 0x593E, KANJI_STANDARD, // 借 + 0x7AD2, KANJI_STANDARD, // 竒 + 0x5955, KANJI_STANDARD, // 奕 + 0x5950, KANJI_STANDARD, // 奐 + 0x594E, KANJI_STANDARD, // 奎 + 0x595A, KANJI_STANDARD, // 奚 + 0x5958, KANJI_STANDARD, // 奘 + 0x5962, KANJI_STANDARD, // 奢 + 0x5960, KANJI_STANDARD, // 奠 + 0x5967, KANJI_STANDARD, // 奧 + 0x596C, KANJI_STANDARD, // 奬 + 0x5969, KANJI_STANDARD, // 奩 + 0x5978, KANJI_STANDARD, // 奞 + 0x5981, KANJI_STANDARD, // 劁 + 0x599D, KANJI_STANDARD, // 劝 + 0x4F5E, KANJI_STANDARD, // 䜞 + 0x4FAB, KANJI_STANDARD, // 䟫 + 0x59A3, KANJI_STANDARD, // 劣 + 0x59B2, KANJI_STANDARD, // 劲 + 0x59C6, KANJI_STANDARD, // 姆 + 0x59E8, KANJI_STANDARD, // å§š + 0x59DC, KANJI_STANDARD, // 姜 + 0x598D, KANJI_STANDARD, // 劍 + 0x59D9, KANJI_STANDARD, // 姙 + 0x59DA, KANJI_STANDARD, // 姚 + 0x5A25, KANJI_STANDARD, // 嚥 + 0x5A1F, KANJI_STANDARD, // 嚟 + 0x5A11, KANJI_STANDARD, // åš‘ + 0x5A1C, KANJI_STANDARD, // åšœ + 0x5A09, KANJI_STANDARD, // 嚉 + 0x5A1A, KANJI_STANDARD, // åšš + 0x5A40, KANJI_STANDARD, // 婀 + 0x5A6C, KANJI_STANDARD, // 婬 + 0x5A49, KANJI_STANDARD, // 婉 + 0x5A35, KANJI_STANDARD, // åšµ + 0x5A36, KANJI_STANDARD, // åš¶ + 0x5A62, KANJI_STANDARD, // å©¢ + 0x5A6A, KANJI_STANDARD, // 婪 + 0x5A9A, KANJI_STANDARD, // 媚 + 0x5ABC, KANJI_STANDARD, // 媌 + 0x5ABE, KANJI_STANDARD, // 媟 + 0x5ACB, KANJI_STANDARD, // 嫋 + 0x5AC2, KANJI_STANDARD, // 嫂 + 0x5ABD, KANJI_STANDARD, // 媜 + 0x5AE3, KANJI_STANDARD, // å«£ + 0x5AD7, KANJI_STANDARD, // 嫗 + 0x5AE6, KANJI_STANDARD, // 嫊 + 0x5AE9, KANJI_STANDARD, // å«© + 0x5AD6, KANJI_STANDARD, // 嫖 + 0x5AFA, KANJI_STANDARD, // 嫺 + 0x5AFB, KANJI_STANDARD, // å«» + 0x5B0C, KANJI_STANDARD, // 嬌 + 0x5B0B, KANJI_STANDARD, // 嬋 + 0x5B16, KANJI_STANDARD, // 嬖 + 0x5B32, KANJI_STANDARD, // 嬲 + 0x5AD0, KANJI_STANDARD, // 嫐 + 0x5B2A, KANJI_STANDARD, // 嬪 + 0x5B36, KANJI_STANDARD, // 嬶 + 0x5B3E, KANJI_STANDARD, // 嬟 + 0x5B43, KANJI_STANDARD, // 孃 + 0x5B45, KANJI_STANDARD, // 孅 + 0x5B40, KANJI_STANDARD, // 孀 + 0x5B51, KANJI_STANDARD, // 孑 + 0x5B55, KANJI_STANDARD, // 孕 + 0x5B5A, KANJI_STANDARD, // 孚 + 0x5B5B, KANJI_STANDARD, // 孛 + 0x5B65, KANJI_STANDARD, // å­¥ + 0x5B69, KANJI_STANDARD, // å­© + 0x5B70, KANJI_STANDARD, // å­° + 0x5B73, KANJI_STANDARD, // å­³ + 0x5B75, KANJI_STANDARD, // å­µ + 0x5B78, KANJI_STANDARD, // å­ž + 0x6588, KANJI_STANDARD, // 斈 + 0x5B7A, KANJI_STANDARD, // å­º + 0x5B80, KANJI_STANDARD, // 宀 + 0x5B83, KANJI_STANDARD, // 它 + 0x5BA6, KANJI_STANDARD, // 宊 + 0x5BB8, KANJI_STANDARD, // 实 + 0x5BC3, KANJI_STANDARD, // 寃 + 0x5BC7, KANJI_STANDARD, // 寇 + 0x5BC9, KANJI_STANDARD, // 寉 + 0x5BD4, KANJI_STANDARD, // 寔 + 0x5BD0, KANJI_STANDARD, // 寐 + 0x5BE4, KANJI_STANDARD, // 寀 + 0x5BE6, KANJI_STANDARD, // 寊 + 0x5BE2, KANJI_STANDARD, // 寢 + 0x5BDE, KANJI_STANDARD, // 寞 + 0x5BE5, KANJI_STANDARD, // 寥 + 0x5BEB, KANJI_STANDARD, // 寫 + 0x5BF0, KANJI_STANDARD, // 寰 + 0x5BF6, KANJI_STANDARD, // 寶 + 0x5BF3, KANJI_STANDARD, // 寳 + 0x5C05, KANJI_STANDARD, // 尅 + 0x5C07, KANJI_STANDARD, // 將 + 0x5C08, KANJI_STANDARD, // 專 + 0x5C0D, KANJI_STANDARD, // 對 + 0x5C13, KANJI_STANDARD, // 尓 + 0x5C20, KANJI_STANDARD, // å°  + 0x5C22, KANJI_STANDARD, // å°¢ + 0x5C28, KANJI_STANDARD, // å°š + 0x5C38, KANJI_STANDARD, // å°ž + 0x5C39, KANJI_STANDARD, // å°¹ + 0x5C41, KANJI_STANDARD, // 屁 + 0x5C46, KANJI_STANDARD, // 屆 + 0x5C4E, KANJI_STANDARD, // 屎 + 0x5C53, KANJI_STANDARD, // 屓 + 0x5C50, KANJI_STANDARD, // 屐 + 0x5C4F, KANJI_STANDARD, // 屏 + 0x5B71, KANJI_STANDARD, // å­± + 0x5C6C, KANJI_STANDARD, // 屬 + 0x5C6E, KANJI_STANDARD, // å±® + 0x4E62, KANJI_STANDARD, // ä¹¢ + 0x5C76, KANJI_STANDARD, // å±¶ + 0x5C79, KANJI_STANDARD, // å±¹ + 0x5C8C, KANJI_STANDARD, // 岌 + 0x5C91, KANJI_STANDARD, // 岑 + 0x5C94, KANJI_STANDARD, // 岔 + 0x599B, KANJI_STANDARD, // 力 + 0x5CAB, KANJI_STANDARD, // 岫 + 0x5CBB, KANJI_STANDARD, // å²» + 0x5CB6, KANJI_STANDARD, // å²¶ + 0x5CBC, KANJI_STANDARD, // 岌 + 0x5CB7, KANJI_STANDARD, // å²· + 0x5CC5, KANJI_STANDARD, // 峅 + 0x5CBE, KANJI_STANDARD, // 岟 + 0x5CC7, KANJI_STANDARD, // 峇 + 0x5CD9, KANJI_STANDARD, // 峙 + 0x5CE9, KANJI_STANDARD, // 峩 + 0x5CFD, KANJI_STANDARD, // 峜 + 0x5CFA, KANJI_STANDARD, // 峺 + 0x5CED, KANJI_STANDARD, // å³­ + 0x5D8C, KANJI_STANDARD, // 嶌 + 0x5CEA, KANJI_STANDARD, // 峪 + 0x5D0B, KANJI_STANDARD, // 压 + 0x5D15, KANJI_STANDARD, // 厕 + 0x5D17, KANJI_STANDARD, // 厗 + 0x5D5C, KANJI_STANDARD, // 嵜 + 0x5D1F, KANJI_STANDARD, // 原 + 0x5D1B, KANJI_STANDARD, // 厛 + 0x5D11, KANJI_STANDARD, // 厑 + 0x5D14, KANJI_STANDARD, // 厔 + 0x5D22, KANJI_STANDARD, // 厢 + 0x5D1A, KANJI_STANDARD, // 厚 + 0x5D19, KANJI_STANDARD, // 厙 + 0x5D18, KANJI_STANDARD, // 厘 + 0x5D4C, KANJI_STANDARD, // 嵌 + 0x5D52, KANJI_STANDARD, // 嵒 + 0x5D4E, KANJI_STANDARD, // 嵎 + 0x5D4B, KANJI_STANDARD, // 嵋 + 0x5D6C, KANJI_STANDARD, // 嵬 + 0x5D73, KANJI_STANDARD, // åµ³ + 0x5D76, KANJI_STANDARD, // åµ¶ + 0x5D87, KANJI_STANDARD, // 嶇 + 0x5D84, KANJI_STANDARD, // 嶄 + 0x5D82, KANJI_STANDARD, // 嶂 + 0x5DA2, KANJI_STANDARD, // å¶¢ + 0x5D9D, KANJI_STANDARD, // 嶝 + 0x5DAC, KANJI_STANDARD, // 嶬 + 0x5DAE, KANJI_STANDARD, // å¶® + 0x5DBD, KANJI_STANDARD, // å¶œ + 0x5D90, KANJI_STANDARD, // 嶐 + 0x5DB7, KANJI_STANDARD, // å¶· + 0x5DBC, KANJI_STANDARD, // å¶Œ + 0x5DC9, KANJI_STANDARD, // 巉 + 0x5DCD, KANJI_STANDARD, // 巍 + 0x5DD3, KANJI_STANDARD, // 巓 + 0x5DD2, KANJI_STANDARD, // 巒 + 0x5DD6, KANJI_STANDARD, // 巖 + 0x5DDB, KANJI_STANDARD, // 巛 + 0x5DEB, KANJI_STANDARD, // å·« + 0x5DF2, KANJI_STANDARD, // å·² + 0x5DF5, KANJI_STANDARD, // å·µ + 0x5E0B, KANJI_STANDARD, // åž‹ + 0x5E1A, KANJI_STANDARD, // åžš + 0x5E19, KANJI_STANDARD, // åž™ + 0x5E11, KANJI_STANDARD, // åž‘ + 0x5E1B, KANJI_STANDARD, // åž› + 0x5E36, KANJI_STANDARD, // åž¶ + 0x5E37, KANJI_STANDARD, // åž· + 0x5E44, KANJI_STANDARD, // 幄 + 0x5E43, KANJI_STANDARD, // 幃 + 0x5E40, KANJI_STANDARD, // 幀 + 0x5E4E, KANJI_STANDARD, // 幎 + 0x5E57, KANJI_STANDARD, // 幗 + 0x5E54, KANJI_STANDARD, // 幔 + 0x5E5F, KANJI_STANDARD, // 幟 + 0x5E62, KANJI_STANDARD, // å¹¢ + 0x5E64, KANJI_STANDARD, // å¹€ + 0x5E47, KANJI_STANDARD, // 幇 + 0x5E75, KANJI_STANDARD, // å¹µ + 0x5E76, KANJI_STANDARD, // å¹¶ + 0x5E7A, KANJI_STANDARD, // 幺 + 0x9EBC, KANJI_STANDARD, // 麌 + 0x5E7F, KANJI_STANDARD, // 广 + 0x5EA0, KANJI_STANDARD, // 庠 + 0x5EC1, KANJI_STANDARD, // 廁 + 0x5EC2, KANJI_STANDARD, // 廂 + 0x5EC8, KANJI_STANDARD, // 廈 + 0x5ED0, KANJI_STANDARD, // 廐 + 0x5ECF, KANJI_STANDARD, // 廏 + 0x5ED6, KANJI_STANDARD, // 廖 + 0x5EE3, KANJI_STANDARD, // 廣 + 0x5EDD, KANJI_STANDARD, // 廝 + 0x5EDA, KANJI_STANDARD, // 廚 + 0x5EDB, KANJI_STANDARD, // 廛 + 0x5EE2, KANJI_STANDARD, // 廢 + 0x5EE1, KANJI_STANDARD, // 廡 + 0x5EE8, KANJI_STANDARD, // 廚 + 0x5EE9, KANJI_STANDARD, // 廩 + 0x5EEC, KANJI_STANDARD, // 廬 + 0x5EF1, KANJI_STANDARD, // å»± + 0x5EF3, KANJI_STANDARD, // 廳 + 0x5EF0, KANJI_STANDARD, // å»° + 0x5EF4, KANJI_STANDARD, // 廎 + 0x5EF8, KANJI_STANDARD, // 廞 + 0x5EFE, KANJI_STANDARD, // 廟 + 0x5F03, KANJI_STANDARD, // 匃 + 0x5F09, KANJI_STANDARD, // 匉 + 0x5F5D, KANJI_STANDARD, // 圝 + 0x5F5C, KANJI_STANDARD, // 圜 + 0x5F0B, KANJI_STANDARD, // 匋 + 0x5F11, KANJI_STANDARD, // 匑 + 0x5F16, KANJI_STANDARD, // 化 + 0x5F29, KANJI_STANDARD, // 匩 + 0x5F2D, KANJI_STANDARD, // 匭 + 0x5F38, KANJI_STANDARD, // 匞 + 0x5F41, KANJI_STANDARD, // 圁 + 0x5F48, KANJI_STANDARD, // 圈 + 0x5F4C, KANJI_STANDARD, // 圌 + 0x5F4E, KANJI_STANDARD, // 圎 + 0x5F2F, KANJI_STANDARD, // 匯 + 0x5F51, KANJI_STANDARD, // 圑 + 0x5F56, KANJI_STANDARD, // 圖 + 0x5F57, KANJI_STANDARD, // 圗 + 0x5F59, KANJI_STANDARD, // 圙 + 0x5F61, KANJI_STANDARD, // 圡 + 0x5F6D, KANJI_STANDARD, // 圭 + 0x5F73, KANJI_STANDARD, // 圳 + 0x5F77, KANJI_STANDARD, // 圷 + 0x5F83, KANJI_STANDARD, // 埃 + 0x5F82, KANJI_STANDARD, // 埂 + 0x5F7F, KANJI_STANDARD, // 圿 + 0x5F8A, KANJI_STANDARD, // 埊 + 0x5F88, KANJI_STANDARD, // 埈 + 0x5F91, KANJI_STANDARD, // 埑 + 0x5F87, KANJI_STANDARD, // 埇 + 0x5F9E, KANJI_STANDARD, // 埞 + 0x5F99, KANJI_STANDARD, // 埙 + 0x5F98, KANJI_STANDARD, // 埘 + 0x5FA0, KANJI_STANDARD, // 埠 + 0x5FA8, KANJI_STANDARD, // 埚 + 0x5FAD, KANJI_STANDARD, // 埭 + 0x5FBC, KANJI_STANDARD, // 埌 + 0x5FD6, KANJI_STANDARD, // 忖 + 0x5FFB, KANJI_STANDARD, // å¿» + 0x5FE4, KANJI_STANDARD, // å¿€ + 0x5FF8, KANJI_STANDARD, // 忞 + 0x5FF1, KANJI_STANDARD, // 忱 + 0x5FDD, KANJI_STANDARD, // 忝 + 0x60B3, KANJI_STANDARD, // 悳 + 0x5FFF, KANJI_STANDARD, // å¿¿ + 0x6021, KANJI_STANDARD, // 怡 + 0x6060, KANJI_STANDARD, // 恠 + 0x6019, KANJI_STANDARD, // 怙 + 0x6010, KANJI_STANDARD, // 怐 + 0x6029, KANJI_STANDARD, // 怩 + 0x600E, KANJI_STANDARD, // 怎 + 0x6031, KANJI_STANDARD, // 怱 + 0x601B, KANJI_STANDARD, // 怛 + 0x6015, KANJI_STANDARD, // 怕 + 0x602B, KANJI_STANDARD, // 怫 + 0x6026, KANJI_STANDARD, // 怊 + 0x600F, KANJI_STANDARD, // 怏 + 0x603A, KANJI_STANDARD, // 怺 + 0x605A, KANJI_STANDARD, // 恚 + 0x6041, KANJI_STANDARD, // 恁 + 0x606A, KANJI_STANDARD, // 恪 + 0x6077, KANJI_STANDARD, // 恷 + 0x605F, KANJI_STANDARD, // 恟 + 0x604A, KANJI_STANDARD, // 恊 + 0x6046, KANJI_STANDARD, // 恆 + 0x604D, KANJI_STANDARD, // 恍 + 0x6063, KANJI_STANDARD, // 恣 + 0x6043, KANJI_STANDARD, // 恃 + 0x6064, KANJI_STANDARD, // 恀 + 0x6042, KANJI_STANDARD, // 恂 + 0x606C, KANJI_STANDARD, // 恬 + 0x606B, KANJI_STANDARD, // 恫 + 0x6059, KANJI_STANDARD, // 恙 + 0x6081, KANJI_STANDARD, // 悁 + 0x608D, KANJI_STANDARD, // 悍 + 0x60E7, KANJI_STANDARD, // 惧 + 0x6083, KANJI_STANDARD, // 悃 + 0x609A, KANJI_STANDARD, // 悚 + 0x6084, KANJI_STANDARD, // 悄 + 0x609B, KANJI_STANDARD, // 悛 + 0x6096, KANJI_STANDARD, // 悖 + 0x6097, KANJI_STANDARD, // 悗 + 0x6092, KANJI_STANDARD, // 悒 + 0x60A7, KANJI_STANDARD, // 悧 + 0x608B, KANJI_STANDARD, // 悋 + 0x60E1, KANJI_STANDARD, // 惡 + 0x60B8, KANJI_STANDARD, // 悞 + 0x60E0, KANJI_STANDARD, // 惠 + 0x60D3, KANJI_STANDARD, // 惓 + 0x60B4, KANJI_STANDARD, // 悎 + 0x5FF0, KANJI_STANDARD, // å¿° + 0x60BD, KANJI_STANDARD, // 悜 + 0x60C6, KANJI_STANDARD, // 惆 + 0x60B5, KANJI_STANDARD, // 悵 + 0x60D8, KANJI_STANDARD, // 惘 + 0x614D, KANJI_STANDARD, // 慍 + 0x6115, KANJI_STANDARD, // 愕 + 0x6106, KANJI_STANDARD, // 愆 + 0x60F6, KANJI_STANDARD, // 惶 + 0x60F7, KANJI_STANDARD, // 惷 + 0x6100, KANJI_STANDARD, // 愀 + 0x60F4, KANJI_STANDARD, // 惎 + 0x60FA, KANJI_STANDARD, // 惺 + 0x6103, KANJI_STANDARD, // 愃 + 0x6121, KANJI_STANDARD, // 愡 + 0x60FB, KANJI_STANDARD, // 惻 + 0x60F1, KANJI_STANDARD, // 惱 + 0x610D, KANJI_STANDARD, // 愍 + 0x610E, KANJI_STANDARD, // 愎 + 0x6147, KANJI_STANDARD, // 慇 + 0x613E, KANJI_STANDARD, // 感 + 0x6128, KANJI_STANDARD, // 愚 + 0x6127, KANJI_STANDARD, // 愧 + 0x614A, KANJI_STANDARD, // 慊 + 0x613F, KANJI_STANDARD, // 愿 + 0x613C, KANJI_STANDARD, // 愌 + 0x612C, KANJI_STANDARD, // 愬 + 0x6134, KANJI_STANDARD, // 愎 + 0x613D, KANJI_STANDARD, // 愜 + 0x6142, KANJI_STANDARD, // 慂 + 0x6144, KANJI_STANDARD, // 慄 + 0x6173, KANJI_STANDARD, // 慳 + 0x6177, KANJI_STANDARD, // 慷 + 0x6158, KANJI_STANDARD, // 慘 + 0x6159, KANJI_STANDARD, // 慙 + 0x615A, KANJI_STANDARD, // 慚 + 0x616B, KANJI_STANDARD, // 慫 + 0x6174, KANJI_STANDARD, // æ…Ž + 0x616F, KANJI_STANDARD, // 慯 + 0x6165, KANJI_STANDARD, // 慥 + 0x6171, KANJI_STANDARD, // 慱 + 0x615F, KANJI_STANDARD, // 慟 + 0x615D, KANJI_STANDARD, // 慝 + 0x6153, KANJI_STANDARD, // 慓 + 0x6175, KANJI_STANDARD, // 慵 + 0x6199, KANJI_STANDARD, // 憙 + 0x6196, KANJI_STANDARD, // 憖 + 0x6187, KANJI_STANDARD, // 憇 + 0x61AC, KANJI_STANDARD, // 憬 + 0x6194, KANJI_STANDARD, // 憔 + 0x619A, KANJI_STANDARD, // 憚 + 0x618A, KANJI_STANDARD, // 憊 + 0x6191, KANJI_STANDARD, // 憑 + 0x61AB, KANJI_STANDARD, // 憫 + 0x61AE, KANJI_STANDARD, // 憮 + 0x61CC, KANJI_STANDARD, // 懌 + 0x61CA, KANJI_STANDARD, // 懊 + 0x61C9, KANJI_STANDARD, // 應 + 0x61F7, KANJI_STANDARD, // 懷 + 0x61C8, KANJI_STANDARD, // 懈 + 0x61C3, KANJI_STANDARD, // 懃 + 0x61C6, KANJI_STANDARD, // 懆 + 0x61BA, KANJI_STANDARD, // 憺 + 0x61CB, KANJI_STANDARD, // 懋 + 0x7F79, KANJI_STANDARD, // 眹 + 0x61CD, KANJI_STANDARD, // 懍 + 0x61E6, KANJI_STANDARD, // 懊 + 0x61E3, KANJI_STANDARD, // 懣 + 0x61F6, KANJI_STANDARD, // 懶 + 0x61FA, KANJI_STANDARD, // 懺 + 0x61F4, KANJI_STANDARD, // 懎 + 0x61FF, KANJI_STANDARD, // 懿 + 0x61FD, KANJI_STANDARD, // 懜 + 0x61FC, KANJI_STANDARD, // 懌 + 0x61FE, KANJI_STANDARD, // 懟 + 0x6200, KANJI_STANDARD, // 戀 + 0x6208, KANJI_STANDARD, // 戈 + 0x6209, KANJI_STANDARD, // 戉 + 0x620D, KANJI_STANDARD, // 戍 + 0x620C, KANJI_STANDARD, // 戌 + 0x6214, KANJI_STANDARD, // 戔 + 0x621B, KANJI_STANDARD, // 戛 + 0x621E, KANJI_STANDARD, // 戞 + 0x6221, KANJI_STANDARD, // 戡 + 0x622A, KANJI_STANDARD, // 截 + 0x622E, KANJI_STANDARD, // 戮 + 0x6230, KANJI_STANDARD, // 戰 + 0x6232, KANJI_STANDARD, // 戲 + 0x6233, KANJI_STANDARD, // 戳 + 0x6241, KANJI_STANDARD, // 扁 + 0x624E, KANJI_STANDARD, // 扎 + 0x625E, KANJI_STANDARD, // 扞 + 0x6263, KANJI_STANDARD, // 扣 + 0x625B, KANJI_STANDARD, // 扛 + 0x6260, KANJI_STANDARD, // 扠 + 0x6268, KANJI_STANDARD, // 扚 + 0x627C, KANJI_STANDARD, // 扌 + 0x6282, KANJI_STANDARD, // 抂 + 0x6289, KANJI_STANDARD, // 抉 + 0x627E, KANJI_STANDARD, // 扟 + 0x6292, KANJI_STANDARD, // 抒 + 0x6293, KANJI_STANDARD, // 抓 + 0x6296, KANJI_STANDARD, // 抖 + 0x62D4, KANJI_STANDARD, // 拔 + 0x6283, KANJI_STANDARD, // 抃 + 0x6294, KANJI_STANDARD, // 抔 + 0x62D7, KANJI_STANDARD, // 拗 + 0x62D1, KANJI_STANDARD, // 拑 + 0x62BB, KANJI_STANDARD, // 抻 + 0x62CF, KANJI_STANDARD, // 拏 + 0x62FF, KANJI_STANDARD, // 拿 + 0x62C6, KANJI_STANDARD, // 拆 + 0x64D4, KANJI_STANDARD, // 擔 + 0x62C8, KANJI_STANDARD, // 拈 + 0x62DC, KANJI_STANDARD, // 拜 + 0x62CC, KANJI_STANDARD, // 拌 + 0x62CA, KANJI_STANDARD, // 拊 + 0x62C2, KANJI_STANDARD, // 拂 + 0x62C7, KANJI_STANDARD, // 拇 + 0x629B, KANJI_STANDARD, // 抛 + 0x62C9, KANJI_STANDARD, // 拉 + 0x630C, KANJI_STANDARD, // 挌 + 0x62EE, KANJI_STANDARD, // 拮 + 0x62F1, KANJI_STANDARD, // 拱 + 0x6327, KANJI_STANDARD, // 挧 + 0x6302, KANJI_STANDARD, // 挂 + 0x6308, KANJI_STANDARD, // 挈 + 0x62EF, KANJI_STANDARD, // 拯 + 0x62F5, KANJI_STANDARD, // 拵 + 0x6350, KANJI_STANDARD, // 捐 + 0x633E, KANJI_STANDARD, // 挟 + 0x634D, KANJI_STANDARD, // 捍 + 0x641C, KANJI_STANDARD, // 搜 + 0x634F, KANJI_STANDARD, // 捏 + 0x6396, KANJI_STANDARD, // 掖 + 0x638E, KANJI_STANDARD, // 掎 + 0x6380, KANJI_STANDARD, // 掀 + 0x63AB, KANJI_STANDARD, // 掫 + 0x6376, KANJI_STANDARD, // 捶 + 0x63A3, KANJI_STANDARD, // 掣 + 0x638F, KANJI_STANDARD, // 掏 + 0x6389, KANJI_STANDARD, // 掉 + 0x639F, KANJI_STANDARD, // 掟 + 0x63B5, KANJI_STANDARD, // 掵 + 0x636B, KANJI_STANDARD, // 捫 + 0x6369, KANJI_STANDARD, // 捩 + 0x63BE, KANJI_STANDARD, // 掟 + 0x63E9, KANJI_STANDARD, // 揩 + 0x63C0, KANJI_STANDARD, // 揀 + 0x63C6, KANJI_STANDARD, // 揆 + 0x63E3, KANJI_STANDARD, // 揣 + 0x63C9, KANJI_STANDARD, // 揉 + 0x63D2, KANJI_STANDARD, // 插 + 0x63F6, KANJI_STANDARD, // 揶 + 0x63C4, KANJI_STANDARD, // 揄 + 0x6416, KANJI_STANDARD, // 搖 + 0x6434, KANJI_STANDARD, // 搎 + 0x6406, KANJI_STANDARD, // 搆 + 0x6413, KANJI_STANDARD, // 搓 + 0x6426, KANJI_STANDARD, // 搊 + 0x6436, KANJI_STANDARD, // 搶 + 0x651D, KANJI_STANDARD, // 攝 + 0x6417, KANJI_STANDARD, // 搗 + 0x6428, KANJI_STANDARD, // 搚 + 0x640F, KANJI_STANDARD, // 搏 + 0x6467, KANJI_STANDARD, // 摧 + 0x646F, KANJI_STANDARD, // 摯 + 0x6476, KANJI_STANDARD, // 摶 + 0x644E, KANJI_STANDARD, // 摎 + 0x652A, KANJI_STANDARD, // 攪 + 0x6495, KANJI_STANDARD, // 撕 + 0x6493, KANJI_STANDARD, // 撓 + 0x64A5, KANJI_STANDARD, // 撥 + 0x64A9, KANJI_STANDARD, // 撩 + 0x6488, KANJI_STANDARD, // 撈 + 0x64BC, KANJI_STANDARD, // æ’Œ + 0x64DA, KANJI_STANDARD, // 據 + 0x64D2, KANJI_STANDARD, // 擒 + 0x64C5, KANJI_STANDARD, // 擅 + 0x64C7, KANJI_STANDARD, // 擇 + 0x64BB, KANJI_STANDARD, // 撻 + 0x64D8, KANJI_STANDARD, // 擘 + 0x64C2, KANJI_STANDARD, // 擂 + 0x64F1, KANJI_STANDARD, // 擱 + 0x64E7, KANJI_STANDARD, // 擧 + 0x8209, KANJI_STANDARD, // 舉 + 0x64E0, KANJI_STANDARD, // 擠 + 0x64E1, KANJI_STANDARD, // 擡 + 0x62AC, KANJI_STANDARD, // 抬 + 0x64E3, KANJI_STANDARD, // 擣 + 0x64EF, KANJI_STANDARD, // 擯 + 0x652C, KANJI_STANDARD, // 攬 + 0x64F6, KANJI_STANDARD, // 擶 + 0x64F4, KANJI_STANDARD, // 擎 + 0x64F2, KANJI_STANDARD, // 擲 + 0x64FA, KANJI_STANDARD, // 擺 + 0x6500, KANJI_STANDARD, // 攀 + 0x64FD, KANJI_STANDARD, // 擜 + 0x6518, KANJI_STANDARD, // 攘 + 0x651C, KANJI_STANDARD, // 攜 + 0x6505, KANJI_STANDARD, // 攅 + 0x6524, KANJI_STANDARD, // 攀 + 0x6523, KANJI_STANDARD, // 攣 + 0x652B, KANJI_STANDARD, // 攫 + 0x6534, KANJI_STANDARD, // 攎 + 0x6535, KANJI_STANDARD, // 攵 + 0x6537, KANJI_STANDARD, // 攷 + 0x6536, KANJI_STANDARD, // 收 + 0x6538, KANJI_STANDARD, // 攞 + 0x754B, KANJI_STANDARD, // 畋 + 0x6548, KANJI_STANDARD, // 效 + 0x6556, KANJI_STANDARD, // 敖 + 0x6555, KANJI_STANDARD, // 敕 + 0x654D, KANJI_STANDARD, // 敍 + 0x6558, KANJI_STANDARD, // 敘 + 0x655E, KANJI_STANDARD, // 敞 + 0x655D, KANJI_STANDARD, // 敝 + 0x6572, KANJI_STANDARD, // 敲 + 0x6578, KANJI_STANDARD, // 敞 + 0x6582, KANJI_STANDARD, // 斂 + 0x6583, KANJI_STANDARD, // 斃 + 0x8B8A, KANJI_STANDARD, // 變 + 0x659B, KANJI_STANDARD, // 斛 + 0x659F, KANJI_STANDARD, // 斟 + 0x65AB, KANJI_STANDARD, // 斫 + 0x65B7, KANJI_STANDARD, // 斷 + 0x65C3, KANJI_STANDARD, // 旃 + 0x65C6, KANJI_STANDARD, // 旆 + 0x65C1, KANJI_STANDARD, // 旁 + 0x65C4, KANJI_STANDARD, // 旄 + 0x65CC, KANJI_STANDARD, // 旌 + 0x65D2, KANJI_STANDARD, // 旒 + 0x65DB, KANJI_STANDARD, // 旛 + 0x65D9, KANJI_STANDARD, // 旙 + 0x65E0, KANJI_STANDARD, // 无 + 0x65E1, KANJI_STANDARD, // 旡 + 0x65F1, KANJI_STANDARD, // 旱 + 0x6772, KANJI_STANDARD, // 杲 + 0x660A, KANJI_STANDARD, // 昊 + 0x6603, KANJI_STANDARD, // 昃 + 0x65FB, KANJI_STANDARD, // 旻 + 0x6773, KANJI_STANDARD, // 杳 + 0x6635, KANJI_STANDARD, // 昵 + 0x6636, KANJI_STANDARD, // 昶 + 0x6634, KANJI_STANDARD, // 明 + 0x661C, KANJI_STANDARD, // 昜 + 0x664F, KANJI_STANDARD, // 晏 + 0x6644, KANJI_STANDARD, // 晄 + 0x6649, KANJI_STANDARD, // 晉 + 0x6641, KANJI_STANDARD, // 晁 + 0x665E, KANJI_STANDARD, // 晞 + 0x665D, KANJI_STANDARD, // 晝 + 0x6664, KANJI_STANDARD, // 晀 + 0x6667, KANJI_STANDARD, // 晧 + 0x6668, KANJI_STANDARD, // 晚 + 0x665F, KANJI_STANDARD, // 晟 + 0x6662, KANJI_STANDARD, // 晢 + 0x6670, KANJI_STANDARD, // 晰 + 0x6683, KANJI_STANDARD, // 暃 + 0x6688, KANJI_STANDARD, // 暈 + 0x668E, KANJI_STANDARD, // 暎 + 0x6689, KANJI_STANDARD, // 暉 + 0x6684, KANJI_STANDARD, // 暄 + 0x6698, KANJI_STANDARD, // 暘 + 0x669D, KANJI_STANDARD, // 暝 + 0x66C1, KANJI_STANDARD, // 曁 + 0x66B9, KANJI_STANDARD, // 暹 + 0x66C9, KANJI_STANDARD, // 曉 + 0x66BE, KANJI_STANDARD, // 暟 + 0x66BC, KANJI_STANDARD, // 暌 + 0x66C4, KANJI_STANDARD, // 曄 + 0x66B8, KANJI_STANDARD, // æšž + 0x66D6, KANJI_STANDARD, // 曖 + 0x66DA, KANJI_STANDARD, // 曚 + 0x66E0, KANJI_STANDARD, // 曠 + 0x663F, KANJI_STANDARD, // 昿 + 0x66E6, KANJI_STANDARD, // 曊 + 0x66E9, KANJI_STANDARD, // 曩 + 0x66F0, KANJI_STANDARD, // 曰 + 0x66F5, KANJI_STANDARD, // 曵 + 0x66F7, KANJI_STANDARD, // 曷 + 0x670F, KANJI_STANDARD, // 朏 + 0x6716, KANJI_STANDARD, // 朖 + 0x671E, KANJI_STANDARD, // 朞 + 0x6726, KANJI_STANDARD, // 朊 + 0x6727, KANJI_STANDARD, // 朧 + 0x9738, KANJI_STANDARD, // 霾 + 0x672E, KANJI_STANDARD, // 朮 + 0x673F, KANJI_STANDARD, // 朿 + 0x6736, KANJI_STANDARD, // 朶 + 0x6741, KANJI_STANDARD, // 杁 + 0x6738, KANJI_STANDARD, // 朞 + 0x6737, KANJI_STANDARD, // 朷 + 0x6746, KANJI_STANDARD, // 杆 + 0x675E, KANJI_STANDARD, // 杞 + 0x6760, KANJI_STANDARD, // 杠 + 0x6759, KANJI_STANDARD, // 杙 + 0x6763, KANJI_STANDARD, // 杣 + 0x6764, KANJI_STANDARD, // 杀 + 0x6789, KANJI_STANDARD, // 枉 + 0x6770, KANJI_STANDARD, // 杰 + 0x67A9, KANJI_STANDARD, // 枩 + 0x677C, KANJI_STANDARD, // 杌 + 0x676A, KANJI_STANDARD, // 杪 + 0x678C, KANJI_STANDARD, // 枌 + 0x678B, KANJI_STANDARD, // 枋 + 0x67A6, KANJI_STANDARD, // 枊 + 0x67A1, KANJI_STANDARD, // 枡 + 0x6785, KANJI_STANDARD, // 枅 + 0x67B7, KANJI_STANDARD, // 枷 + 0x67EF, KANJI_STANDARD, // 柯 + 0x67B4, KANJI_STANDARD, // 枎 + 0x67EC, KANJI_STANDARD, // 柬 + 0x67B3, KANJI_STANDARD, // 枳 + 0x67E9, KANJI_STANDARD, // 柩 + 0x67B8, KANJI_STANDARD, // æžž + 0x67E4, KANJI_STANDARD, // 柀 + 0x67DE, KANJI_STANDARD, // 柞 + 0x67DD, KANJI_STANDARD, // 柝 + 0x67E2, KANJI_STANDARD, // 柢 + 0x67EE, KANJI_STANDARD, // 柮 + 0x67B9, KANJI_STANDARD, // 枹 + 0x67CE, KANJI_STANDARD, // 柎 + 0x67C6, KANJI_STANDARD, // 柆 + 0x67E7, KANJI_STANDARD, // 柧 + 0x6A9C, KANJI_STANDARD, // 檜 + 0x681E, KANJI_STANDARD, // 栞 + 0x6846, KANJI_STANDARD, // 框 + 0x6829, KANJI_STANDARD, // æ © + 0x6840, KANJI_STANDARD, // 桀 + 0x684D, KANJI_STANDARD, // 桍 + 0x6832, KANJI_STANDARD, // æ ² + 0x684E, KANJI_STANDARD, // 桎 + 0x68B3, KANJI_STANDARD, // 梳 + 0x682B, KANJI_STANDARD, // æ « + 0x6859, KANJI_STANDARD, // 桙 + 0x6863, KANJI_STANDARD, // æ¡£ + 0x6877, KANJI_STANDARD, // æ¡· + 0x687F, KANJI_STANDARD, // æ¡¿ + 0x689F, KANJI_STANDARD, // 梟 + 0x688F, KANJI_STANDARD, // 梏 + 0x68AD, KANJI_STANDARD, // 梭 + 0x6894, KANJI_STANDARD, // 梔 + 0x689D, KANJI_STANDARD, // 條 + 0x689B, KANJI_STANDARD, // 梛 + 0x6883, KANJI_STANDARD, // 梃 + 0x6AAE, KANJI_STANDARD, // 檮 + 0x68B9, KANJI_STANDARD, // 梹 + 0x6874, KANJI_STANDARD, // 桎 + 0x68B5, KANJI_STANDARD, // 梵 + 0x68A0, KANJI_STANDARD, // 梠 + 0x68BA, KANJI_STANDARD, // 梺 + 0x690F, KANJI_STANDARD, // 怏 + 0x688D, KANJI_STANDARD, // 梍 + 0x687E, KANJI_STANDARD, // 桟 + 0x6901, KANJI_STANDARD, // 态 + 0x68CA, KANJI_STANDARD, // 棊 + 0x6908, KANJI_STANDARD, // 怈 + 0x68D8, KANJI_STANDARD, // 棘 + 0x6922, KANJI_STANDARD, // 怢 + 0x6926, KANJI_STANDARD, // 怊 + 0x68E1, KANJI_STANDARD, // 棡 + 0x690C, KANJI_STANDARD, // 怌 + 0x68CD, KANJI_STANDARD, // 棍 + 0x68D4, KANJI_STANDARD, // 棔 + 0x68E7, KANJI_STANDARD, // 棧 + 0x68D5, KANJI_STANDARD, // 棕 + 0x6936, KANJI_STANDARD, // 怶 + 0x6912, KANJI_STANDARD, // 怒 + 0x6904, KANJI_STANDARD, // 怄 + 0x68D7, KANJI_STANDARD, // 棗 + 0x68E3, KANJI_STANDARD, // 棣 + 0x6925, KANJI_STANDARD, // 急 + 0x68F9, KANJI_STANDARD, // 棹 + 0x68E0, KANJI_STANDARD, // 棠 + 0x68EF, KANJI_STANDARD, // 棯 + 0x6928, KANJI_STANDARD, // 怚 + 0x692A, KANJI_STANDARD, // 怪 + 0x691A, KANJI_STANDARD, // 怚 + 0x6923, KANJI_STANDARD, // 怣 + 0x6921, KANJI_STANDARD, // 怡 + 0x68C6, KANJI_STANDARD, // 棆 + 0x6979, KANJI_STANDARD, // 楹 + 0x6977, KANJI_STANDARD, // 楷 + 0x695C, KANJI_STANDARD, // 楜 + 0x6978, KANJI_STANDARD, // 楞 + 0x696B, KANJI_STANDARD, // 楫 + 0x6954, KANJI_STANDARD, // 楔 + 0x697E, KANJI_STANDARD, // 楟 + 0x696E, KANJI_STANDARD, // 楮 + 0x6939, KANJI_STANDARD, // 怹 + 0x6974, KANJI_STANDARD, // 楎 + 0x693D, KANJI_STANDARD, // 怜 + 0x6959, KANJI_STANDARD, // 楙 + 0x6930, KANJI_STANDARD, // 怰 + 0x6961, KANJI_STANDARD, // 楡 + 0x695E, KANJI_STANDARD, // 楞 + 0x695D, KANJI_STANDARD, // 楝 + 0x6981, KANJI_STANDARD, // 抁 + 0x696A, KANJI_STANDARD, // 楪 + 0x69B2, KANJI_STANDARD, // 抲 + 0x69AE, KANJI_STANDARD, // 抮 + 0x69D0, KANJI_STANDARD, // 槐 + 0x69BF, KANJI_STANDARD, // 抿 + 0x69C1, KANJI_STANDARD, // 槁 + 0x69D3, KANJI_STANDARD, // 槓 + 0x69BE, KANJI_STANDARD, // 抟 + 0x69CE, KANJI_STANDARD, // 槎 + 0x5BE8, KANJI_STANDARD, // 寚 + 0x69CA, KANJI_STANDARD, // 槊 + 0x69DD, KANJI_STANDARD, // 槝 + 0x69BB, KANJI_STANDARD, // 抻 + 0x69C3, KANJI_STANDARD, // 槃 + 0x69A7, KANJI_STANDARD, // 抧 + 0x6A2E, KANJI_STANDARD, // æš® + 0x6991, KANJI_STANDARD, // 抑 + 0x69A0, KANJI_STANDARD, // 抠 + 0x699C, KANJI_STANDARD, // 抜 + 0x6995, KANJI_STANDARD, // 投 + 0x69B4, KANJI_STANDARD, // 抎 + 0x69DE, KANJI_STANDARD, // 槞 + 0x69E8, KANJI_STANDARD, // æ§š + 0x6A02, KANJI_STANDARD, // æš‚ + 0x6A1B, KANJI_STANDARD, // æš› + 0x69FF, KANJI_STANDARD, // æ§¿ + 0x6B0A, KANJI_STANDARD, // 權 + 0x69F9, KANJI_STANDARD, // æ§¹ + 0x69F2, KANJI_STANDARD, // æ§² + 0x69E7, KANJI_STANDARD, // æ§§ + 0x6A05, KANJI_STANDARD, // æš… + 0x69B1, KANJI_STANDARD, // 抱 + 0x6A1E, KANJI_STANDARD, // 暞 + 0x69ED, KANJI_STANDARD, // æ§­ + 0x6A14, KANJI_STANDARD, // æš” + 0x69EB, KANJI_STANDARD, // æ§« + 0x6A0A, KANJI_STANDARD, // 暊 + 0x6A12, KANJI_STANDARD, // æš’ + 0x6AC1, KANJI_STANDARD, // 櫁 + 0x6A23, KANJI_STANDARD, // 暣 + 0x6A13, KANJI_STANDARD, // æš“ + 0x6A44, KANJI_STANDARD, // 橄 + 0x6A0C, KANJI_STANDARD, // 暌 + 0x6A72, KANJI_STANDARD, // 橲 + 0x6A36, KANJI_STANDARD, // æš¶ + 0x6A78, KANJI_STANDARD, // 橞 + 0x6A47, KANJI_STANDARD, // 橇 + 0x6A62, KANJI_STANDARD, // æ©¢ + 0x6A59, KANJI_STANDARD, // 橙 + 0x6A66, KANJI_STANDARD, // 橊 + 0x6A48, KANJI_STANDARD, // 橈 + 0x6A38, KANJI_STANDARD, // æšž + 0x6A22, KANJI_STANDARD, // 暢 + 0x6A90, KANJI_STANDARD, // 檐 + 0x6A8D, KANJI_STANDARD, // 檍 + 0x6AA0, KANJI_STANDARD, // 檠 + 0x6A84, KANJI_STANDARD, // 檄 + 0x6AA2, KANJI_STANDARD, // 檢 + 0x6AA3, KANJI_STANDARD, // 檣 + 0x6A97, KANJI_STANDARD, // 檗 + 0x8617, KANJI_STANDARD, // 蘗 + 0x6ABB, KANJI_STANDARD, // 檻 + 0x6AC3, KANJI_STANDARD, // 櫃 + 0x6AC2, KANJI_STANDARD, // 櫂 + 0x6AB8, KANJI_STANDARD, // 檞 + 0x6AB3, KANJI_STANDARD, // 檳 + 0x6AAC, KANJI_STANDARD, // 檬 + 0x6ADE, KANJI_STANDARD, // 櫞 + 0x6AD1, KANJI_STANDARD, // 櫑 + 0x6ADF, KANJI_STANDARD, // 櫟 + 0x6AAA, KANJI_STANDARD, // 檪 + 0x6ADA, KANJI_STANDARD, // 櫚 + 0x6AEA, KANJI_STANDARD, // 櫪 + 0x6AFB, KANJI_STANDARD, // æ«» + 0x6B05, KANJI_STANDARD, // 欅 + 0x8616, KANJI_STANDARD, // 蘖 + 0x6AFA, KANJI_STANDARD, // 櫺 + 0x6B12, KANJI_STANDARD, // 欒 + 0x6B16, KANJI_STANDARD, // 欖 + 0x9B31, KANJI_STANDARD, // 鬱 + 0x6B1F, KANJI_STANDARD, // 欟 + 0x6B38, KANJI_STANDARD, // 欞 + 0x6B37, KANJI_STANDARD, // 欷 + 0x76DC, KANJI_STANDARD, // 盜 + 0x6B39, KANJI_STANDARD, // 欹 + 0x98EE, KANJI_STANDARD, // 飮 + 0x6B47, KANJI_STANDARD, // 歇 + 0x6B43, KANJI_STANDARD, // 歃 + 0x6B49, KANJI_STANDARD, // 歉 + 0x6B50, KANJI_STANDARD, // 歐 + 0x6B59, KANJI_STANDARD, // 歙 + 0x6B54, KANJI_STANDARD, // 歔 + 0x6B5B, KANJI_STANDARD, // 歛 + 0x6B5F, KANJI_STANDARD, // 歟 + 0x6B61, KANJI_STANDARD, // æ­¡ + 0x6B78, KANJI_STANDARD, // æ­ž + 0x6B79, KANJI_STANDARD, // æ­¹ + 0x6B7F, KANJI_STANDARD, // æ­¿ + 0x6B80, KANJI_STANDARD, // 殀 + 0x6B84, KANJI_STANDARD, // 殄 + 0x6B83, KANJI_STANDARD, // 殃 + 0x6B8D, KANJI_STANDARD, // 殍 + 0x6B98, KANJI_STANDARD, // 殘 + 0x6B95, KANJI_STANDARD, // 殕 + 0x6B9E, KANJI_STANDARD, // 殞 + 0x6BA4, KANJI_STANDARD, // 殀 + 0x6BAA, KANJI_STANDARD, // 殪 + 0x6BAB, KANJI_STANDARD, // 殫 + 0x6BAF, KANJI_STANDARD, // 殯 + 0x6BB2, KANJI_STANDARD, // 殲 + 0x6BB1, KANJI_STANDARD, // æ®± + 0x6BB3, KANJI_STANDARD, // 殳 + 0x6BB7, KANJI_STANDARD, // æ®· + 0x6BBC, KANJI_STANDARD, // 殌 + 0x6BC6, KANJI_STANDARD, // 毆 + 0x6BCB, KANJI_STANDARD, // 毋 + 0x6BD3, KANJI_STANDARD, // 毓 + 0x6BDF, KANJI_STANDARD, // 毟 + 0x6BEC, KANJI_STANDARD, // 毬 + 0x6BEB, KANJI_STANDARD, // 毫 + 0x6BF3, KANJI_STANDARD, // 毳 + 0x6BEF, KANJI_STANDARD, // 毯 + 0x9EBE, KANJI_STANDARD, // 麟 + 0x6C08, KANJI_STANDARD, // 氈 + 0x6C13, KANJI_STANDARD, // 氓 + 0x6C14, KANJI_STANDARD, // 气 + 0x6C1B, KANJI_STANDARD, // 氛 + 0x6C24, KANJI_STANDARD, // æ°€ + 0x6C23, KANJI_STANDARD, // æ°£ + 0x6C5E, KANJI_STANDARD, // 汞 + 0x6C55, KANJI_STANDARD, // 汕 + 0x6C62, KANJI_STANDARD, // æ±¢ + 0x6C6A, KANJI_STANDARD, // 汪 + 0x6C82, KANJI_STANDARD, // 沂 + 0x6C8D, KANJI_STANDARD, // 沍 + 0x6C9A, KANJI_STANDARD, // 沚 + 0x6C81, KANJI_STANDARD, // 沁 + 0x6C9B, KANJI_STANDARD, // 沛 + 0x6C7E, KANJI_STANDARD, // 江 + 0x6C68, KANJI_STANDARD, // 汚 + 0x6C73, KANJI_STANDARD, // æ±³ + 0x6C92, KANJI_STANDARD, // 沒 + 0x6C90, KANJI_STANDARD, // 沐 + 0x6CC4, KANJI_STANDARD, // 泄 + 0x6CF1, KANJI_STANDARD, // æ³± + 0x6CD3, KANJI_STANDARD, // 泓 + 0x6CBD, KANJI_STANDARD, // 沜 + 0x6CD7, KANJI_STANDARD, // 泗 + 0x6CC5, KANJI_STANDARD, // 泅 + 0x6CDD, KANJI_STANDARD, // 泝 + 0x6CAE, KANJI_STANDARD, // æ²® + 0x6CB1, KANJI_STANDARD, // æ²± + 0x6CBE, KANJI_STANDARD, // 沟 + 0x6CBA, KANJI_STANDARD, // 沺 + 0x6CDB, KANJI_STANDARD, // 泛 + 0x6CEF, KANJI_STANDARD, // 泯 + 0x6CD9, KANJI_STANDARD, // 泙 + 0x6CEA, KANJI_STANDARD, // 泪 + 0x6D1F, KANJI_STANDARD, // 掟 + 0x884D, KANJI_STANDARD, // 衍 + 0x6D36, KANJI_STANDARD, // 掶 + 0x6D2B, KANJI_STANDARD, // 掫 + 0x6D3D, KANJI_STANDARD, // 掜 + 0x6D38, KANJI_STANDARD, // 掞 + 0x6D19, KANJI_STANDARD, // 掙 + 0x6D35, KANJI_STANDARD, // 掵 + 0x6D33, KANJI_STANDARD, // 掳 + 0x6D12, KANJI_STANDARD, // 排 + 0x6D0C, KANJI_STANDARD, // 掌 + 0x6D63, KANJI_STANDARD, // æµ£ + 0x6D93, KANJI_STANDARD, // 涓 + 0x6D64, KANJI_STANDARD, // æµ€ + 0x6D5A, KANJI_STANDARD, // 浚 + 0x6D79, KANJI_STANDARD, // æµ¹ + 0x6D59, KANJI_STANDARD, // 浙 + 0x6D8E, KANJI_STANDARD, // 涎 + 0x6D95, KANJI_STANDARD, // 涕 + 0x6FE4, KANJI_STANDARD, // æ¿€ + 0x6D85, KANJI_STANDARD, // 涅 + 0x6DF9, KANJI_STANDARD, // æ·¹ + 0x6E15, KANJI_STANDARD, // æž• + 0x6E0A, KANJI_STANDARD, // 枊 + 0x6DB5, KANJI_STANDARD, // æ¶µ + 0x6DC7, KANJI_STANDARD, // 淇 + 0x6DE6, KANJI_STANDARD, // æ·Š + 0x6DB8, KANJI_STANDARD, // æ¶ž + 0x6DC6, KANJI_STANDARD, // 淆 + 0x6DEC, KANJI_STANDARD, // æ·¬ + 0x6DDE, KANJI_STANDARD, // 淞 + 0x6DCC, KANJI_STANDARD, // 淌 + 0x6DE8, KANJI_STANDARD, // æ·š + 0x6DD2, KANJI_STANDARD, // 淒 + 0x6DC5, KANJI_STANDARD, // 淅 + 0x6DFA, KANJI_STANDARD, // æ·º + 0x6DD9, KANJI_STANDARD, // 淙 + 0x6DE4, KANJI_STANDARD, // æ·€ + 0x6DD5, KANJI_STANDARD, // 淕 + 0x6DEA, KANJI_STANDARD, // æ·ª + 0x6DEE, KANJI_STANDARD, // æ·® + 0x6E2D, KANJI_STANDARD, // æž­ + 0x6E6E, KANJI_STANDARD, // æ¹® + 0x6E2E, KANJI_STANDARD, // æž® + 0x6E19, KANJI_STANDARD, // æž™ + 0x6E72, KANJI_STANDARD, // æ¹² + 0x6E5F, KANJI_STANDARD, // 湟 + 0x6E3E, KANJI_STANDARD, // 枟 + 0x6E23, KANJI_STANDARD, // 枣 + 0x6E6B, KANJI_STANDARD, // 湫 + 0x6E2B, KANJI_STANDARD, // æž« + 0x6E76, KANJI_STANDARD, // æ¹¶ + 0x6E4D, KANJI_STANDARD, // 湍 + 0x6E1F, KANJI_STANDARD, // 枟 + 0x6E43, KANJI_STANDARD, // 湃 + 0x6E3A, KANJI_STANDARD, // 枺 + 0x6E4E, KANJI_STANDARD, // 湎 + 0x6E24, KANJI_STANDARD, // 枀 + 0x6EFF, KANJI_STANDARD, // 滿 + 0x6E1D, KANJI_STANDARD, // 枝 + 0x6E38, KANJI_STANDARD, // æžž + 0x6E82, KANJI_STANDARD, // 溂 + 0x6EAA, KANJI_STANDARD, // 溪 + 0x6E98, KANJI_STANDARD, // 溘 + 0x6EC9, KANJI_STANDARD, // 滉 + 0x6EB7, KANJI_STANDARD, // 溷 + 0x6ED3, KANJI_STANDARD, // 滓 + 0x6EBD, KANJI_STANDARD, // 溜 + 0x6EAF, KANJI_STANDARD, // 溯 + 0x6EC4, KANJI_STANDARD, // 滄 + 0x6EB2, KANJI_STANDARD, // 溲 + 0x6ED4, KANJI_STANDARD, // 滔 + 0x6ED5, KANJI_STANDARD, // 滕 + 0x6E8F, KANJI_STANDARD, // 溏 + 0x6EA5, KANJI_STANDARD, // 溥 + 0x6EC2, KANJI_STANDARD, // 滂 + 0x6E9F, KANJI_STANDARD, // 溟 + 0x6F41, KANJI_STANDARD, // 朁 + 0x6F11, KANJI_STANDARD, // 挑 + 0x704C, KANJI_STANDARD, // 灌 + 0x6EEC, KANJI_STANDARD, // 滬 + 0x6EF8, KANJI_STANDARD, // 滞 + 0x6EFE, KANJI_STANDARD, // 滟 + 0x6F3F, KANJI_STANDARD, // 挿 + 0x6EF2, KANJI_STANDARD, // 滲 + 0x6F31, KANJI_STANDARD, // 挱 + 0x6EEF, KANJI_STANDARD, // 滯 + 0x6F32, KANJI_STANDARD, // 挲 + 0x6ECC, KANJI_STANDARD, // 滌 + 0x6F3E, KANJI_STANDARD, // 挟 + 0x6F13, KANJI_STANDARD, // 挓 + 0x6EF7, KANJI_STANDARD, // æ»· + 0x6F86, KANJI_STANDARD, // 柆 + 0x6F7A, KANJI_STANDARD, // 机 + 0x6F78, KANJI_STANDARD, // 朞 + 0x6F81, KANJI_STANDARD, // 柁 + 0x6F80, KANJI_STANDARD, // 柀 + 0x6F6F, KANJI_STANDARD, // 术 + 0x6F5B, KANJI_STANDARD, // 望 + 0x6FF3, KANJI_STANDARD, // 濳 + 0x6F6D, KANJI_STANDARD, // 札 + 0x6F82, KANJI_STANDARD, // 柂 + 0x6F7C, KANJI_STANDARD, // 朌 + 0x6F58, KANJI_STANDARD, // 朘 + 0x6F8E, KANJI_STANDARD, // 柎 + 0x6F91, KANJI_STANDARD, // 柑 + 0x6FC2, KANJI_STANDARD, // 濂 + 0x6F66, KANJI_STANDARD, // 朊 + 0x6FB3, KANJI_STANDARD, // 柳 + 0x6FA3, KANJI_STANDARD, // 柣 + 0x6FA1, KANJI_STANDARD, // 柡 + 0x6FA4, KANJI_STANDARD, // 柀 + 0x6FB9, KANJI_STANDARD, // 柹 + 0x6FC6, KANJI_STANDARD, // 濆 + 0x6FAA, KANJI_STANDARD, // 柪 + 0x6FDF, KANJI_STANDARD, // 濟 + 0x6FD5, KANJI_STANDARD, // 濕 + 0x6FEC, KANJI_STANDARD, // 濬 + 0x6FD4, KANJI_STANDARD, // 濔 + 0x6FD8, KANJI_STANDARD, // 濘 + 0x6FF1, KANJI_STANDARD, // 濱 + 0x6FEE, KANJI_STANDARD, // æ¿® + 0x6FDB, KANJI_STANDARD, // 濛 + 0x7009, KANJI_STANDARD, // 瀉 + 0x700B, KANJI_STANDARD, // 瀋 + 0x6FFA, KANJI_STANDARD, // 濺 + 0x7011, KANJI_STANDARD, // 瀑 + 0x7001, KANJI_STANDARD, // 瀁 + 0x700F, KANJI_STANDARD, // 瀏 + 0x6FFE, KANJI_STANDARD, // 濟 + 0x701B, KANJI_STANDARD, // 瀛 + 0x701A, KANJI_STANDARD, // 瀚 + 0x6F74, KANJI_STANDARD, // 朎 + 0x701D, KANJI_STANDARD, // 瀝 + 0x7018, KANJI_STANDARD, // 瀘 + 0x701F, KANJI_STANDARD, // 瀟 + 0x7030, KANJI_STANDARD, // 瀰 + 0x703E, KANJI_STANDARD, // 瀟 + 0x7032, KANJI_STANDARD, // 瀲 + 0x7051, KANJI_STANDARD, // 灑 + 0x7063, KANJI_STANDARD, // 灣 + 0x7099, KANJI_STANDARD, // 炙 + 0x7092, KANJI_STANDARD, // 炒 + 0x70AF, KANJI_STANDARD, // 炯 + 0x70F1, KANJI_STANDARD, // 烱 + 0x70AC, KANJI_STANDARD, // 炬 + 0x70B8, KANJI_STANDARD, // 炾 + 0x70B3, KANJI_STANDARD, // 炳 + 0x70AE, KANJI_STANDARD, // 炮 + 0x70DF, KANJI_STANDARD, // 烟 + 0x70CB, KANJI_STANDARD, // 烋 + 0x70DD, KANJI_STANDARD, // 烝 + 0x70D9, KANJI_STANDARD, // 烙 + 0x7109, KANJI_STANDARD, // 焉 + 0x70FD, KANJI_STANDARD, // 烜 + 0x711C, KANJI_STANDARD, // 焜 + 0x7119, KANJI_STANDARD, // 焙 + 0x7165, KANJI_STANDARD, // 煥 + 0x7155, KANJI_STANDARD, // 煕 + 0x7188, KANJI_STANDARD, // 熈 + 0x7166, KANJI_STANDARD, // 煩 + 0x7162, KANJI_STANDARD, // 煢 + 0x714C, KANJI_STANDARD, // 煌 + 0x7156, KANJI_STANDARD, // 煖 + 0x716C, KANJI_STANDARD, // 煬 + 0x718F, KANJI_STANDARD, // 熏 + 0x71FB, KANJI_STANDARD, // 燻 + 0x7184, KANJI_STANDARD, // 熄 + 0x7195, KANJI_STANDARD, // 熕 + 0x71A8, KANJI_STANDARD, // 熹 + 0x71AC, KANJI_STANDARD, // 熬 + 0x71D7, KANJI_STANDARD, // 燗 + 0x71B9, KANJI_STANDARD, // 熹 + 0x71BE, KANJI_STANDARD, // 熟 + 0x71D2, KANJI_STANDARD, // 燒 + 0x71C9, KANJI_STANDARD, // 燉 + 0x71D4, KANJI_STANDARD, // 燔 + 0x71CE, KANJI_STANDARD, // 燎 + 0x71E0, KANJI_STANDARD, // 燠 + 0x71EC, KANJI_STANDARD, // 燬 + 0x71E7, KANJI_STANDARD, // 燧 + 0x71F5, KANJI_STANDARD, // 燵 + 0x71FC, KANJI_STANDARD, // 燌 + 0x71F9, KANJI_STANDARD, // 燹 + 0x71FF, KANJI_STANDARD, // 燿 + 0x720D, KANJI_STANDARD, // 爍 + 0x7210, KANJI_STANDARD, // 爐 + 0x721B, KANJI_STANDARD, // 爛 + 0x7228, KANJI_STANDARD, // 爚 + 0x722D, KANJI_STANDARD, // 爭 + 0x722C, KANJI_STANDARD, // 爬 + 0x7230, KANJI_STANDARD, // 爰 + 0x7232, KANJI_STANDARD, // 爲 + 0x723B, KANJI_STANDARD, // 爻 + 0x723C, KANJI_STANDARD, // 爌 + 0x723F, KANJI_STANDARD, // 爿 + 0x7240, KANJI_STANDARD, // 牀 + 0x7246, KANJI_STANDARD, // 牆 + 0x724B, KANJI_STANDARD, // 牋 + 0x7258, KANJI_STANDARD, // 牘 + 0x7274, KANJI_STANDARD, // 牮 + 0x727E, KANJI_STANDARD, // 牟 + 0x7282, KANJI_STANDARD, // 犂 + 0x7281, KANJI_STANDARD, // 犁 + 0x7287, KANJI_STANDARD, // 犇 + 0x7292, KANJI_STANDARD, // 犒 + 0x7296, KANJI_STANDARD, // 犖 + 0x72A2, KANJI_STANDARD, // 犢 + 0x72A7, KANJI_STANDARD, // 犧 + 0x72B9, KANJI_STANDARD, // 犹 + 0x72B2, KANJI_STANDARD, // 犲 + 0x72C3, KANJI_STANDARD, // 狃 + 0x72C6, KANJI_STANDARD, // 狆 + 0x72C4, KANJI_STANDARD, // 狄 + 0x72CE, KANJI_STANDARD, // 狎 + 0x72D2, KANJI_STANDARD, // 狒 + 0x72E2, KANJI_STANDARD, // 狢 + 0x72E0, KANJI_STANDARD, // 狠 + 0x72E1, KANJI_STANDARD, // 狡 + 0x72F9, KANJI_STANDARD, // 狹 + 0x72F7, KANJI_STANDARD, // 狷 + 0x500F, KANJI_STANDARD, // 倏 + 0x7317, KANJI_STANDARD, // 猗 + 0x730A, KANJI_STANDARD, // 猊 + 0x731C, KANJI_STANDARD, // 猜 + 0x7316, KANJI_STANDARD, // 猖 + 0x731D, KANJI_STANDARD, // 猝 + 0x7334, KANJI_STANDARD, // 献 + 0x732F, KANJI_STANDARD, // 猯 + 0x7329, KANJI_STANDARD, // 猩 + 0x7325, KANJI_STANDARD, // 猥 + 0x733E, KANJI_STANDARD, // 猟 + 0x734E, KANJI_STANDARD, // 獎 + 0x734F, KANJI_STANDARD, // 獏 + 0x9ED8, KANJI_STANDARD, // 默 + 0x7357, KANJI_STANDARD, // 獗 + 0x736A, KANJI_STANDARD, // 獪 + 0x7368, KANJI_STANDARD, // 獚 + 0x7370, KANJI_STANDARD, // 獰 + 0x7378, KANJI_STANDARD, // 獞 + 0x7375, KANJI_STANDARD, // 獵 + 0x737B, KANJI_STANDARD, // 獻 + 0x737A, KANJI_STANDARD, // 獺 + 0x73C8, KANJI_STANDARD, // 珈 + 0x73B3, KANJI_STANDARD, // 玳 + 0x73CE, KANJI_STANDARD, // 珎 + 0x73BB, KANJI_STANDARD, // 玻 + 0x73C0, KANJI_STANDARD, // 珀 + 0x73E5, KANJI_STANDARD, // 珥 + 0x73EE, KANJI_STANDARD, // 珮 + 0x73DE, KANJI_STANDARD, // 珞 + 0x74A2, KANJI_STANDARD, // 璢 + 0x7405, KANJI_STANDARD, // 琅 + 0x746F, KANJI_STANDARD, // 瑯 + 0x7425, KANJI_STANDARD, // 琥 + 0x73F8, KANJI_STANDARD, // 珞 + 0x7432, KANJI_STANDARD, // 琲 + 0x743A, KANJI_STANDARD, // 琺 + 0x7455, KANJI_STANDARD, // 瑕 + 0x743F, KANJI_STANDARD, // 琿 + 0x745F, KANJI_STANDARD, // 瑟 + 0x7459, KANJI_STANDARD, // 瑙 + 0x7441, KANJI_STANDARD, // 瑁 + 0x745C, KANJI_STANDARD, // 瑜 + 0x7469, KANJI_STANDARD, // 瑩 + 0x7470, KANJI_STANDARD, // 瑰 + 0x7463, KANJI_STANDARD, // 瑣 + 0x746A, KANJI_STANDARD, // 瑪 + 0x7476, KANJI_STANDARD, // 瑶 + 0x747E, KANJI_STANDARD, // 瑟 + 0x748B, KANJI_STANDARD, // 璋 + 0x749E, KANJI_STANDARD, // 璞 + 0x74A7, KANJI_STANDARD, // 璧 + 0x74CA, KANJI_STANDARD, // 瓊 + 0x74CF, KANJI_STANDARD, // 瓏 + 0x74D4, KANJI_STANDARD, // 瓔 + 0x73F1, KANJI_STANDARD, // 珱 + 0x74E0, KANJI_STANDARD, // 瓠 + 0x74E3, KANJI_STANDARD, // 瓣 + 0x74E7, KANJI_STANDARD, // 瓧 + 0x74E9, KANJI_STANDARD, // 瓩 + 0x74EE, KANJI_STANDARD, // 瓮 + 0x74F2, KANJI_STANDARD, // 瓲 + 0x74F0, KANJI_STANDARD, // 瓰 + 0x74F1, KANJI_STANDARD, // 瓱 + 0x74F8, KANJI_STANDARD, // 瓾 + 0x74F7, KANJI_STANDARD, // 瓷 + 0x7504, KANJI_STANDARD, // 甄 + 0x7503, KANJI_STANDARD, // 甃 + 0x7505, KANJI_STANDARD, // 甅 + 0x750C, KANJI_STANDARD, // 甌 + 0x750E, KANJI_STANDARD, // 甎 + 0x750D, KANJI_STANDARD, // 甍 + 0x7515, KANJI_STANDARD, // 甕 + 0x7513, KANJI_STANDARD, // 甓 + 0x751E, KANJI_STANDARD, // 甞 + 0x7526, KANJI_STANDARD, // 甩 + 0x752C, KANJI_STANDARD, // 甬 + 0x753C, KANJI_STANDARD, // 甌 + 0x7544, KANJI_STANDARD, // 畄 + 0x754D, KANJI_STANDARD, // 畍 + 0x754A, KANJI_STANDARD, // 畊 + 0x7549, KANJI_STANDARD, // 畉 + 0x755B, KANJI_STANDARD, // 畛 + 0x7546, KANJI_STANDARD, // 畆 + 0x755A, KANJI_STANDARD, // 畚 + 0x7569, KANJI_STANDARD, // 畩 + 0x7564, KANJI_STANDARD, // ç•€ + 0x7567, KANJI_STANDARD, // 畧 + 0x756B, KANJI_STANDARD, // 畫 + 0x756D, KANJI_STANDARD, // 畭 + 0x7578, KANJI_STANDARD, // 畾 + 0x7576, KANJI_STANDARD, // 當 + 0x7586, KANJI_STANDARD, // 疆 + 0x7587, KANJI_STANDARD, // 疇 + 0x7574, KANJI_STANDARD, // 畮 + 0x758A, KANJI_STANDARD, // 疊 + 0x7589, KANJI_STANDARD, // 疉 + 0x7582, KANJI_STANDARD, // 疂 + 0x7594, KANJI_STANDARD, // 疔 + 0x759A, KANJI_STANDARD, // 疚 + 0x759D, KANJI_STANDARD, // 疝 + 0x75A5, KANJI_STANDARD, // 疥 + 0x75A3, KANJI_STANDARD, // 疣 + 0x75C2, KANJI_STANDARD, // 痂 + 0x75B3, KANJI_STANDARD, // 疳 + 0x75C3, KANJI_STANDARD, // 痃 + 0x75B5, KANJI_STANDARD, // 疵 + 0x75BD, KANJI_STANDARD, // ç–œ + 0x75B8, KANJI_STANDARD, // 疾 + 0x75BC, KANJI_STANDARD, // ç–Œ + 0x75B1, KANJI_STANDARD, // 疱 + 0x75CD, KANJI_STANDARD, // 痍 + 0x75CA, KANJI_STANDARD, // 痊 + 0x75D2, KANJI_STANDARD, // 痒 + 0x75D9, KANJI_STANDARD, // 痙 + 0x75E3, KANJI_STANDARD, // 痣 + 0x75DE, KANJI_STANDARD, // 痞 + 0x75FE, KANJI_STANDARD, // ç—Ÿ + 0x75FF, KANJI_STANDARD, // 痿 + 0x75FC, KANJI_STANDARD, // ç—Œ + 0x7601, KANJI_STANDARD, // 瘁 + 0x75F0, KANJI_STANDARD, // 痰 + 0x75FA, KANJI_STANDARD, // 痺 + 0x75F2, KANJI_STANDARD, // 痲 + 0x75F3, KANJI_STANDARD, // 痳 + 0x760B, KANJI_STANDARD, // 瘋 + 0x760D, KANJI_STANDARD, // 瘍 + 0x7609, KANJI_STANDARD, // 瘉 + 0x761F, KANJI_STANDARD, // 瘟 + 0x7627, KANJI_STANDARD, // 瘧 + 0x7620, KANJI_STANDARD, // 瘠 + 0x7621, KANJI_STANDARD, // 瘡 + 0x7622, KANJI_STANDARD, // 瘢 + 0x7624, KANJI_STANDARD, // 瘀 + 0x7634, KANJI_STANDARD, // 瘎 + 0x7630, KANJI_STANDARD, // 瘰 + 0x763B, KANJI_STANDARD, // 瘻 + 0x7647, KANJI_STANDARD, // 癇 + 0x7648, KANJI_STANDARD, // 癈 + 0x7646, KANJI_STANDARD, // 癆 + 0x765C, KANJI_STANDARD, // 癜 + 0x7658, KANJI_STANDARD, // 癘 + 0x7661, KANJI_STANDARD, // 癡 + 0x7662, KANJI_STANDARD, // 癢 + 0x7668, KANJI_STANDARD, // 癹 + 0x7669, KANJI_STANDARD, // 癩 + 0x766A, KANJI_STANDARD, // 癪 + 0x7667, KANJI_STANDARD, // 癧 + 0x766C, KANJI_STANDARD, // 癬 + 0x7670, KANJI_STANDARD, // 癰 + 0x7672, KANJI_STANDARD, // 癲 + 0x7676, KANJI_STANDARD, // 癶 + 0x7678, KANJI_STANDARD, // 百 + 0x767C, KANJI_STANDARD, // 癌 + 0x7680, KANJI_STANDARD, // 皀 + 0x7683, KANJI_STANDARD, // 皃 + 0x7688, KANJI_STANDARD, // 皈 + 0x768B, KANJI_STANDARD, // 皋 + 0x768E, KANJI_STANDARD, // 皎 + 0x7696, KANJI_STANDARD, // 皖 + 0x7693, KANJI_STANDARD, // 皓 + 0x7699, KANJI_STANDARD, // 皙 + 0x769A, KANJI_STANDARD, // 皚 + 0x76B0, KANJI_STANDARD, // 皰 + 0x76B4, KANJI_STANDARD, // 皮 + 0x76B8, KANJI_STANDARD, // 皾 + 0x76B9, KANJI_STANDARD, // 皹 + 0x76BA, KANJI_STANDARD, // 皺 + 0x76C2, KANJI_STANDARD, // 盂 + 0x76CD, KANJI_STANDARD, // 盍 + 0x76D6, KANJI_STANDARD, // 盖 + 0x76D2, KANJI_STANDARD, // 盒 + 0x76DE, KANJI_STANDARD, // 盞 + 0x76E1, KANJI_STANDARD, // 盡 + 0x76E5, KANJI_STANDARD, // 盥 + 0x76E7, KANJI_STANDARD, // 盧 + 0x76EA, KANJI_STANDARD, // 盪 + 0x862F, KANJI_STANDARD, // 蘯 + 0x76FB, KANJI_STANDARD, // 盻 + 0x7708, KANJI_STANDARD, // 眈 + 0x7707, KANJI_STANDARD, // 眇 + 0x7704, KANJI_STANDARD, // 眄 + 0x7729, KANJI_STANDARD, // 眩 + 0x7724, KANJI_STANDARD, // 眀 + 0x771E, KANJI_STANDARD, // 眞 + 0x7725, KANJI_STANDARD, // 眥 + 0x7726, KANJI_STANDARD, // 眩 + 0x771B, KANJI_STANDARD, // 眛 + 0x7737, KANJI_STANDARD, // 眷 + 0x7738, KANJI_STANDARD, // 眾 + 0x7747, KANJI_STANDARD, // 睇 + 0x775A, KANJI_STANDARD, // 睚 + 0x7768, KANJI_STANDARD, // 睚 + 0x776B, KANJI_STANDARD, // 睫 + 0x775B, KANJI_STANDARD, // 睛 + 0x7765, KANJI_STANDARD, // 睥 + 0x777F, KANJI_STANDARD, // 睿 + 0x777E, KANJI_STANDARD, // 睟 + 0x7779, KANJI_STANDARD, // 睹 + 0x778E, KANJI_STANDARD, // 瞎 + 0x778B, KANJI_STANDARD, // 瞋 + 0x7791, KANJI_STANDARD, // 瞑 + 0x77A0, KANJI_STANDARD, // 瞠 + 0x779E, KANJI_STANDARD, // 瞞 + 0x77B0, KANJI_STANDARD, // 瞰 + 0x77B6, KANJI_STANDARD, // 瞶 + 0x77B9, KANJI_STANDARD, // 瞹 + 0x77BF, KANJI_STANDARD, // 瞿 + 0x77BC, KANJI_STANDARD, // 瞌 + 0x77BD, KANJI_STANDARD, // 瞜 + 0x77BB, KANJI_STANDARD, // 瞻 + 0x77C7, KANJI_STANDARD, // 矇 + 0x77CD, KANJI_STANDARD, // 矍 + 0x77D7, KANJI_STANDARD, // 矗 + 0x77DA, KANJI_STANDARD, // 矚 + 0x77DC, KANJI_STANDARD, // 矜 + 0x77E3, KANJI_STANDARD, // 矣 + 0x77EE, KANJI_STANDARD, // 矮 + 0x77FC, KANJI_STANDARD, // 矌 + 0x780C, KANJI_STANDARD, // 砌 + 0x7812, KANJI_STANDARD, // 砒 + 0x7926, KANJI_STANDARD, // 瀊 + 0x7820, KANJI_STANDARD, // ç   + 0x792A, KANJI_STANDARD, // 瀪 + 0x7845, KANJI_STANDARD, // 硅 + 0x788E, KANJI_STANDARD, // 碎 + 0x7874, KANJI_STANDARD, // 硎 + 0x7886, KANJI_STANDARD, // 碆 + 0x787C, KANJI_STANDARD, // 硌 + 0x789A, KANJI_STANDARD, // 碚 + 0x788C, KANJI_STANDARD, // 碌 + 0x78A3, KANJI_STANDARD, // 碣 + 0x78B5, KANJI_STANDARD, // 碵 + 0x78AA, KANJI_STANDARD, // 碪 + 0x78AF, KANJI_STANDARD, // 碯 + 0x78D1, KANJI_STANDARD, // 磑 + 0x78C6, KANJI_STANDARD, // 磆 + 0x78CB, KANJI_STANDARD, // 磋 + 0x78D4, KANJI_STANDARD, // 磔 + 0x78BE, KANJI_STANDARD, // 碟 + 0x78BC, KANJI_STANDARD, // 碌 + 0x78C5, KANJI_STANDARD, // 磅 + 0x78CA, KANJI_STANDARD, // 磊 + 0x78EC, KANJI_STANDARD, // 磬 + 0x78E7, KANJI_STANDARD, // 磧 + 0x78DA, KANJI_STANDARD, // 磚 + 0x78FD, KANJI_STANDARD, // 磜 + 0x78F4, KANJI_STANDARD, // 磎 + 0x7907, KANJI_STANDARD, // 瀇 + 0x7912, KANJI_STANDARD, // 瀒 + 0x7911, KANJI_STANDARD, // 瀑 + 0x7919, KANJI_STANDARD, // 瀙 + 0x792C, KANJI_STANDARD, // 瀬 + 0x792B, KANJI_STANDARD, // 瀫 + 0x7940, KANJI_STANDARD, // 祀 + 0x7960, KANJI_STANDARD, // 祠 + 0x7957, KANJI_STANDARD, // 祗 + 0x795F, KANJI_STANDARD, // 祟 + 0x795A, KANJI_STANDARD, // 祚 + 0x7955, KANJI_STANDARD, // 祕 + 0x7953, KANJI_STANDARD, // 祓 + 0x797A, KANJI_STANDARD, // 祺 + 0x797F, KANJI_STANDARD, // 祿 + 0x798A, KANJI_STANDARD, // 穊 + 0x799D, KANJI_STANDARD, // 犝 + 0x79A7, KANJI_STANDARD, // 犧 + 0x9F4B, KANJI_STANDARD, // 霋 + 0x79AA, KANJI_STANDARD, // 犪 + 0x79AE, KANJI_STANDARD, // 犮 + 0x79B3, KANJI_STANDARD, // 犳 + 0x79B9, KANJI_STANDARD, // 犹 + 0x79BA, KANJI_STANDARD, // 犺 + 0x79C9, KANJI_STANDARD, // 秉 + 0x79D5, KANJI_STANDARD, // 秕 + 0x79E7, KANJI_STANDARD, // ç§§ + 0x79EC, KANJI_STANDARD, // 秬 + 0x79E1, KANJI_STANDARD, // ç§¡ + 0x79E3, KANJI_STANDARD, // ç§£ + 0x7A08, KANJI_STANDARD, // 皈 + 0x7A0D, KANJI_STANDARD, // 皍 + 0x7A18, KANJI_STANDARD, // 皘 + 0x7A19, KANJI_STANDARD, // 繙 + 0x7A20, KANJI_STANDARD, // çš  + 0x7A1F, KANJI_STANDARD, // 繟 + 0x7980, KANJI_STANDARD, // 穀 + 0x7A31, KANJI_STANDARD, // çš± + 0x7A3B, KANJI_STANDARD, // çš» + 0x7A3E, KANJI_STANDARD, // 皟 + 0x7A37, KANJI_STANDARD, // çš· + 0x7A43, KANJI_STANDARD, // 穃 + 0x7A57, KANJI_STANDARD, // 穗 + 0x7A49, KANJI_STANDARD, // 穉 + 0x7A61, KANJI_STANDARD, // ç©¡ + 0x7A62, KANJI_STANDARD, // ç©¢ + 0x7A69, KANJI_STANDARD, // ç©© + 0x9F9D, KANJI_STANDARD, // 韝 + 0x7A70, KANJI_STANDARD, // ç©° + 0x7A79, KANJI_STANDARD, // 穹 + 0x7A7D, KANJI_STANDARD, // 穜 + 0x7A88, KANJI_STANDARD, // 窈 + 0x7A97, KANJI_STANDARD, // 窗 + 0x7A95, KANJI_STANDARD, // 窕 + 0x7A98, KANJI_STANDARD, // 窘 + 0x7A96, KANJI_STANDARD, // 窖 + 0x7AA9, KANJI_STANDARD, // 窩 + 0x7AC8, KANJI_STANDARD, // 竈 + 0x7AB0, KANJI_STANDARD, // 窰 + 0x7AB6, KANJI_STANDARD, // 窶 + 0x7AC5, KANJI_STANDARD, // 竅 + 0x7AC4, KANJI_STANDARD, // 竄 + 0x7ABF, KANJI_STANDARD, // 窿 + 0x9083, KANJI_STANDARD, // 邃 + 0x7AC7, KANJI_STANDARD, // 竇 + 0x7ACA, KANJI_STANDARD, // 竊 + 0x7ACD, KANJI_STANDARD, // 竍 + 0x7ACF, KANJI_STANDARD, // 竏 + 0x7AD5, KANJI_STANDARD, // 竕 + 0x7AD3, KANJI_STANDARD, // 竓 + 0x7AD9, KANJI_STANDARD, // 站 + 0x7ADA, KANJI_STANDARD, // 竚 + 0x7ADD, KANJI_STANDARD, // 竝 + 0x7AE1, KANJI_STANDARD, // ç«¡ + 0x7AE2, KANJI_STANDARD, // ç«¢ + 0x7AE6, KANJI_STANDARD, // 竊 + 0x7AED, KANJI_STANDARD, // ç«­ + 0x7AF0, KANJI_STANDARD, // ç«° + 0x7B02, KANJI_STANDARD, // 笂 + 0x7B0F, KANJI_STANDARD, // 笏 + 0x7B0A, KANJI_STANDARD, // 笊 + 0x7B06, KANJI_STANDARD, // 笆 + 0x7B33, KANJI_STANDARD, // 笳 + 0x7B18, KANJI_STANDARD, // 笘 + 0x7B19, KANJI_STANDARD, // 笙 + 0x7B1E, KANJI_STANDARD, // 笞 + 0x7B35, KANJI_STANDARD, // 笵 + 0x7B28, KANJI_STANDARD, // 笚 + 0x7B36, KANJI_STANDARD, // 笶 + 0x7B50, KANJI_STANDARD, // 筐 + 0x7B7A, KANJI_STANDARD, // ç­º + 0x7B04, KANJI_STANDARD, // 笄 + 0x7B4D, KANJI_STANDARD, // 筍 + 0x7B0B, KANJI_STANDARD, // 笋 + 0x7B4C, KANJI_STANDARD, // 筌 + 0x7B45, KANJI_STANDARD, // 筅 + 0x7B75, KANJI_STANDARD, // ç­µ + 0x7B65, KANJI_STANDARD, // ç­¥ + 0x7B74, KANJI_STANDARD, // ç­Ž + 0x7B67, KANJI_STANDARD, // ç­§ + 0x7B70, KANJI_STANDARD, // ç­° + 0x7B71, KANJI_STANDARD, // ç­± + 0x7B6C, KANJI_STANDARD, // ç­¬ + 0x7B6E, KANJI_STANDARD, // ç­® + 0x7B9D, KANJI_STANDARD, // 箝 + 0x7B98, KANJI_STANDARD, // 箘 + 0x7B9F, KANJI_STANDARD, // 箟 + 0x7B8D, KANJI_STANDARD, // 箍 + 0x7B9C, KANJI_STANDARD, // 箜 + 0x7B9A, KANJI_STANDARD, // 箚 + 0x7B8B, KANJI_STANDARD, // 箋 + 0x7B92, KANJI_STANDARD, // 箒 + 0x7B8F, KANJI_STANDARD, // 箏 + 0x7B5D, KANJI_STANDARD, // 筝 + 0x7B99, KANJI_STANDARD, // 箙 + 0x7BCB, KANJI_STANDARD, // 篋 + 0x7BC1, KANJI_STANDARD, // 篁 + 0x7BCC, KANJI_STANDARD, // 篌 + 0x7BCF, KANJI_STANDARD, // 篏 + 0x7BB4, KANJI_STANDARD, // 箎 + 0x7BC6, KANJI_STANDARD, // 篆 + 0x7BDD, KANJI_STANDARD, // 篝 + 0x7BE9, KANJI_STANDARD, // 篩 + 0x7C11, KANJI_STANDARD, // 簑 + 0x7C14, KANJI_STANDARD, // 簔 + 0x7BE6, KANJI_STANDARD, // 篊 + 0x7BE5, KANJI_STANDARD, // 篥 + 0x7C60, KANJI_STANDARD, // ç±  + 0x7C00, KANJI_STANDARD, // 簀 + 0x7C07, KANJI_STANDARD, // 簇 + 0x7C13, KANJI_STANDARD, // 簓 + 0x7BF3, KANJI_STANDARD, // 篳 + 0x7BF7, KANJI_STANDARD, // 篷 + 0x7C17, KANJI_STANDARD, // 簗 + 0x7C0D, KANJI_STANDARD, // 簍 + 0x7BF6, KANJI_STANDARD, // 篶 + 0x7C23, KANJI_STANDARD, // ç°£ + 0x7C27, KANJI_STANDARD, // ç°§ + 0x7C2A, KANJI_STANDARD, // ç°ª + 0x7C1F, KANJI_STANDARD, // 簟 + 0x7C37, KANJI_STANDARD, // ç°· + 0x7C2B, KANJI_STANDARD, // ç°« + 0x7C3D, KANJI_STANDARD, // ç°œ + 0x7C4C, KANJI_STANDARD, // 籌 + 0x7C43, KANJI_STANDARD, // 籃 + 0x7C54, KANJI_STANDARD, // 籔 + 0x7C4F, KANJI_STANDARD, // 籏 + 0x7C40, KANJI_STANDARD, // 籀 + 0x7C50, KANJI_STANDARD, // 籐 + 0x7C58, KANJI_STANDARD, // 籘 + 0x7C5F, KANJI_STANDARD, // 籟 + 0x7C64, KANJI_STANDARD, // ç±€ + 0x7C56, KANJI_STANDARD, // 籖 + 0x7C65, KANJI_STANDARD, // ç±¥ + 0x7C6C, KANJI_STANDARD, // 籬 + 0x7C75, KANJI_STANDARD, // ç±µ + 0x7C83, KANJI_STANDARD, // 粃 + 0x7C90, KANJI_STANDARD, // 粐 + 0x7CA4, KANJI_STANDARD, // ç²€ + 0x7CAD, KANJI_STANDARD, // ç²­ + 0x7CA2, KANJI_STANDARD, // ç²¢ + 0x7CAB, KANJI_STANDARD, // 粫 + 0x7CA1, KANJI_STANDARD, // 粡 + 0x7CA8, KANJI_STANDARD, // 粚 + 0x7CB3, KANJI_STANDARD, // ç²³ + 0x7CB2, KANJI_STANDARD, // ç²² + 0x7CB1, KANJI_STANDARD, // ç²± + 0x7CAE, KANJI_STANDARD, // ç²® + 0x7CB9, KANJI_STANDARD, // ç²¹ + 0x7CBD, KANJI_STANDARD, // 粜 + 0x7CC0, KANJI_STANDARD, // 糀 + 0x7CC5, KANJI_STANDARD, // 糅 + 0x7CC2, KANJI_STANDARD, // 糂 + 0x7CD8, KANJI_STANDARD, // 糘 + 0x7CD2, KANJI_STANDARD, // 糒 + 0x7CDC, KANJI_STANDARD, // 糜 + 0x7CE2, KANJI_STANDARD, // ç³¢ + 0x9B3B, KANJI_STANDARD, // 鬻 + 0x7CEF, KANJI_STANDARD, // 糯 + 0x7CF2, KANJI_STANDARD, // ç³² + 0x7CF4, KANJI_STANDARD, // 糎 + 0x7CF6, KANJI_STANDARD, // ç³¶ + 0x7CFA, KANJI_STANDARD, // 糺 + 0x7D06, KANJI_STANDARD, // 箆 + 0x7D02, KANJI_STANDARD, // 箂 + 0x7D1C, KANJI_STANDARD, // 箜 + 0x7D15, KANJI_STANDARD, // 箕 + 0x7D0A, KANJI_STANDARD, // 箊 + 0x7D45, KANJI_STANDARD, // 絅 + 0x7D4B, KANJI_STANDARD, // 絋 + 0x7D2E, KANJI_STANDARD, // 玮 + 0x7D32, KANJI_STANDARD, // 玲 + 0x7D3F, KANJI_STANDARD, // 玿 + 0x7D35, KANJI_STANDARD, // 玵 + 0x7D46, KANJI_STANDARD, // 絆 + 0x7D73, KANJI_STANDARD, // çµ³ + 0x7D56, KANJI_STANDARD, // 絖 + 0x7D4E, KANJI_STANDARD, // 絎 + 0x7D72, KANJI_STANDARD, // çµ² + 0x7D68, KANJI_STANDARD, // 絚 + 0x7D6E, KANJI_STANDARD, // çµ® + 0x7D4F, KANJI_STANDARD, // 絏 + 0x7D63, KANJI_STANDARD, // çµ£ + 0x7D93, KANJI_STANDARD, // 經 + 0x7D89, KANJI_STANDARD, // 綉 + 0x7D5B, KANJI_STANDARD, // 絛 + 0x7D8F, KANJI_STANDARD, // 綏 + 0x7D7D, KANJI_STANDARD, // 絜 + 0x7D9B, KANJI_STANDARD, // 綛 + 0x7DBA, KANJI_STANDARD, // 綺 + 0x7DAE, KANJI_STANDARD, // ç¶® + 0x7DA3, KANJI_STANDARD, // ç¶£ + 0x7DB5, KANJI_STANDARD, // ç¶µ + 0x7DC7, KANJI_STANDARD, // 緇 + 0x7DBD, KANJI_STANDARD, // ç¶œ + 0x7DAB, KANJI_STANDARD, // ç¶« + 0x7E3D, KANJI_STANDARD, // çžœ + 0x7DA2, KANJI_STANDARD, // ç¶¢ + 0x7DAF, KANJI_STANDARD, // 綯 + 0x7DDC, KANJI_STANDARD, // 緜 + 0x7DB8, KANJI_STANDARD, // ç¶ž + 0x7D9F, KANJI_STANDARD, // 綟 + 0x7DB0, KANJI_STANDARD, // ç¶° + 0x7DD8, KANJI_STANDARD, // 緘 + 0x7DDD, KANJI_STANDARD, // 緝 + 0x7DE4, KANJI_STANDARD, // ç·€ + 0x7DDE, KANJI_STANDARD, // 緞 + 0x7DFB, KANJI_STANDARD, // ç·» + 0x7DF2, KANJI_STANDARD, // ç·² + 0x7DE1, KANJI_STANDARD, // ç·¡ + 0x7E05, KANJI_STANDARD, // 羅 + 0x7E0A, KANJI_STANDARD, // 羊 + 0x7E23, KANJI_STANDARD, // 瞣 + 0x7E21, KANJI_STANDARD, // çž¡ + 0x7E12, KANJI_STANDARD, // 羒 + 0x7E31, KANJI_STANDARD, // çž± + 0x7E1F, KANJI_STANDARD, // 羟 + 0x7E09, KANJI_STANDARD, // 羉 + 0x7E0B, KANJI_STANDARD, // 羋 + 0x7E22, KANJI_STANDARD, // 瞢 + 0x7E46, KANJI_STANDARD, // 繆 + 0x7E66, KANJI_STANDARD, // 繊 + 0x7E3B, KANJI_STANDARD, // çž» + 0x7E35, KANJI_STANDARD, // çžµ + 0x7E39, KANJI_STANDARD, // çž¹ + 0x7E43, KANJI_STANDARD, // 繃 + 0x7E37, KANJI_STANDARD, // çž· + 0x7E32, KANJI_STANDARD, // çž² + 0x7E3A, KANJI_STANDARD, // 瞺 + 0x7E67, KANJI_STANDARD, // ç¹§ + 0x7E5D, KANJI_STANDARD, // 繝 + 0x7E56, KANJI_STANDARD, // 繖 + 0x7E5E, KANJI_STANDARD, // 繞 + 0x7E59, KANJI_STANDARD, // 繙 + 0x7E5A, KANJI_STANDARD, // 繚 + 0x7E79, KANJI_STANDARD, // ç¹¹ + 0x7E6A, KANJI_STANDARD, // 繪 + 0x7E69, KANJI_STANDARD, // 繩 + 0x7E7C, KANJI_STANDARD, // 繌 + 0x7E7B, KANJI_STANDARD, // ç¹» + 0x7E83, KANJI_STANDARD, // 纃 + 0x7DD5, KANJI_STANDARD, // 緕 + 0x7E7D, KANJI_STANDARD, // 繜 + 0x8FAE, KANJI_STANDARD, // 蟮 + 0x7E7F, KANJI_STANDARD, // 繿 + 0x7E88, KANJI_STANDARD, // 纈 + 0x7E89, KANJI_STANDARD, // 纉 + 0x7E8C, KANJI_STANDARD, // 續 + 0x7E92, KANJI_STANDARD, // 纒 + 0x7E90, KANJI_STANDARD, // 纐 + 0x7E93, KANJI_STANDARD, // 纓 + 0x7E94, KANJI_STANDARD, // 纔 + 0x7E96, KANJI_STANDARD, // 纖 + 0x7E8E, KANJI_STANDARD, // 纎 + 0x7E9B, KANJI_STANDARD, // 纛 + 0x7E9C, KANJI_STANDARD, // 纜 + 0x7F38, KANJI_STANDARD, // 猞 + 0x7F3A, KANJI_STANDARD, // 猺 + 0x7F45, KANJI_STANDARD, // 眅 + 0x7F4C, KANJI_STANDARD, // 県 + 0x7F4D, KANJI_STANDARD, // 眍 + 0x7F4E, KANJI_STANDARD, // 眎 + 0x7F50, KANJI_STANDARD, // 眐 + 0x7F51, KANJI_STANDARD, // 眑 + 0x7F55, KANJI_STANDARD, // 眕 + 0x7F54, KANJI_STANDARD, // 眔 + 0x7F58, KANJI_STANDARD, // 眘 + 0x7F5F, KANJI_STANDARD, // 真 + 0x7F60, KANJI_STANDARD, // 眠 + 0x7F68, KANJI_STANDARD, // 眚 + 0x7F69, KANJI_STANDARD, // 眩 + 0x7F67, KANJI_STANDARD, // 眧 + 0x7F78, KANJI_STANDARD, // 眞 + 0x7F82, KANJI_STANDARD, // 矂 + 0x7F86, KANJI_STANDARD, // 矆 + 0x7F83, KANJI_STANDARD, // 矃 + 0x7F88, KANJI_STANDARD, // 矈 + 0x7F87, KANJI_STANDARD, // 矇 + 0x7F8C, KANJI_STANDARD, // 矌 + 0x7F94, KANJI_STANDARD, // 矔 + 0x7F9E, KANJI_STANDARD, // 矞 + 0x7F9D, KANJI_STANDARD, // 矝 + 0x7F9A, KANJI_STANDARD, // 矚 + 0x7FA3, KANJI_STANDARD, // 矣 + 0x7FAF, KANJI_STANDARD, // 矯 + 0x7FB2, KANJI_STANDARD, // 矲 + 0x7FB9, KANJI_STANDARD, // 矹 + 0x7FAE, KANJI_STANDARD, // 矮 + 0x7FB6, KANJI_STANDARD, // 矶 + 0x7FB8, KANJI_STANDARD, // 矞 + 0x8B71, KANJI_STANDARD, // è­± + 0x7FC5, KANJI_STANDARD, // 翅 + 0x7FC6, KANJI_STANDARD, // 翆 + 0x7FCA, KANJI_STANDARD, // 翊 + 0x7FD5, KANJI_STANDARD, // 翕 + 0x7FD4, KANJI_STANDARD, // 翔 + 0x7FE1, KANJI_STANDARD, // ç¿¡ + 0x7FE6, KANJI_STANDARD, // 翊 + 0x7FE9, KANJI_STANDARD, // ç¿© + 0x7FF3, KANJI_STANDARD, // 翳 + 0x7FF9, KANJI_STANDARD, // 翹 + 0x98DC, KANJI_STANDARD, // 飜 + 0x8006, KANJI_STANDARD, // 耆 + 0x8004, KANJI_STANDARD, // 耄 + 0x800B, KANJI_STANDARD, // 耋 + 0x8012, KANJI_STANDARD, // 耒 + 0x8018, KANJI_STANDARD, // 耘 + 0x8019, KANJI_STANDARD, // 耙 + 0x801C, KANJI_STANDARD, // 耜 + 0x8021, KANJI_STANDARD, // 耡 + 0x8028, KANJI_STANDARD, // 耚 + 0x803F, KANJI_STANDARD, // 耿 + 0x803B, KANJI_STANDARD, // 耻 + 0x804A, KANJI_STANDARD, // 聊 + 0x8046, KANJI_STANDARD, // 聆 + 0x8052, KANJI_STANDARD, // 聒 + 0x8058, KANJI_STANDARD, // 聘 + 0x805A, KANJI_STANDARD, // 聚 + 0x805F, KANJI_STANDARD, // 聟 + 0x8062, KANJI_STANDARD, // 聢 + 0x8068, KANJI_STANDARD, // 聚 + 0x8073, KANJI_STANDARD, // 聳 + 0x8072, KANJI_STANDARD, // 聲 + 0x8070, KANJI_STANDARD, // 聰 + 0x8076, KANJI_STANDARD, // 聶 + 0x8079, KANJI_STANDARD, // 聹 + 0x807D, KANJI_STANDARD, // 聜 + 0x807F, KANJI_STANDARD, // 聿 + 0x8084, KANJI_STANDARD, // 肄 + 0x8086, KANJI_STANDARD, // 肆 + 0x8085, KANJI_STANDARD, // 肅 + 0x809B, KANJI_STANDARD, // 肛 + 0x8093, KANJI_STANDARD, // 肓 + 0x809A, KANJI_STANDARD, // 肚 + 0x80AD, KANJI_STANDARD, // 肭 + 0x5190, KANJI_STANDARD, // 冐 + 0x80AC, KANJI_STANDARD, // 肬 + 0x80DB, KANJI_STANDARD, // 胛 + 0x80E5, KANJI_STANDARD, // 胥 + 0x80D9, KANJI_STANDARD, // 胙 + 0x80DD, KANJI_STANDARD, // 胝 + 0x80C4, KANJI_STANDARD, // 胄 + 0x80DA, KANJI_STANDARD, // 胚 + 0x80D6, KANJI_STANDARD, // 胖 + 0x8109, KANJI_STANDARD, // 脉 + 0x80EF, KANJI_STANDARD, // 胯 + 0x80F1, KANJI_STANDARD, // 胱 + 0x811B, KANJI_STANDARD, // 脛 + 0x8129, KANJI_STANDARD, // 脩 + 0x8123, KANJI_STANDARD, // 脣 + 0x812F, KANJI_STANDARD, // 脯 + 0x814B, KANJI_STANDARD, // 腋 + 0x968B, KANJI_STANDARD, // 隋 + 0x8146, KANJI_STANDARD, // 腆 + 0x813E, KANJI_STANDARD, // 脟 + 0x8153, KANJI_STANDARD, // 腓 + 0x8151, KANJI_STANDARD, // 腑 + 0x80FC, KANJI_STANDARD, // 背 + 0x8171, KANJI_STANDARD, // 腱 + 0x816E, KANJI_STANDARD, // 腮 + 0x8165, KANJI_STANDARD, // 腥 + 0x8166, KANJI_STANDARD, // è…Š + 0x8174, KANJI_STANDARD, // è…Ž + 0x8183, KANJI_STANDARD, // 膃 + 0x8188, KANJI_STANDARD, // 膈 + 0x818A, KANJI_STANDARD, // 膊 + 0x8180, KANJI_STANDARD, // 膀 + 0x8182, KANJI_STANDARD, // 膂 + 0x81A0, KANJI_STANDARD, // 膠 + 0x8195, KANJI_STANDARD, // 膕 + 0x81A4, KANJI_STANDARD, // 膀 + 0x81A3, KANJI_STANDARD, // 膣 + 0x815F, KANJI_STANDARD, // 腟 + 0x8193, KANJI_STANDARD, // 膓 + 0x81A9, KANJI_STANDARD, // 膩 + 0x81B0, KANJI_STANDARD, // 膰 + 0x81B5, KANJI_STANDARD, // 膵 + 0x81BE, KANJI_STANDARD, // 膟 + 0x81B8, KANJI_STANDARD, // 膞 + 0x81BD, KANJI_STANDARD, // 膜 + 0x81C0, KANJI_STANDARD, // 臀 + 0x81C2, KANJI_STANDARD, // 臂 + 0x81BA, KANJI_STANDARD, // 膺 + 0x81C9, KANJI_STANDARD, // 臉 + 0x81CD, KANJI_STANDARD, // 臍 + 0x81D1, KANJI_STANDARD, // 臑 + 0x81D9, KANJI_STANDARD, // 臙 + 0x81D8, KANJI_STANDARD, // 臘 + 0x81C8, KANJI_STANDARD, // 臈 + 0x81DA, KANJI_STANDARD, // 臚 + 0x81DF, KANJI_STANDARD, // 臟 + 0x81E0, KANJI_STANDARD, // 臠 + 0x81E7, KANJI_STANDARD, // 臧 + 0x81FA, KANJI_STANDARD, // 臺 + 0x81FB, KANJI_STANDARD, // 臻 + 0x81FE, KANJI_STANDARD, // 臟 + 0x8201, KANJI_STANDARD, // 舁 + 0x8202, KANJI_STANDARD, // 舂 + 0x8205, KANJI_STANDARD, // 舅 + 0x8207, KANJI_STANDARD, // 與 + 0x820A, KANJI_STANDARD, // 舊 + 0x820D, KANJI_STANDARD, // 舍 + 0x8210, KANJI_STANDARD, // 舐 + 0x8216, KANJI_STANDARD, // 舖 + 0x8229, KANJI_STANDARD, // 舩 + 0x822B, KANJI_STANDARD, // 舫 + 0x8238, KANJI_STANDARD, // 舞 + 0x8233, KANJI_STANDARD, // 舳 + 0x8240, KANJI_STANDARD, // 艀 + 0x8259, KANJI_STANDARD, // 艙 + 0x8258, KANJI_STANDARD, // 艘 + 0x825D, KANJI_STANDARD, // 艝 + 0x825A, KANJI_STANDARD, // 艚 + 0x825F, KANJI_STANDARD, // 艟 + 0x8264, KANJI_STANDARD, // 艀 + 0x8262, KANJI_STANDARD, // 艢 + 0x8268, KANJI_STANDARD, // 艚 + 0x826A, KANJI_STANDARD, // 艪 + 0x826B, KANJI_STANDARD, // 艫 + 0x822E, KANJI_STANDARD, // 舮 + 0x8271, KANJI_STANDARD, // 艱 + 0x8277, KANJI_STANDARD, // 艷 + 0x8278, KANJI_STANDARD, // 艞 + 0x827E, KANJI_STANDARD, // 艟 + 0x828D, KANJI_STANDARD, // 芍 + 0x8292, KANJI_STANDARD, // 芒 + 0x82AB, KANJI_STANDARD, // 芫 + 0x829F, KANJI_STANDARD, // 芟 + 0x82BB, KANJI_STANDARD, // 芻 + 0x82AC, KANJI_STANDARD, // 芬 + 0x82E1, KANJI_STANDARD, // 苡 + 0x82E3, KANJI_STANDARD, // 苣 + 0x82DF, KANJI_STANDARD, // 苟 + 0x82D2, KANJI_STANDARD, // 苒 + 0x82F4, KANJI_STANDARD, // 苎 + 0x82F3, KANJI_STANDARD, // 苳 + 0x82FA, KANJI_STANDARD, // 苺 + 0x8393, KANJI_STANDARD, // 莓 + 0x8303, KANJI_STANDARD, // 范 + 0x82FB, KANJI_STANDARD, // 苻 + 0x82F9, KANJI_STANDARD, // 苹 + 0x82DE, KANJI_STANDARD, // 苞 + 0x8306, KANJI_STANDARD, // 茆 + 0x82DC, KANJI_STANDARD, // 苜 + 0x8309, KANJI_STANDARD, // 茉 + 0x82D9, KANJI_STANDARD, // 苙 + 0x8335, KANJI_STANDARD, // 茵 + 0x8334, KANJI_STANDARD, // 茎 + 0x8316, KANJI_STANDARD, // 茖 + 0x8332, KANJI_STANDARD, // 茲 + 0x8331, KANJI_STANDARD, // 茱 + 0x8340, KANJI_STANDARD, // 荀 + 0x8339, KANJI_STANDARD, // 茹 + 0x8350, KANJI_STANDARD, // 荐 + 0x8345, KANJI_STANDARD, // 荅 + 0x832F, KANJI_STANDARD, // 茯 + 0x832B, KANJI_STANDARD, // 茫 + 0x8317, KANJI_STANDARD, // 茗 + 0x8318, KANJI_STANDARD, // 茘 + 0x8385, KANJI_STANDARD, // 莅 + 0x839A, KANJI_STANDARD, // 莚 + 0x83AA, KANJI_STANDARD, // 莪 + 0x839F, KANJI_STANDARD, // 莟 + 0x83A2, KANJI_STANDARD, // 莢 + 0x8396, KANJI_STANDARD, // 莖 + 0x8323, KANJI_STANDARD, // 茣 + 0x838E, KANJI_STANDARD, // 莎 + 0x8387, KANJI_STANDARD, // 莇 + 0x838A, KANJI_STANDARD, // 莊 + 0x837C, KANJI_STANDARD, // 荌 + 0x83B5, KANJI_STANDARD, // 莵 + 0x8373, KANJI_STANDARD, // 荳 + 0x8375, KANJI_STANDARD, // 荵 + 0x83A0, KANJI_STANDARD, // 莠 + 0x8389, KANJI_STANDARD, // 莉 + 0x83A8, KANJI_STANDARD, // 莚 + 0x83F4, KANJI_STANDARD, // 菎 + 0x8413, KANJI_STANDARD, // 萓 + 0x83EB, KANJI_STANDARD, // 菫 + 0x83CE, KANJI_STANDARD, // 菎 + 0x83FD, KANJI_STANDARD, // 菜 + 0x8403, KANJI_STANDARD, // 萃 + 0x83D8, KANJI_STANDARD, // 菘 + 0x840B, KANJI_STANDARD, // 萋 + 0x83C1, KANJI_STANDARD, // 菁 + 0x83F7, KANJI_STANDARD, // 菷 + 0x8407, KANJI_STANDARD, // 萇 + 0x83E0, KANJI_STANDARD, // 菠 + 0x83F2, KANJI_STANDARD, // 菲 + 0x840D, KANJI_STANDARD, // 萍 + 0x8422, KANJI_STANDARD, // 萢 + 0x8420, KANJI_STANDARD, // 萠 + 0x83BD, KANJI_STANDARD, // 莜 + 0x8438, KANJI_STANDARD, // 萞 + 0x8506, KANJI_STANDARD, // 蔆 + 0x83FB, KANJI_STANDARD, // 菻 + 0x846D, KANJI_STANDARD, // 葭 + 0x842A, KANJI_STANDARD, // 萪 + 0x843C, KANJI_STANDARD, // 萌 + 0x855A, KANJI_STANDARD, // 蕚 + 0x8484, KANJI_STANDARD, // 蒄 + 0x8477, KANJI_STANDARD, // 葷 + 0x846B, KANJI_STANDARD, // 葫 + 0x84AD, KANJI_STANDARD, // 蒭 + 0x846E, KANJI_STANDARD, // 葮 + 0x8482, KANJI_STANDARD, // 蒂 + 0x8469, KANJI_STANDARD, // 葩 + 0x8446, KANJI_STANDARD, // 葆 + 0x842C, KANJI_STANDARD, // 萬 + 0x846F, KANJI_STANDARD, // 葯 + 0x8479, KANJI_STANDARD, // 葹 + 0x8435, KANJI_STANDARD, // 萵 + 0x84CA, KANJI_STANDARD, // 蓊 + 0x8462, KANJI_STANDARD, // 葢 + 0x84B9, KANJI_STANDARD, // 蒹 + 0x84BF, KANJI_STANDARD, // 蒿 + 0x849F, KANJI_STANDARD, // 蒟 + 0x84D9, KANJI_STANDARD, // 蓙 + 0x84CD, KANJI_STANDARD, // 蓍 + 0x84BB, KANJI_STANDARD, // 蒻 + 0x84DA, KANJI_STANDARD, // 蓚 + 0x84D0, KANJI_STANDARD, // 蓐 + 0x84C1, KANJI_STANDARD, // 蓁 + 0x84C6, KANJI_STANDARD, // 蓆 + 0x84D6, KANJI_STANDARD, // 蓖 + 0x84A1, KANJI_STANDARD, // 蒡 + 0x8521, KANJI_STANDARD, // 蔡 + 0x84FF, KANJI_STANDARD, // 蓿 + 0x84F4, KANJI_STANDARD, // 蓎 + 0x8517, KANJI_STANDARD, // 蔗 + 0x8518, KANJI_STANDARD, // 蔘 + 0x852C, KANJI_STANDARD, // 蔬 + 0x851F, KANJI_STANDARD, // 蔟 + 0x8515, KANJI_STANDARD, // 蔕 + 0x8514, KANJI_STANDARD, // 蔔 + 0x84FC, KANJI_STANDARD, // 蓌 + 0x8540, KANJI_STANDARD, // 蕀 + 0x8563, KANJI_STANDARD, // 蕣 + 0x8558, KANJI_STANDARD, // 蕘 + 0x8548, KANJI_STANDARD, // 蕈 + 0x8541, KANJI_STANDARD, // 蕁 + 0x8602, KANJI_STANDARD, // 蘂 + 0x854B, KANJI_STANDARD, // 蕋 + 0x8555, KANJI_STANDARD, // 蕕 + 0x8580, KANJI_STANDARD, // 薀 + 0x85A4, KANJI_STANDARD, // è–€ + 0x8588, KANJI_STANDARD, // 薈 + 0x8591, KANJI_STANDARD, // 薑 + 0x858A, KANJI_STANDARD, // 薊 + 0x85A8, KANJI_STANDARD, // è–š + 0x856D, KANJI_STANDARD, // 蕭 + 0x8594, KANJI_STANDARD, // 薔 + 0x859B, KANJI_STANDARD, // 薛 + 0x85EA, KANJI_STANDARD, // 藪 + 0x8587, KANJI_STANDARD, // 薇 + 0x859C, KANJI_STANDARD, // 薜 + 0x8577, KANJI_STANDARD, // 蕷 + 0x857E, KANJI_STANDARD, // 蕟 + 0x8590, KANJI_STANDARD, // 薐 + 0x85C9, KANJI_STANDARD, // 藉 + 0x85BA, KANJI_STANDARD, // 薺 + 0x85CF, KANJI_STANDARD, // 藏 + 0x85B9, KANJI_STANDARD, // 薹 + 0x85D0, KANJI_STANDARD, // 藐 + 0x85D5, KANJI_STANDARD, // 藕 + 0x85DD, KANJI_STANDARD, // 藝 + 0x85E5, KANJI_STANDARD, // 藥 + 0x85DC, KANJI_STANDARD, // 藜 + 0x85F9, KANJI_STANDARD, // 藹 + 0x860A, KANJI_STANDARD, // 蘊 + 0x8613, KANJI_STANDARD, // 蘓 + 0x860B, KANJI_STANDARD, // 蘋 + 0x85FE, KANJI_STANDARD, // è—Ÿ + 0x85FA, KANJI_STANDARD, // 藺 + 0x8606, KANJI_STANDARD, // 蘆 + 0x8622, KANJI_STANDARD, // 蘢 + 0x861A, KANJI_STANDARD, // 蘚 + 0x8630, KANJI_STANDARD, // 蘰 + 0x863F, KANJI_STANDARD, // 蘿 + 0x864D, KANJI_STANDARD, // 虍 + 0x4E55, KANJI_STANDARD, // 乕 + 0x8654, KANJI_STANDARD, // 虔 + 0x865F, KANJI_STANDARD, // 號 + 0x8667, KANJI_STANDARD, // 虧 + 0x8671, KANJI_STANDARD, // 虱 + 0x8693, KANJI_STANDARD, // 蚓 + 0x86A3, KANJI_STANDARD, // 蚣 + 0x86A9, KANJI_STANDARD, // 蚩 + 0x86AA, KANJI_STANDARD, // 蚪 + 0x868B, KANJI_STANDARD, // 蚋 + 0x868C, KANJI_STANDARD, // 蚌 + 0x86B6, KANJI_STANDARD, // 蚶 + 0x86AF, KANJI_STANDARD, // 蚯 + 0x86C4, KANJI_STANDARD, // 蛄 + 0x86C6, KANJI_STANDARD, // 蛆 + 0x86B0, KANJI_STANDARD, // 蚰 + 0x86C9, KANJI_STANDARD, // 蛉 + 0x8823, KANJI_STANDARD, // è £ + 0x86AB, KANJI_STANDARD, // 蚫 + 0x86D4, KANJI_STANDARD, // 蛔 + 0x86DE, KANJI_STANDARD, // 蛞 + 0x86E9, KANJI_STANDARD, // 蛩 + 0x86EC, KANJI_STANDARD, // 蛬 + 0x86DF, KANJI_STANDARD, // 蛟 + 0x86DB, KANJI_STANDARD, // 蛛 + 0x86EF, KANJI_STANDARD, // 蛯 + 0x8712, KANJI_STANDARD, // 蜒 + 0x8706, KANJI_STANDARD, // 蜆 + 0x8708, KANJI_STANDARD, // 蜈 + 0x8700, KANJI_STANDARD, // 蜀 + 0x8703, KANJI_STANDARD, // 蜃 + 0x86FB, KANJI_STANDARD, // 蛻 + 0x8711, KANJI_STANDARD, // 蜑 + 0x8709, KANJI_STANDARD, // 蜉 + 0x870D, KANJI_STANDARD, // 蜍 + 0x86F9, KANJI_STANDARD, // 蛹 + 0x870A, KANJI_STANDARD, // 蜊 + 0x8734, KANJI_STANDARD, // 蜎 + 0x873F, KANJI_STANDARD, // 蜿 + 0x8737, KANJI_STANDARD, // 蜷 + 0x873B, KANJI_STANDARD, // 蜻 + 0x8725, KANJI_STANDARD, // 蜥 + 0x8729, KANJI_STANDARD, // 蜩 + 0x871A, KANJI_STANDARD, // 蜚 + 0x8760, KANJI_STANDARD, // 蝠 + 0x875F, KANJI_STANDARD, // 蝟 + 0x8778, KANJI_STANDARD, // 蝞 + 0x874C, KANJI_STANDARD, // 蝌 + 0x874E, KANJI_STANDARD, // 蝎 + 0x8774, KANJI_STANDARD, // 蝎 + 0x8757, KANJI_STANDARD, // 蝗 + 0x8768, KANJI_STANDARD, // 蝚 + 0x876E, KANJI_STANDARD, // 蝮 + 0x8759, KANJI_STANDARD, // 蝙 + 0x8753, KANJI_STANDARD, // 蝓 + 0x8763, KANJI_STANDARD, // 蝣 + 0x876A, KANJI_STANDARD, // 蝪 + 0x8805, KANJI_STANDARD, // 蠅 + 0x87A2, KANJI_STANDARD, // 螢 + 0x879F, KANJI_STANDARD, // 螟 + 0x8782, KANJI_STANDARD, // 螂 + 0x87AF, KANJI_STANDARD, // 螯 + 0x87CB, KANJI_STANDARD, // 蟋 + 0x87BD, KANJI_STANDARD, // 螜 + 0x87C0, KANJI_STANDARD, // 蟀 + 0x87D0, KANJI_STANDARD, // 蟐 + 0x96D6, KANJI_STANDARD, // 雖 + 0x87AB, KANJI_STANDARD, // 螫 + 0x87C4, KANJI_STANDARD, // 蟄 + 0x87B3, KANJI_STANDARD, // 螳 + 0x87C7, KANJI_STANDARD, // 蟇 + 0x87C6, KANJI_STANDARD, // 蟆 + 0x87BB, KANJI_STANDARD, // 螻 + 0x87EF, KANJI_STANDARD, // 蟯 + 0x87F2, KANJI_STANDARD, // 蟲 + 0x87E0, KANJI_STANDARD, // 蟠 + 0x880F, KANJI_STANDARD, // 蠏 + 0x880D, KANJI_STANDARD, // 蠍 + 0x87FE, KANJI_STANDARD, // 蟟 + 0x87F6, KANJI_STANDARD, // 蟶 + 0x87F7, KANJI_STANDARD, // 蟷 + 0x880E, KANJI_STANDARD, // 蠎 + 0x87D2, KANJI_STANDARD, // 蟒 + 0x8811, KANJI_STANDARD, // 蠑 + 0x8816, KANJI_STANDARD, // 蠖 + 0x8815, KANJI_STANDARD, // 蠕 + 0x8822, KANJI_STANDARD, // è ¢ + 0x8821, KANJI_STANDARD, // è ¡ + 0x8831, KANJI_STANDARD, // è ± + 0x8836, KANJI_STANDARD, // è ¶ + 0x8839, KANJI_STANDARD, // è ¹ + 0x8827, KANJI_STANDARD, // è § + 0x883B, KANJI_STANDARD, // è » + 0x8844, KANJI_STANDARD, // 衄 + 0x8842, KANJI_STANDARD, // 衂 + 0x8852, KANJI_STANDARD, // 衒 + 0x8859, KANJI_STANDARD, // 衙 + 0x885E, KANJI_STANDARD, // 衞 + 0x8862, KANJI_STANDARD, // è¡¢ + 0x886B, KANJI_STANDARD, // è¡« + 0x8881, KANJI_STANDARD, // 袁 + 0x887E, KANJI_STANDARD, // 衟 + 0x889E, KANJI_STANDARD, // 袞 + 0x8875, KANJI_STANDARD, // 衵 + 0x887D, KANJI_STANDARD, // 衜 + 0x88B5, KANJI_STANDARD, // 袵 + 0x8872, KANJI_STANDARD, // 衲 + 0x8882, KANJI_STANDARD, // 袂 + 0x8897, KANJI_STANDARD, // 袗 + 0x8892, KANJI_STANDARD, // 袒 + 0x88AE, KANJI_STANDARD, // 袮 + 0x8899, KANJI_STANDARD, // 袙 + 0x88A2, KANJI_STANDARD, // 袢 + 0x888D, KANJI_STANDARD, // 袍 + 0x88A4, KANJI_STANDARD, // 袀 + 0x88B0, KANJI_STANDARD, // 袰 + 0x88BF, KANJI_STANDARD, // 袿 + 0x88B1, KANJI_STANDARD, // 袱 + 0x88C3, KANJI_STANDARD, // 裃 + 0x88C4, KANJI_STANDARD, // 裄 + 0x88D4, KANJI_STANDARD, // 裔 + 0x88D8, KANJI_STANDARD, // 裘 + 0x88D9, KANJI_STANDARD, // 裙 + 0x88DD, KANJI_STANDARD, // 裝 + 0x88F9, KANJI_STANDARD, // 裹 + 0x8902, KANJI_STANDARD, // 耂 + 0x88FC, KANJI_STANDARD, // 裌 + 0x88F4, KANJI_STANDARD, // 裎 + 0x88E8, KANJI_STANDARD, // 裚 + 0x88F2, KANJI_STANDARD, // 裲 + 0x8904, KANJI_STANDARD, // 耄 + 0x890C, KANJI_STANDARD, // 而 + 0x890A, KANJI_STANDARD, // 耊 + 0x8913, KANJI_STANDARD, // 耓 + 0x8943, KANJI_STANDARD, // 襃 + 0x891E, KANJI_STANDARD, // 耞 + 0x8925, KANJI_STANDARD, // 耥 + 0x892A, KANJI_STANDARD, // 耪 + 0x892B, KANJI_STANDARD, // 耫 + 0x8941, KANJI_STANDARD, // 襁 + 0x8944, KANJI_STANDARD, // 襄 + 0x893B, KANJI_STANDARD, // 耻 + 0x8936, KANJI_STANDARD, // 耶 + 0x8938, KANJI_STANDARD, // 耞 + 0x894C, KANJI_STANDARD, // 襌 + 0x891D, KANJI_STANDARD, // 耝 + 0x8960, KANJI_STANDARD, // 襠 + 0x895E, KANJI_STANDARD, // 襞 + 0x8966, KANJI_STANDARD, // 襊 + 0x8964, KANJI_STANDARD, // 襀 + 0x896D, KANJI_STANDARD, // 襭 + 0x896A, KANJI_STANDARD, // 襪 + 0x896F, KANJI_STANDARD, // 襯 + 0x8974, KANJI_STANDARD, // 襎 + 0x8977, KANJI_STANDARD, // 襷 + 0x897E, KANJI_STANDARD, // 襟 + 0x8983, KANJI_STANDARD, // 芃 + 0x8988, KANJI_STANDARD, // 芈 + 0x898A, KANJI_STANDARD, // 芊 + 0x8993, KANJI_STANDARD, // 芓 + 0x8998, KANJI_STANDARD, // 芘 + 0x89A1, KANJI_STANDARD, // 芡 + 0x89A9, KANJI_STANDARD, // 芩 + 0x89A6, KANJI_STANDARD, // 芊 + 0x89AC, KANJI_STANDARD, // 芬 + 0x89AF, KANJI_STANDARD, // 芯 + 0x89B2, KANJI_STANDARD, // 芲 + 0x89BA, KANJI_STANDARD, // 芺 + 0x89BD, KANJI_STANDARD, // 芜 + 0x89BF, KANJI_STANDARD, // 芿 + 0x89C0, KANJI_STANDARD, // 觀 + 0x89DA, KANJI_STANDARD, // 觚 + 0x89DC, KANJI_STANDARD, // 觜 + 0x89DD, KANJI_STANDARD, // 觝 + 0x89E7, KANJI_STANDARD, // è§§ + 0x89F4, KANJI_STANDARD, // è§Ž + 0x89F8, KANJI_STANDARD, // è§ž + 0x8A03, KANJI_STANDARD, // 蚃 + 0x8A16, KANJI_STANDARD, // èš– + 0x8A10, KANJI_STANDARD, // 蚐 + 0x8A0C, KANJI_STANDARD, // 蚌 + 0x8A1B, KANJI_STANDARD, // èš› + 0x8A1D, KANJI_STANDARD, // 蚝 + 0x8A25, KANJI_STANDARD, // 蚥 + 0x8A36, KANJI_STANDARD, // èš¶ + 0x8A41, KANJI_STANDARD, // 詁 + 0x8A5B, KANJI_STANDARD, // 詛 + 0x8A52, KANJI_STANDARD, // 詒 + 0x8A46, KANJI_STANDARD, // 詆 + 0x8A48, KANJI_STANDARD, // 詈 + 0x8A7C, KANJI_STANDARD, // 詌 + 0x8A6D, KANJI_STANDARD, // è©­ + 0x8A6C, KANJI_STANDARD, // 詬 + 0x8A62, KANJI_STANDARD, // è©¢ + 0x8A85, KANJI_STANDARD, // 誅 + 0x8A82, KANJI_STANDARD, // 誂 + 0x8A84, KANJI_STANDARD, // 誄 + 0x8AA8, KANJI_STANDARD, // 誚 + 0x8AA1, KANJI_STANDARD, // 誡 + 0x8A91, KANJI_STANDARD, // 誑 + 0x8AA5, KANJI_STANDARD, // 誥 + 0x8AA6, KANJI_STANDARD, // 誊 + 0x8A9A, KANJI_STANDARD, // 誚 + 0x8AA3, KANJI_STANDARD, // 誣 + 0x8AC4, KANJI_STANDARD, // 諄 + 0x8ACD, KANJI_STANDARD, // 諍 + 0x8AC2, KANJI_STANDARD, // 諂 + 0x8ADA, KANJI_STANDARD, // 諚 + 0x8AEB, KANJI_STANDARD, // è«« + 0x8AF3, KANJI_STANDARD, // 諳 + 0x8AE7, KANJI_STANDARD, // è«§ + 0x8AE4, KANJI_STANDARD, // è«€ + 0x8AF1, KANJI_STANDARD, // 諱 + 0x8B14, KANJI_STANDARD, // 謔 + 0x8AE0, KANJI_STANDARD, // è«  + 0x8AE2, KANJI_STANDARD, // è«¢ + 0x8AF7, KANJI_STANDARD, // è«· + 0x8ADE, KANJI_STANDARD, // 諞 + 0x8ADB, KANJI_STANDARD, // 諛 + 0x8B0C, KANJI_STANDARD, // 謌 + 0x8B07, KANJI_STANDARD, // 謇 + 0x8B1A, KANJI_STANDARD, // 謚 + 0x8AE1, KANJI_STANDARD, // è«¡ + 0x8B16, KANJI_STANDARD, // 謖 + 0x8B10, KANJI_STANDARD, // 謐 + 0x8B17, KANJI_STANDARD, // 謗 + 0x8B20, KANJI_STANDARD, // 謠 + 0x8B33, KANJI_STANDARD, // 謳 + 0x97AB, KANJI_STANDARD, // 鞫 + 0x8B26, KANJI_STANDARD, // 謊 + 0x8B2B, KANJI_STANDARD, // 謫 + 0x8B3E, KANJI_STANDARD, // 謟 + 0x8B28, KANJI_STANDARD, // 謚 + 0x8B41, KANJI_STANDARD, // 譁 + 0x8B4C, KANJI_STANDARD, // 譌 + 0x8B4F, KANJI_STANDARD, // 譏 + 0x8B4E, KANJI_STANDARD, // 譎 + 0x8B49, KANJI_STANDARD, // 證 + 0x8B56, KANJI_STANDARD, // 譖 + 0x8B5B, KANJI_STANDARD, // 譛 + 0x8B5A, KANJI_STANDARD, // 譚 + 0x8B6B, KANJI_STANDARD, // è­« + 0x8B5F, KANJI_STANDARD, // 譟 + 0x8B6C, KANJI_STANDARD, // è­¬ + 0x8B6F, KANJI_STANDARD, // è­¯ + 0x8B74, KANJI_STANDARD, // è­Ž + 0x8B7D, KANJI_STANDARD, // è­œ + 0x8B80, KANJI_STANDARD, // 讀 + 0x8B8C, KANJI_STANDARD, // 讌 + 0x8B8E, KANJI_STANDARD, // 讎 + 0x8B92, KANJI_STANDARD, // 讒 + 0x8B93, KANJI_STANDARD, // 讓 + 0x8B96, KANJI_STANDARD, // 讖 + 0x8B99, KANJI_STANDARD, // 讙 + 0x8B9A, KANJI_STANDARD, // 讚 + 0x8C3A, KANJI_STANDARD, // è°º + 0x8C41, KANJI_STANDARD, // 豁 + 0x8C3F, KANJI_STANDARD, // è°¿ + 0x8C48, KANJI_STANDARD, // 豈 + 0x8C4C, KANJI_STANDARD, // 豌 + 0x8C4E, KANJI_STANDARD, // 豎 + 0x8C50, KANJI_STANDARD, // 豐 + 0x8C55, KANJI_STANDARD, // 豕 + 0x8C62, KANJI_STANDARD, // è±¢ + 0x8C6C, KANJI_STANDARD, // 豬 + 0x8C78, KANJI_STANDARD, // 豞 + 0x8C7A, KANJI_STANDARD, // 豺 + 0x8C82, KANJI_STANDARD, // 貂 + 0x8C89, KANJI_STANDARD, // 貉 + 0x8C85, KANJI_STANDARD, // 貅 + 0x8C8A, KANJI_STANDARD, // 貊 + 0x8C8D, KANJI_STANDARD, // 貍 + 0x8C8E, KANJI_STANDARD, // 貎 + 0x8C94, KANJI_STANDARD, // 貔 + 0x8C7C, KANJI_STANDARD, // 豌 + 0x8C98, KANJI_STANDARD, // 貘 + 0x621D, KANJI_STANDARD, // 戝 + 0x8CAD, KANJI_STANDARD, // è²­ + 0x8CAA, KANJI_STANDARD, // 貪 + 0x8CBD, KANJI_STANDARD, // 貜 + 0x8CB2, KANJI_STANDARD, // è²² + 0x8CB3, KANJI_STANDARD, // è²³ + 0x8CAE, KANJI_STANDARD, // è²® + 0x8CB6, KANJI_STANDARD, // è²¶ + 0x8CC8, KANJI_STANDARD, // 賈 + 0x8CC1, KANJI_STANDARD, // 賁 + 0x8CE4, KANJI_STANDARD, // è³€ + 0x8CE3, KANJI_STANDARD, // è³£ + 0x8CDA, KANJI_STANDARD, // 賚 + 0x8CFD, KANJI_STANDARD, // 賜 + 0x8CFA, KANJI_STANDARD, // 賺 + 0x8CFB, KANJI_STANDARD, // è³» + 0x8D04, KANJI_STANDARD, // 莄 + 0x8D05, KANJI_STANDARD, // 莅 + 0x8D0A, KANJI_STANDARD, // 莊 + 0x8D07, KANJI_STANDARD, // 莇 + 0x8D0F, KANJI_STANDARD, // 莏 + 0x8D0D, KANJI_STANDARD, // 莍 + 0x8D10, KANJI_STANDARD, // 莐 + 0x9F4E, KANJI_STANDARD, // 霎 + 0x8D13, KANJI_STANDARD, // 莓 + 0x8CCD, KANJI_STANDARD, // 賍 + 0x8D14, KANJI_STANDARD, // 莔 + 0x8D16, KANJI_STANDARD, // 莖 + 0x8D67, KANJI_STANDARD, // èµ§ + 0x8D6D, KANJI_STANDARD, // èµ­ + 0x8D71, KANJI_STANDARD, // èµ± + 0x8D73, KANJI_STANDARD, // èµ³ + 0x8D81, KANJI_STANDARD, // 趁 + 0x8D99, KANJI_STANDARD, // 趙 + 0x8DC2, KANJI_STANDARD, // 跂 + 0x8DBE, KANJI_STANDARD, // è¶Ÿ + 0x8DBA, KANJI_STANDARD, // 趺 + 0x8DCF, KANJI_STANDARD, // 跏 + 0x8DDA, KANJI_STANDARD, // 跚 + 0x8DD6, KANJI_STANDARD, // 跖 + 0x8DCC, KANJI_STANDARD, // 跌 + 0x8DDB, KANJI_STANDARD, // 跛 + 0x8DCB, KANJI_STANDARD, // 跋 + 0x8DEA, KANJI_STANDARD, // è·ª + 0x8DEB, KANJI_STANDARD, // è·« + 0x8DDF, KANJI_STANDARD, // 跟 + 0x8DE3, KANJI_STANDARD, // è·£ + 0x8DFC, KANJI_STANDARD, // è·Œ + 0x8E08, KANJI_STANDARD, // 螈 + 0x8E09, KANJI_STANDARD, // 螉 + 0x8DFF, KANJI_STANDARD, // è·¿ + 0x8E1D, KANJI_STANDARD, // 螝 + 0x8E1E, KANJI_STANDARD, // èžž + 0x8E10, KANJI_STANDARD, // 螐 + 0x8E1F, KANJI_STANDARD, // 螟 + 0x8E42, KANJI_STANDARD, // 蹂 + 0x8E35, KANJI_STANDARD, // èžµ + 0x8E30, KANJI_STANDARD, // èž° + 0x8E34, KANJI_STANDARD, // 螎 + 0x8E4A, KANJI_STANDARD, // 蹊 + 0x8E47, KANJI_STANDARD, // 蹇 + 0x8E49, KANJI_STANDARD, // 蹉 + 0x8E4C, KANJI_STANDARD, // 蹌 + 0x8E50, KANJI_STANDARD, // 蹐 + 0x8E48, KANJI_STANDARD, // 蹈 + 0x8E59, KANJI_STANDARD, // 蹙 + 0x8E64, KANJI_STANDARD, // è¹€ + 0x8E60, KANJI_STANDARD, // è¹  + 0x8E2A, KANJI_STANDARD, // 螪 + 0x8E63, KANJI_STANDARD, // è¹£ + 0x8E55, KANJI_STANDARD, // 蹕 + 0x8E76, KANJI_STANDARD, // è¹¶ + 0x8E72, KANJI_STANDARD, // è¹² + 0x8E7C, KANJI_STANDARD, // 蹌 + 0x8E81, KANJI_STANDARD, // 躁 + 0x8E87, KANJI_STANDARD, // 躇 + 0x8E85, KANJI_STANDARD, // 躅 + 0x8E84, KANJI_STANDARD, // 躄 + 0x8E8B, KANJI_STANDARD, // 躋 + 0x8E8A, KANJI_STANDARD, // 躊 + 0x8E93, KANJI_STANDARD, // 躓 + 0x8E91, KANJI_STANDARD, // 躑 + 0x8E94, KANJI_STANDARD, // 躔 + 0x8E99, KANJI_STANDARD, // 躙 + 0x8EAA, KANJI_STANDARD, // 躪 + 0x8EA1, KANJI_STANDARD, // 躡 + 0x8EAC, KANJI_STANDARD, // 躬 + 0x8EB0, KANJI_STANDARD, // 躰 + 0x8EC6, KANJI_STANDARD, // 軆 + 0x8EB1, KANJI_STANDARD, // 躱 + 0x8EBE, KANJI_STANDARD, // 躟 + 0x8EC5, KANJI_STANDARD, // 軅 + 0x8EC8, KANJI_STANDARD, // 軈 + 0x8ECB, KANJI_STANDARD, // 軋 + 0x8EDB, KANJI_STANDARD, // 軛 + 0x8EE3, KANJI_STANDARD, // 軣 + 0x8EFC, KANJI_STANDARD, // 軌 + 0x8EFB, KANJI_STANDARD, // è»» + 0x8EEB, KANJI_STANDARD, // 軫 + 0x8EFE, KANJI_STANDARD, // 軟 + 0x8F0A, KANJI_STANDARD, // 茊 + 0x8F05, KANJI_STANDARD, // 茅 + 0x8F15, KANJI_STANDARD, // 茕 + 0x8F12, KANJI_STANDARD, // 茒 + 0x8F19, KANJI_STANDARD, // 茙 + 0x8F13, KANJI_STANDARD, // 茓 + 0x8F1C, KANJI_STANDARD, // 茜 + 0x8F1F, KANJI_STANDARD, // 茟 + 0x8F1B, KANJI_STANDARD, // 茛 + 0x8F0C, KANJI_STANDARD, // 茌 + 0x8F26, KANJI_STANDARD, // 茊 + 0x8F33, KANJI_STANDARD, // 茳 + 0x8F3B, KANJI_STANDARD, // 茻 + 0x8F39, KANJI_STANDARD, // 茹 + 0x8F45, KANJI_STANDARD, // 蜅 + 0x8F42, KANJI_STANDARD, // 蜂 + 0x8F3E, KANJI_STANDARD, // 茟 + 0x8F4C, KANJI_STANDARD, // 蜌 + 0x8F49, KANJI_STANDARD, // 蜉 + 0x8F46, KANJI_STANDARD, // 蜆 + 0x8F4E, KANJI_STANDARD, // 蜎 + 0x8F57, KANJI_STANDARD, // 蜗 + 0x8F5C, KANJI_STANDARD, // 蜜 + 0x8F62, KANJI_STANDARD, // 蜢 + 0x8F63, KANJI_STANDARD, // 蜣 + 0x8F64, KANJI_STANDARD, // 蜀 + 0x8F9C, KANJI_STANDARD, // 蟜 + 0x8F9F, KANJI_STANDARD, // 蟟 + 0x8FA3, KANJI_STANDARD, // 蟣 + 0x8FAD, KANJI_STANDARD, // 蟭 + 0x8FAF, KANJI_STANDARD, // 蟯 + 0x8FB7, KANJI_STANDARD, // 蟷 + 0x8FDA, KANJI_STANDARD, // 迚 + 0x8FE5, KANJI_STANDARD, // è¿¥ + 0x8FE2, KANJI_STANDARD, // è¿¢ + 0x8FEA, KANJI_STANDARD, // 迪 + 0x8FEF, KANJI_STANDARD, // 迯 + 0x9087, KANJI_STANDARD, // 邇 + 0x8FF4, KANJI_STANDARD, // 迎 + 0x9005, KANJI_STANDARD, // 逅 + 0x8FF9, KANJI_STANDARD, // 迹 + 0x8FFA, KANJI_STANDARD, // 迺 + 0x9011, KANJI_STANDARD, // 逑 + 0x9015, KANJI_STANDARD, // 逕 + 0x9021, KANJI_STANDARD, // 逡 + 0x900D, KANJI_STANDARD, // 逍 + 0x901E, KANJI_STANDARD, // 逞 + 0x9016, KANJI_STANDARD, // 逖 + 0x900B, KANJI_STANDARD, // 逋 + 0x9027, KANJI_STANDARD, // 逧 + 0x9036, KANJI_STANDARD, // 逶 + 0x9035, KANJI_STANDARD, // 逵 + 0x9039, KANJI_STANDARD, // 逹 + 0x8FF8, KANJI_STANDARD, // 连 + 0x904F, KANJI_STANDARD, // 遏 + 0x9050, KANJI_STANDARD, // 遐 + 0x9051, KANJI_STANDARD, // 遑 + 0x9052, KANJI_STANDARD, // 遒 + 0x900E, KANJI_STANDARD, // 逎 + 0x9049, KANJI_STANDARD, // 遉 + 0x903E, KANJI_STANDARD, // 速 + 0x9056, KANJI_STANDARD, // 遖 + 0x9058, KANJI_STANDARD, // 遘 + 0x905E, KANJI_STANDARD, // 遞 + 0x9068, KANJI_STANDARD, // 遚 + 0x906F, KANJI_STANDARD, // 遯 + 0x9076, KANJI_STANDARD, // 遶 + 0x96A8, KANJI_STANDARD, // 隹 + 0x9072, KANJI_STANDARD, // 遲 + 0x9082, KANJI_STANDARD, // 邂 + 0x907D, KANJI_STANDARD, // 遜 + 0x9081, KANJI_STANDARD, // 邁 + 0x9080, KANJI_STANDARD, // 邀 + 0x908A, KANJI_STANDARD, // 邊 + 0x9089, KANJI_STANDARD, // 邉 + 0x908F, KANJI_STANDARD, // 邏 + 0x90A8, KANJI_STANDARD, // 邹 + 0x90AF, KANJI_STANDARD, // 邯 + 0x90B1, KANJI_STANDARD, // 邱 + 0x90B5, KANJI_STANDARD, // 邵 + 0x90E2, KANJI_STANDARD, // 郢 + 0x90E4, KANJI_STANDARD, // 郀 + 0x6248, KANJI_STANDARD, // 扈 + 0x90DB, KANJI_STANDARD, // 郛 + 0x9102, KANJI_STANDARD, // 鄂 + 0x9112, KANJI_STANDARD, // 鄒 + 0x9119, KANJI_STANDARD, // 鄙 + 0x9132, KANJI_STANDARD, // 鄲 + 0x9130, KANJI_STANDARD, // 鄰 + 0x914A, KANJI_STANDARD, // 酊 + 0x9156, KANJI_STANDARD, // 酖 + 0x9158, KANJI_STANDARD, // 酘 + 0x9163, KANJI_STANDARD, // 酣 + 0x9165, KANJI_STANDARD, // 酥 + 0x9169, KANJI_STANDARD, // 酩 + 0x9173, KANJI_STANDARD, // 酳 + 0x9172, KANJI_STANDARD, // 酲 + 0x918B, KANJI_STANDARD, // 醋 + 0x9189, KANJI_STANDARD, // 醉 + 0x9182, KANJI_STANDARD, // 醂 + 0x91A2, KANJI_STANDARD, // 醢 + 0x91AB, KANJI_STANDARD, // 醫 + 0x91AF, KANJI_STANDARD, // 醯 + 0x91AA, KANJI_STANDARD, // 醪 + 0x91B5, KANJI_STANDARD, // 醵 + 0x91B4, KANJI_STANDARD, // 醮 + 0x91BA, KANJI_STANDARD, // 醺 + 0x91C0, KANJI_STANDARD, // 釀 + 0x91C1, KANJI_STANDARD, // 釁 + 0x91C9, KANJI_STANDARD, // 釉 + 0x91CB, KANJI_STANDARD, // 釋 + 0x91D0, KANJI_STANDARD, // 釐 + 0x91D6, KANJI_STANDARD, // 釖 + 0x91DF, KANJI_STANDARD, // 釟 + 0x91E1, KANJI_STANDARD, // 釡 + 0x91DB, KANJI_STANDARD, // 釛 + 0x91FC, KANJI_STANDARD, // 里 + 0x91F5, KANJI_STANDARD, // 釵 + 0x91F6, KANJI_STANDARD, // 釶 + 0x921E, KANJI_STANDARD, // 鈞 + 0x91FF, KANJI_STANDARD, // 釿 + 0x9214, KANJI_STANDARD, // 鈔 + 0x922C, KANJI_STANDARD, // 鈬 + 0x9215, KANJI_STANDARD, // 鈕 + 0x9211, KANJI_STANDARD, // 鈑 + 0x925E, KANJI_STANDARD, // 鉞 + 0x9257, KANJI_STANDARD, // 鉗 + 0x9245, KANJI_STANDARD, // 鉅 + 0x9249, KANJI_STANDARD, // 鉉 + 0x9264, KANJI_STANDARD, // 鉀 + 0x9248, KANJI_STANDARD, // 鉈 + 0x9295, KANJI_STANDARD, // 銕 + 0x923F, KANJI_STANDARD, // 鈿 + 0x924B, KANJI_STANDARD, // 鉋 + 0x9250, KANJI_STANDARD, // 鉐 + 0x929C, KANJI_STANDARD, // 銜 + 0x9296, KANJI_STANDARD, // 銖 + 0x9293, KANJI_STANDARD, // 銓 + 0x929B, KANJI_STANDARD, // 銛 + 0x925A, KANJI_STANDARD, // 鉚 + 0x92CF, KANJI_STANDARD, // 鋏 + 0x92B9, KANJI_STANDARD, // 銹 + 0x92B7, KANJI_STANDARD, // 銷 + 0x92E9, KANJI_STANDARD, // 鋩 + 0x930F, KANJI_STANDARD, // 錏 + 0x92FA, KANJI_STANDARD, // 鋺 + 0x9344, KANJI_STANDARD, // 鍄 + 0x932E, KANJI_STANDARD, // 錮 + 0x9319, KANJI_STANDARD, // 錙 + 0x9322, KANJI_STANDARD, // 錢 + 0x931A, KANJI_STANDARD, // 錚 + 0x9323, KANJI_STANDARD, // 錣 + 0x933A, KANJI_STANDARD, // 錺 + 0x9335, KANJI_STANDARD, // 錵 + 0x933B, KANJI_STANDARD, // 錻 + 0x935C, KANJI_STANDARD, // 鍜 + 0x9360, KANJI_STANDARD, // 鍠 + 0x937C, KANJI_STANDARD, // 鍌 + 0x936E, KANJI_STANDARD, // 鍮 + 0x9356, KANJI_STANDARD, // 鍖 + 0x93B0, KANJI_STANDARD, // 鎰 + 0x93AC, KANJI_STANDARD, // 鎬 + 0x93AD, KANJI_STANDARD, // 鎭 + 0x9394, KANJI_STANDARD, // 鎔 + 0x93B9, KANJI_STANDARD, // 鎹 + 0x93D6, KANJI_STANDARD, // 鏖 + 0x93D7, KANJI_STANDARD, // 鏗 + 0x93E8, KANJI_STANDARD, // 鏚 + 0x93E5, KANJI_STANDARD, // 鏥 + 0x93D8, KANJI_STANDARD, // 鏘 + 0x93C3, KANJI_STANDARD, // 鏃 + 0x93DD, KANJI_STANDARD, // 鏝 + 0x93D0, KANJI_STANDARD, // 鏐 + 0x93C8, KANJI_STANDARD, // 鏈 + 0x93E4, KANJI_STANDARD, // 鏀 + 0x941A, KANJI_STANDARD, // 鐚 + 0x9414, KANJI_STANDARD, // 鐔 + 0x9413, KANJI_STANDARD, // 鐓 + 0x9403, KANJI_STANDARD, // 鐃 + 0x9407, KANJI_STANDARD, // 鐇 + 0x9410, KANJI_STANDARD, // 鐐 + 0x9436, KANJI_STANDARD, // 鐶 + 0x942B, KANJI_STANDARD, // 鐫 + 0x9435, KANJI_STANDARD, // 鐵 + 0x9421, KANJI_STANDARD, // 鐡 + 0x943A, KANJI_STANDARD, // 鐺 + 0x9441, KANJI_STANDARD, // 鑁 + 0x9452, KANJI_STANDARD, // 鑒 + 0x9444, KANJI_STANDARD, // 鑄 + 0x945B, KANJI_STANDARD, // 鑛 + 0x9460, KANJI_STANDARD, // 鑠 + 0x9462, KANJI_STANDARD, // 鑢 + 0x945E, KANJI_STANDARD, // 鑞 + 0x946A, KANJI_STANDARD, // 鑪 + 0x9229, KANJI_STANDARD, // 鈩 + 0x9470, KANJI_STANDARD, // 鑰 + 0x9475, KANJI_STANDARD, // 鑵 + 0x9477, KANJI_STANDARD, // 鑷 + 0x947D, KANJI_STANDARD, // 鑜 + 0x945A, KANJI_STANDARD, // 鑚 + 0x947C, KANJI_STANDARD, // 鑌 + 0x947E, KANJI_STANDARD, // 鑟 + 0x9481, KANJI_STANDARD, // 钁 + 0x947F, KANJI_STANDARD, // 鑿 + 0x9582, KANJI_STANDARD, // 閂 + 0x9587, KANJI_STANDARD, // 閇 + 0x958A, KANJI_STANDARD, // 閊 + 0x9594, KANJI_STANDARD, // 閔 + 0x9596, KANJI_STANDARD, // 閖 + 0x9598, KANJI_STANDARD, // 閘 + 0x9599, KANJI_STANDARD, // 閙 + 0x95A0, KANJI_STANDARD, // 閠 + 0x95A8, KANJI_STANDARD, // 閹 + 0x95A7, KANJI_STANDARD, // 閧 + 0x95AD, KANJI_STANDARD, // 閭 + 0x95BC, KANJI_STANDARD, // é–Œ + 0x95BB, KANJI_STANDARD, // 閻 + 0x95B9, KANJI_STANDARD, // 閹 + 0x95BE, KANJI_STANDARD, // é–Ÿ + 0x95CA, KANJI_STANDARD, // 闊 + 0x6FF6, KANJI_STANDARD, // æ¿¶ + 0x95C3, KANJI_STANDARD, // 闃 + 0x95CD, KANJI_STANDARD, // 闍 + 0x95CC, KANJI_STANDARD, // 闌 + 0x95D5, KANJI_STANDARD, // 闕 + 0x95D4, KANJI_STANDARD, // 闔 + 0x95D6, KANJI_STANDARD, // 闖 + 0x95DC, KANJI_STANDARD, // 關 + 0x95E1, KANJI_STANDARD, // 闡 + 0x95E5, KANJI_STANDARD, // 闥 + 0x95E2, KANJI_STANDARD, // 闢 + 0x9621, KANJI_STANDARD, // 阡 + 0x9628, KANJI_STANDARD, // 阚 + 0x962E, KANJI_STANDARD, // 阮 + 0x962F, KANJI_STANDARD, // 阯 + 0x9642, KANJI_STANDARD, // 陂 + 0x964C, KANJI_STANDARD, // 陌 + 0x964F, KANJI_STANDARD, // 陏 + 0x964B, KANJI_STANDARD, // 陋 + 0x9677, KANJI_STANDARD, // 陷 + 0x965C, KANJI_STANDARD, // 陜 + 0x965E, KANJI_STANDARD, // 陞 + 0x965D, KANJI_STANDARD, // 陝 + 0x965F, KANJI_STANDARD, // 陟 + 0x9666, KANJI_STANDARD, // 险 + 0x9672, KANJI_STANDARD, // 陲 + 0x966C, KANJI_STANDARD, // 陬 + 0x968D, KANJI_STANDARD, // 隍 + 0x9698, KANJI_STANDARD, // 隘 + 0x9695, KANJI_STANDARD, // 隕 + 0x9697, KANJI_STANDARD, // 隗 + 0x96AA, KANJI_STANDARD, // 險 + 0x96A7, KANJI_STANDARD, // 隧 + 0x96B1, KANJI_STANDARD, // 隱 + 0x96B2, KANJI_STANDARD, // 隲 + 0x96B0, KANJI_STANDARD, // 隰 + 0x96B4, KANJI_STANDARD, // 隮 + 0x96B6, KANJI_STANDARD, // 隶 + 0x96B8, KANJI_STANDARD, // 难 + 0x96B9, KANJI_STANDARD, // 隹 + 0x96CE, KANJI_STANDARD, // 雎 + 0x96CB, KANJI_STANDARD, // 雋 + 0x96C9, KANJI_STANDARD, // 雉 + 0x96CD, KANJI_STANDARD, // 雍 + 0x894D, KANJI_STANDARD, // 襍 + 0x96DC, KANJI_STANDARD, // 雜 + 0x970D, KANJI_STANDARD, // 霍 + 0x96D5, KANJI_STANDARD, // 雕 + 0x96F9, KANJI_STANDARD, // 雹 + 0x9704, KANJI_STANDARD, // 霄 + 0x9706, KANJI_STANDARD, // 霆 + 0x9708, KANJI_STANDARD, // 霈 + 0x9713, KANJI_STANDARD, // 霓 + 0x970E, KANJI_STANDARD, // 霎 + 0x9711, KANJI_STANDARD, // 霑 + 0x970F, KANJI_STANDARD, // 霏 + 0x9716, KANJI_STANDARD, // 霖 + 0x9719, KANJI_STANDARD, // 霙 + 0x9724, KANJI_STANDARD, // 需 + 0x972A, KANJI_STANDARD, // 霪 + 0x9730, KANJI_STANDARD, // 霰 + 0x9739, KANJI_STANDARD, // 霹 + 0x973D, KANJI_STANDARD, // 霜 + 0x973E, KANJI_STANDARD, // 霟 + 0x9744, KANJI_STANDARD, // 靄 + 0x9746, KANJI_STANDARD, // 靆 + 0x9748, KANJI_STANDARD, // 靈 + 0x9742, KANJI_STANDARD, // 靂 + 0x9749, KANJI_STANDARD, // 靉 + 0x975C, KANJI_STANDARD, // 靜 + 0x9760, KANJI_STANDARD, // 靠 + 0x9764, KANJI_STANDARD, // 靀 + 0x9766, KANJI_STANDARD, // 靊 + 0x9768, KANJI_STANDARD, // 靚 + 0x52D2, KANJI_STANDARD, // 勒 + 0x976B, KANJI_STANDARD, // 靫 + 0x9771, KANJI_STANDARD, // 靱 + 0x9779, KANJI_STANDARD, // 靹 + 0x9785, KANJI_STANDARD, // 鞅 + 0x977C, KANJI_STANDARD, // 靌 + 0x9781, KANJI_STANDARD, // 鞁 + 0x977A, KANJI_STANDARD, // 靺 + 0x9786, KANJI_STANDARD, // 鞆 + 0x978B, KANJI_STANDARD, // 鞋 + 0x978F, KANJI_STANDARD, // 鞏 + 0x9790, KANJI_STANDARD, // 鞐 + 0x979C, KANJI_STANDARD, // 鞜 + 0x97A8, KANJI_STANDARD, // 鞚 + 0x97A6, KANJI_STANDARD, // 鞊 + 0x97A3, KANJI_STANDARD, // 鞣 + 0x97B3, KANJI_STANDARD, // 鞳 + 0x97B4, KANJI_STANDARD, // 鞮 + 0x97C3, KANJI_STANDARD, // 韃 + 0x97C6, KANJI_STANDARD, // 韆 + 0x97C8, KANJI_STANDARD, // 韈 + 0x97CB, KANJI_STANDARD, // 韋 + 0x97DC, KANJI_STANDARD, // 韜 + 0x97ED, KANJI_STANDARD, // 韭 + 0x9F4F, KANJI_STANDARD, // 霏 + 0x97F2, KANJI_STANDARD, // 韲 + 0x7ADF, KANJI_STANDARD, // 竟 + 0x97F6, KANJI_STANDARD, // 韶 + 0x97F5, KANJI_STANDARD, // 韵 + 0x980F, KANJI_STANDARD, // 頏 + 0x980C, KANJI_STANDARD, // 頌 + 0x9838, KANJI_STANDARD, // é ž + 0x9824, KANJI_STANDARD, // é € + 0x9821, KANJI_STANDARD, // é ¡ + 0x9837, KANJI_STANDARD, // é · + 0x983D, KANJI_STANDARD, // é œ + 0x9846, KANJI_STANDARD, // 顆 + 0x984F, KANJI_STANDARD, // 顏 + 0x984B, KANJI_STANDARD, // 顋 + 0x986B, KANJI_STANDARD, // é¡« + 0x986F, KANJI_STANDARD, // 顯 + 0x9870, KANJI_STANDARD, // é¡° + 0x9871, KANJI_STANDARD, // 顱 + 0x9874, KANJI_STANDARD, // 顎 + 0x9873, KANJI_STANDARD, // 顳 + 0x98AA, KANJI_STANDARD, // 颪 + 0x98AF, KANJI_STANDARD, // 颯 + 0x98B1, KANJI_STANDARD, // 颱 + 0x98B6, KANJI_STANDARD, // 颶 + 0x98C4, KANJI_STANDARD, // 飄 + 0x98C3, KANJI_STANDARD, // 飃 + 0x98C6, KANJI_STANDARD, // 飆 + 0x98E9, KANJI_STANDARD, // 飩 + 0x98EB, KANJI_STANDARD, // 飫 + 0x9903, KANJI_STANDARD, // 逃 + 0x9909, KANJI_STANDARD, // 选 + 0x9912, KANJI_STANDARD, // 递 + 0x9914, KANJI_STANDARD, // 途 + 0x9918, KANJI_STANDARD, // 逘 + 0x9921, KANJI_STANDARD, // 逡 + 0x991D, KANJI_STANDARD, // 逝 + 0x991E, KANJI_STANDARD, // 逞 + 0x9924, KANJI_STANDARD, // 退 + 0x9920, KANJI_STANDARD, // 造 + 0x992C, KANJI_STANDARD, // 逬 + 0x992E, KANJI_STANDARD, // 逮 + 0x993D, KANJI_STANDARD, // 逜 + 0x993E, KANJI_STANDARD, // 速 + 0x9942, KANJI_STANDARD, // 饂 + 0x9949, KANJI_STANDARD, // 饉 + 0x9945, KANJI_STANDARD, // 饅 + 0x9950, KANJI_STANDARD, // 饐 + 0x994B, KANJI_STANDARD, // 饋 + 0x9951, KANJI_STANDARD, // 饑 + 0x9952, KANJI_STANDARD, // 饒 + 0x994C, KANJI_STANDARD, // 饌 + 0x9955, KANJI_STANDARD, // 饕 + 0x9997, KANJI_STANDARD, // 驗 + 0x9998, KANJI_STANDARD, // 銘 + 0x99A5, KANJI_STANDARD, // 銥 + 0x99AD, KANJI_STANDARD, // 銭 + 0x99AE, KANJI_STANDARD, // 銮 + 0x99BC, KANJI_STANDARD, // 銌 + 0x99DF, KANJI_STANDARD, // 駟 + 0x99DB, KANJI_STANDARD, // 駛 + 0x99DD, KANJI_STANDARD, // 駝 + 0x99D8, KANJI_STANDARD, // 駘 + 0x99D1, KANJI_STANDARD, // 駑 + 0x99ED, KANJI_STANDARD, // é§­ + 0x99EE, KANJI_STANDARD, // é§® + 0x99F1, KANJI_STANDARD, // é§± + 0x99F2, KANJI_STANDARD, // é§² + 0x99FB, KANJI_STANDARD, // é§» + 0x99F8, KANJI_STANDARD, // é§ž + 0x9A01, KANJI_STANDARD, // 隁 + 0x9A0F, KANJI_STANDARD, // 随 + 0x9A05, KANJI_STANDARD, // 鹅 + 0x99E2, KANJI_STANDARD, // é§¢ + 0x9A19, KANJI_STANDARD, // 鹙 + 0x9A2B, KANJI_STANDARD, // éš« + 0x9A37, KANJI_STANDARD, // éš· + 0x9A45, KANJI_STANDARD, // 驅 + 0x9A42, KANJI_STANDARD, // 驂 + 0x9A40, KANJI_STANDARD, // 驀 + 0x9A43, KANJI_STANDARD, // 驃 + 0x9A3E, KANJI_STANDARD, // 隟 + 0x9A55, KANJI_STANDARD, // 驕 + 0x9A4D, KANJI_STANDARD, // 驍 + 0x9A5B, KANJI_STANDARD, // 驛 + 0x9A57, KANJI_STANDARD, // 驗 + 0x9A5F, KANJI_STANDARD, // 驟 + 0x9A62, KANJI_STANDARD, // é©¢ + 0x9A65, KANJI_STANDARD, // é©¥ + 0x9A64, KANJI_STANDARD, // é©€ + 0x9A69, KANJI_STANDARD, // é©© + 0x9A6B, KANJI_STANDARD, // é©« + 0x9A6A, KANJI_STANDARD, // 驪 + 0x9AAD, KANJI_STANDARD, // 骭 + 0x9AB0, KANJI_STANDARD, // 骰 + 0x9ABC, KANJI_STANDARD, // 验 + 0x9AC0, KANJI_STANDARD, // 髀 + 0x9ACF, KANJI_STANDARD, // 髏 + 0x9AD1, KANJI_STANDARD, // 髑 + 0x9AD3, KANJI_STANDARD, // 髓 + 0x9AD4, KANJI_STANDARD, // 體 + 0x9ADE, KANJI_STANDARD, // 髞 + 0x9ADF, KANJI_STANDARD, // 髟 + 0x9AE2, KANJI_STANDARD, // é«¢ + 0x9AE3, KANJI_STANDARD, // é«£ + 0x9AE6, KANJI_STANDARD, // 髊 + 0x9AEF, KANJI_STANDARD, // 髯 + 0x9AEB, KANJI_STANDARD, // é«« + 0x9AEE, KANJI_STANDARD, // é«® + 0x9AF4, KANJI_STANDARD, // 髎 + 0x9AF1, KANJI_STANDARD, // 髱 + 0x9AF7, KANJI_STANDARD, // é«· + 0x9AFB, KANJI_STANDARD, // é«» + 0x9B06, KANJI_STANDARD, // 鬆 + 0x9B18, KANJI_STANDARD, // 鬘 + 0x9B1A, KANJI_STANDARD, // 鬚 + 0x9B1F, KANJI_STANDARD, // 鬟 + 0x9B22, KANJI_STANDARD, // 鬢 + 0x9B23, KANJI_STANDARD, // 鬣 + 0x9B25, KANJI_STANDARD, // 鬥 + 0x9B27, KANJI_STANDARD, // 鬧 + 0x9B28, KANJI_STANDARD, // 鬚 + 0x9B29, KANJI_STANDARD, // 鬩 + 0x9B2A, KANJI_STANDARD, // 鬪 + 0x9B2E, KANJI_STANDARD, // 鬮 + 0x9B2F, KANJI_STANDARD, // 鬯 + 0x9B32, KANJI_STANDARD, // 鬲 + 0x9B44, KANJI_STANDARD, // 魄 + 0x9B43, KANJI_STANDARD, // 魃 + 0x9B4F, KANJI_STANDARD, // 魏 + 0x9B4D, KANJI_STANDARD, // 魍 + 0x9B4E, KANJI_STANDARD, // 魎 + 0x9B51, KANJI_STANDARD, // 魑 + 0x9B58, KANJI_STANDARD, // 魘 + 0x9B74, KANJI_STANDARD, // é­Ž + 0x9B93, KANJI_STANDARD, // 鮓 + 0x9B83, KANJI_STANDARD, // 鮃 + 0x9B91, KANJI_STANDARD, // 鮑 + 0x9B96, KANJI_STANDARD, // 鮖 + 0x9B97, KANJI_STANDARD, // 鮗 + 0x9B9F, KANJI_STANDARD, // 鮟 + 0x9BA0, KANJI_STANDARD, // é®  + 0x9BA8, KANJI_STANDARD, // 鮚 + 0x9BB4, KANJI_STANDARD, // 鮎 + 0x9BC0, KANJI_STANDARD, // 鯀 + 0x9BCA, KANJI_STANDARD, // 鯊 + 0x9BB9, KANJI_STANDARD, // 鮹 + 0x9BC6, KANJI_STANDARD, // 鯆 + 0x9BCF, KANJI_STANDARD, // 鯏 + 0x9BD1, KANJI_STANDARD, // 鯑 + 0x9BD2, KANJI_STANDARD, // 鯒 + 0x9BE3, KANJI_STANDARD, // 鯣 + 0x9BE2, KANJI_STANDARD, // 鯢 + 0x9BE4, KANJI_STANDARD, // 鯀 + 0x9BD4, KANJI_STANDARD, // 鯔 + 0x9BE1, KANJI_STANDARD, // 鯡 + 0x9C3A, KANJI_STANDARD, // é°º + 0x9BF2, KANJI_STANDARD, // 鯲 + 0x9BF1, KANJI_STANDARD, // 鯱 + 0x9BF0, KANJI_STANDARD, // 鯰 + 0x9C15, KANJI_STANDARD, // 鰕 + 0x9C14, KANJI_STANDARD, // 鰔 + 0x9C09, KANJI_STANDARD, // 鰉 + 0x9C13, KANJI_STANDARD, // 鰓 + 0x9C0C, KANJI_STANDARD, // 鰌 + 0x9C06, KANJI_STANDARD, // 鰆 + 0x9C08, KANJI_STANDARD, // 鰈 + 0x9C12, KANJI_STANDARD, // 鰒 + 0x9C0A, KANJI_STANDARD, // 鰊 + 0x9C04, KANJI_STANDARD, // 鰄 + 0x9C2E, KANJI_STANDARD, // é°® + 0x9C1B, KANJI_STANDARD, // 鰛 + 0x9C25, KANJI_STANDARD, // é°¥ + 0x9C24, KANJI_STANDARD, // é°€ + 0x9C21, KANJI_STANDARD, // é°¡ + 0x9C30, KANJI_STANDARD, // é°° + 0x9C47, KANJI_STANDARD, // 鱇 + 0x9C32, KANJI_STANDARD, // é°² + 0x9C46, KANJI_STANDARD, // 鱆 + 0x9C3E, KANJI_STANDARD, // é°Ÿ + 0x9C5A, KANJI_STANDARD, // 鱚 + 0x9C60, KANJI_STANDARD, // é±  + 0x9C67, KANJI_STANDARD, // é±§ + 0x9C76, KANJI_STANDARD, // é±¶ + 0x9C78, KANJI_STANDARD, // 鱞 + 0x9CE7, KANJI_STANDARD, // é³§ + 0x9CEC, KANJI_STANDARD, // 鳬 + 0x9CF0, KANJI_STANDARD, // é³° + 0x9D09, KANJI_STANDARD, // 鮉 + 0x9D08, KANJI_STANDARD, // 鎈 + 0x9CEB, KANJI_STANDARD, // 鳫 + 0x9D03, KANJI_STANDARD, // 鎃 + 0x9D06, KANJI_STANDARD, // 鮆 + 0x9D2A, KANJI_STANDARD, // 鎪 + 0x9D26, KANJI_STANDARD, // 鎊 + 0x9DAF, KANJI_STANDARD, // 鶯 + 0x9D23, KANJI_STANDARD, // 鎣 + 0x9D1F, KANJI_STANDARD, // 鮟 + 0x9D44, KANJI_STANDARD, // 鵄 + 0x9D15, KANJI_STANDARD, // 鮕 + 0x9D12, KANJI_STANDARD, // 鮒 + 0x9D41, KANJI_STANDARD, // 鵁 + 0x9D3F, KANJI_STANDARD, // 鎿 + 0x9D3E, KANJI_STANDARD, // 鎟 + 0x9D46, KANJI_STANDARD, // 鵆 + 0x9D48, KANJI_STANDARD, // 鵈 + 0x9D5D, KANJI_STANDARD, // 鵝 + 0x9D5E, KANJI_STANDARD, // 鵞 + 0x9D64, KANJI_STANDARD, // éµ€ + 0x9D51, KANJI_STANDARD, // 鵑 + 0x9D50, KANJI_STANDARD, // 鵐 + 0x9D59, KANJI_STANDARD, // 鵙 + 0x9D72, KANJI_STANDARD, // éµ² + 0x9D89, KANJI_STANDARD, // 鶉 + 0x9D87, KANJI_STANDARD, // 鶇 + 0x9DAB, KANJI_STANDARD, // é¶« + 0x9D6F, KANJI_STANDARD, // 鵯 + 0x9D7A, KANJI_STANDARD, // 鵺 + 0x9D9A, KANJI_STANDARD, // 鶚 + 0x9DA4, KANJI_STANDARD, // é¶€ + 0x9DA9, KANJI_STANDARD, // é¶© + 0x9DB2, KANJI_STANDARD, // é¶² + 0x9DC4, KANJI_STANDARD, // 鷄 + 0x9DC1, KANJI_STANDARD, // 鷁 + 0x9DBB, KANJI_STANDARD, // é¶» + 0x9DB8, KANJI_STANDARD, // é¶ž + 0x9DBA, KANJI_STANDARD, // 鶺 + 0x9DC6, KANJI_STANDARD, // 鷆 + 0x9DCF, KANJI_STANDARD, // 鷏 + 0x9DC2, KANJI_STANDARD, // 鷂 + 0x9DD9, KANJI_STANDARD, // 鷙 + 0x9DD3, KANJI_STANDARD, // 鷓 + 0x9DF8, KANJI_STANDARD, // é·ž + 0x9DE6, KANJI_STANDARD, // é·Š + 0x9DED, KANJI_STANDARD, // é·­ + 0x9DEF, KANJI_STANDARD, // é·¯ + 0x9DFD, KANJI_STANDARD, // é·œ + 0x9E1A, KANJI_STANDARD, // 龚 + 0x9E1B, KANJI_STANDARD, // 龛 + 0x9E1E, KANJI_STANDARD, // 龞 + 0x9E75, KANJI_STANDARD, // é¹µ + 0x9E79, KANJI_STANDARD, // é¹¹ + 0x9E7D, KANJI_STANDARD, // 鹜 + 0x9E81, KANJI_STANDARD, // 麁 + 0x9E88, KANJI_STANDARD, // 麈 + 0x9E8B, KANJI_STANDARD, // 麋 + 0x9E8C, KANJI_STANDARD, // 麌 + 0x9E92, KANJI_STANDARD, // 麒 + 0x9E95, KANJI_STANDARD, // 麕 + 0x9E91, KANJI_STANDARD, // 麑 + 0x9E9D, KANJI_STANDARD, // 麝 + 0x9EA5, KANJI_STANDARD, // 麥 + 0x9EA9, KANJI_STANDARD, // 麩 + 0x9EB8, KANJI_STANDARD, // 麞 + 0x9EAA, KANJI_STANDARD, // 麪 + 0x9EAD, KANJI_STANDARD, // 麭 + 0x9761, KANJI_STANDARD, // 靡 + 0x9ECC, KANJI_STANDARD, // 黌 + 0x9ECE, KANJI_STANDARD, // 黎 + 0x9ECF, KANJI_STANDARD, // 黏 + 0x9ED0, KANJI_STANDARD, // 黐 + 0x9ED4, KANJI_STANDARD, // 黔 + 0x9EDC, KANJI_STANDARD, // 黜 + 0x9EDE, KANJI_STANDARD, // 點 + 0x9EDD, KANJI_STANDARD, // 黝 + 0x9EE0, KANJI_STANDARD, // é»  + 0x9EE5, KANJI_STANDARD, // 黥 + 0x9EE8, KANJI_STANDARD, // 黚 + 0x9EEF, KANJI_STANDARD, // 黯 + 0x9EF4, KANJI_STANDARD, // 黎 + 0x9EF6, KANJI_STANDARD, // é»¶ + 0x9EF7, KANJI_STANDARD, // é»· + 0x9EF9, KANJI_STANDARD, // 黹 + 0x9EFB, KANJI_STANDARD, // é»» + 0x9EFC, KANJI_STANDARD, // 黌 + 0x9EFD, KANJI_STANDARD, // 黜 + 0x9F07, KANJI_STANDARD, // 錇 + 0x9F08, KANJI_STANDARD, // 錈 + 0x76B7, KANJI_STANDARD, // 皷 + 0x9F15, KANJI_STANDARD, // 錕 + 0x9F21, KANJI_STANDARD, // 錡 + 0x9F2C, KANJI_STANDARD, // 錬 + 0x9F3E, KANJI_STANDARD, // 錟 + 0x9F4A, KANJI_STANDARD, // 霊 + 0x9F52, KANJI_STANDARD, // 霒 + 0x9F54, KANJI_STANDARD, // 霔 + 0x9F63, KANJI_STANDARD, // 霣 + 0x9F5F, KANJI_STANDARD, // 霟 + 0x9F60, KANJI_STANDARD, // 霠 + 0x9F61, KANJI_STANDARD, // 霡 + 0x9F66, KANJI_STANDARD, // 霊 + 0x9F67, KANJI_STANDARD, // 霧 + 0x9F6C, KANJI_STANDARD, // 霬 + 0x9F6A, KANJI_STANDARD, // 霪 + 0x9F77, KANJI_STANDARD, // 霷 + 0x9F72, KANJI_STANDARD, // 露 + 0x9F76, KANJI_STANDARD, // 霶 + 0x9F95, KANJI_STANDARD, // 韕 + 0x9F9C, KANJI_STANDARD, // 韜 + 0x9FA0, KANJI_STANDARD, // 韠 + 0x582F, KANJI_STANDARD, // å ¯ + 0x69C7, KANJI_STANDARD, // 槇 + 0x9059, KANJI_STANDARD, // 遙 + 0x7464, KANJI_STANDARD, // ç‘€ + 0x51DC, KANJI_STANDARD, // 凜 + 0x7199, KANJI_STANDARD, // 熙 + 0x4E02, KANJI_RARELY_USED, // 侂 + 0x4E04, KANJI_RARELY_USED, // 侄 + 0x4E05, KANJI_RARELY_USED, // 侅 + 0x4E0C, KANJI_RARELY_USED, // 侌 + 0x4E12, KANJI_RARELY_USED, // 侒 + 0x4E1F, KANJI_RARELY_USED, // 侟 + 0x4E23, KANJI_RARELY_USED, // 䞣 + 0x4E24, KANJI_RARELY_USED, // 䞀 + 0x4E28, KANJI_RARELY_USED, // äžš + 0x4E2B, KANJI_RARELY_USED, // äž« + 0x4E2E, KANJI_RARELY_USED, // äž® + 0x4E2F, KANJI_RARELY_USED, // 䞯 + 0x4E30, KANJI_RARELY_USED, // äž° + 0x4E35, KANJI_RARELY_USED, // äžµ + 0x4E40, KANJI_RARELY_USED, // 乀 + 0x4E41, KANJI_RARELY_USED, // 乁 + 0x4E44, KANJI_RARELY_USED, // 乄 + 0x4E47, KANJI_RARELY_USED, // 乇 + 0x4E51, KANJI_RARELY_USED, // 乑 + 0x4E5A, KANJI_RARELY_USED, // 乚 + 0x4E5C, KANJI_RARELY_USED, // 乜 + 0x4E63, KANJI_RARELY_USED, // ä¹£ + 0x4E68, KANJI_RARELY_USED, // 乚 + 0x4E69, KANJI_RARELY_USED, // 乩 + 0x4E74, KANJI_RARELY_USED, // 乎 + 0x4E75, KANJI_RARELY_USED, // ä¹µ + 0x4E79, KANJI_RARELY_USED, // ä¹¹ + 0x4E7F, KANJI_RARELY_USED, // 乿 + 0x4E8D, KANJI_RARELY_USED, // 亍 + 0x4E96, KANJI_RARELY_USED, // 亖 + 0x4E97, KANJI_RARELY_USED, // 亗 + 0x4E9D, KANJI_RARELY_USED, // 亝 + 0x4EAF, KANJI_RARELY_USED, // 亯 + 0x4EB9, KANJI_RARELY_USED, // 亹 + 0x4EC3, KANJI_RARELY_USED, // 仃 + 0x4ED0, KANJI_RARELY_USED, // 仐 + 0x4EDA, KANJI_RARELY_USED, // 仚 + 0x4EDB, KANJI_RARELY_USED, // 仛 + 0x4EE0, KANJI_RARELY_USED, // ä»  + 0x4EE1, KANJI_RARELY_USED, // 仡 + 0x4EE2, KANJI_RARELY_USED, // 仢 + 0x4EE8, KANJI_RARELY_USED, // 仚 + 0x4EEF, KANJI_RARELY_USED, // 仯 + 0x4EF1, KANJI_RARELY_USED, // ä»± + 0x4EF3, KANJI_RARELY_USED, // 仳 + 0x4EF5, KANJI_RARELY_USED, // 仵 + 0x4EFD, KANJI_RARELY_USED, // 仜 + 0x4EFE, KANJI_RARELY_USED, // 仟 + 0x4EFF, KANJI_RARELY_USED, // 仿 + 0x4F00, KANJI_RARELY_USED, // 䌀 + 0x4F02, KANJI_RARELY_USED, // 䌂 + 0x4F03, KANJI_RARELY_USED, // 䌃 + 0x4F08, KANJI_RARELY_USED, // 䌈 + 0x4F0B, KANJI_RARELY_USED, // 䌋 + 0x4F0C, KANJI_RARELY_USED, // 䌌 + 0x4F12, KANJI_RARELY_USED, // 䌒 + 0x4F15, KANJI_RARELY_USED, // 䌕 + 0x4F16, KANJI_RARELY_USED, // 䌖 + 0x4F17, KANJI_RARELY_USED, // 䌗 + 0x4F19, KANJI_RARELY_USED, // 䌙 + 0x4F2E, KANJI_RARELY_USED, // 䌮 + 0x4F31, KANJI_RARELY_USED, // 䌱 + 0x4F60, KANJI_RARELY_USED, // 䜠 + 0x4F33, KANJI_RARELY_USED, // 䌳 + 0x4F35, KANJI_RARELY_USED, // 䌵 + 0x4F37, KANJI_RARELY_USED, // 䌷 + 0x4F39, KANJI_RARELY_USED, // 䌹 + 0x4F3B, KANJI_RARELY_USED, // 䌻 + 0x4F3E, KANJI_RARELY_USED, // 䌟 + 0x4F40, KANJI_RARELY_USED, // 䜀 + 0x4F42, KANJI_RARELY_USED, // 䜂 + 0x4F48, KANJI_RARELY_USED, // 䜈 + 0x4F49, KANJI_RARELY_USED, // 䜉 + 0x4F4B, KANJI_RARELY_USED, // 䜋 + 0x4F4C, KANJI_RARELY_USED, // 䜌 + 0x4F52, KANJI_RARELY_USED, // 䜒 + 0x4F54, KANJI_RARELY_USED, // 䜔 + 0x4F56, KANJI_RARELY_USED, // 䜖 + 0x4F58, KANJI_RARELY_USED, // 䜘 + 0x4F5F, KANJI_RARELY_USED, // 䜟 + 0x4F63, KANJI_RARELY_USED, // 䜣 + 0x4F6A, KANJI_RARELY_USED, // 䜪 + 0x4F6C, KANJI_RARELY_USED, // 䜬 + 0x4F6E, KANJI_RARELY_USED, // 䜮 + 0x4F71, KANJI_RARELY_USED, // 䜱 + 0x4F77, KANJI_RARELY_USED, // 䜷 + 0x4F78, KANJI_RARELY_USED, // 䜞 + 0x4F79, KANJI_RARELY_USED, // 䜹 + 0x4F7A, KANJI_RARELY_USED, // 䜺 + 0x4F7D, KANJI_RARELY_USED, // 䜜 + 0x4F7E, KANJI_RARELY_USED, // 䜟 + 0x4F81, KANJI_RARELY_USED, // 䟁 + 0x4F82, KANJI_RARELY_USED, // 䟂 + 0x4F84, KANJI_RARELY_USED, // 䟄 + 0x4F85, KANJI_RARELY_USED, // 䟅 + 0x4F89, KANJI_RARELY_USED, // 䟉 + 0x4F8A, KANJI_RARELY_USED, // 䟊 + 0x4F8C, KANJI_RARELY_USED, // 䟌 + 0x4F8E, KANJI_RARELY_USED, // 䟎 + 0x4F90, KANJI_RARELY_USED, // 䟐 + 0x4F92, KANJI_RARELY_USED, // 䟒 + 0x4F93, KANJI_RARELY_USED, // 䟓 + 0x4F94, KANJI_RARELY_USED, // 䟔 + 0x4F97, KANJI_RARELY_USED, // 䟗 + 0x4F99, KANJI_RARELY_USED, // 䟙 + 0x4F9A, KANJI_RARELY_USED, // 䟚 + 0x4F9E, KANJI_RARELY_USED, // 䟞 + 0x4F9F, KANJI_RARELY_USED, // 䟟 + 0x4FB2, KANJI_RARELY_USED, // 䟲 + 0x4FB7, KANJI_RARELY_USED, // 䟷 + 0x4FB9, KANJI_RARELY_USED, // 䟹 + 0x4FBB, KANJI_RARELY_USED, // 䟻 + 0x4FBC, KANJI_RARELY_USED, // 䟌 + 0x4FBD, KANJI_RARELY_USED, // 䟜 + 0x4FBE, KANJI_RARELY_USED, // 䟟 + 0x4FC0, KANJI_RARELY_USED, // 俀 + 0x4FC1, KANJI_RARELY_USED, // 俁 + 0x4FC5, KANJI_RARELY_USED, // 俅 + 0x4FC6, KANJI_RARELY_USED, // 俆 + 0x4FC8, KANJI_RARELY_USED, // 俈 + 0x4FC9, KANJI_RARELY_USED, // 俉 + 0x4FCB, KANJI_RARELY_USED, // 俋 + 0x4FCC, KANJI_RARELY_USED, // 俌 + 0x4FCD, KANJI_RARELY_USED, // 俍 + 0x4FCF, KANJI_RARELY_USED, // 俏 + 0x4FD2, KANJI_RARELY_USED, // 俒 + 0x4FDC, KANJI_RARELY_USED, // 俜 + 0x4FE0, KANJI_RARELY_USED, // ä¿  + 0x4FE2, KANJI_RARELY_USED, // ä¿¢ + 0x4FF0, KANJI_RARELY_USED, // ä¿° + 0x4FF2, KANJI_RARELY_USED, // 俲 + 0x4FFC, KANJI_RARELY_USED, // 俌 + 0x4FFD, KANJI_RARELY_USED, // 俜 + 0x4FFF, KANJI_RARELY_USED, // ä¿¿ + 0x5000, KANJI_RARELY_USED, // 倀 + 0x5001, KANJI_RARELY_USED, // 倁 + 0x5004, KANJI_RARELY_USED, // 倄 + 0x5007, KANJI_RARELY_USED, // 倇 + 0x500A, KANJI_RARELY_USED, // 倊 + 0x500C, KANJI_RARELY_USED, // 倌 + 0x500E, KANJI_RARELY_USED, // 倎 + 0x5010, KANJI_RARELY_USED, // 倐 + 0x5013, KANJI_RARELY_USED, // 倓 + 0x5017, KANJI_RARELY_USED, // 倗 + 0x5018, KANJI_RARELY_USED, // 倘 + 0x501B, KANJI_RARELY_USED, // 倛 + 0x501C, KANJI_RARELY_USED, // 倜 + 0x501D, KANJI_RARELY_USED, // 倝 + 0x501E, KANJI_RARELY_USED, // 倞 + 0x5022, KANJI_RARELY_USED, // 倢 + 0x5027, KANJI_RARELY_USED, // 倧 + 0x502E, KANJI_RARELY_USED, // 倮 + 0x5030, KANJI_RARELY_USED, // 倰 + 0x5032, KANJI_RARELY_USED, // 倲 + 0x5033, KANJI_RARELY_USED, // 倳 + 0x5035, KANJI_RARELY_USED, // 倵 + 0x5040, KANJI_RARELY_USED, // 偀 + 0x5041, KANJI_RARELY_USED, // 偁 + 0x5042, KANJI_RARELY_USED, // 偂 + 0x5045, KANJI_RARELY_USED, // 偅 + 0x5046, KANJI_RARELY_USED, // 偆 + 0x504A, KANJI_RARELY_USED, // 偊 + 0x504C, KANJI_RARELY_USED, // 偌 + 0x504E, KANJI_RARELY_USED, // 偎 + 0x5051, KANJI_RARELY_USED, // 偑 + 0x5052, KANJI_RARELY_USED, // 偒 + 0x5053, KANJI_RARELY_USED, // 偓 + 0x5057, KANJI_RARELY_USED, // 偗 + 0x5059, KANJI_RARELY_USED, // 偙 + 0x505F, KANJI_RARELY_USED, // 偟 + 0x5060, KANJI_RARELY_USED, // 偠 + 0x5062, KANJI_RARELY_USED, // 偢 + 0x5063, KANJI_RARELY_USED, // 偣 + 0x5066, KANJI_RARELY_USED, // 偊 + 0x5067, KANJI_RARELY_USED, // 偧 + 0x506A, KANJI_RARELY_USED, // 偪 + 0x506D, KANJI_RARELY_USED, // 偭 + 0x5070, KANJI_RARELY_USED, // 偰 + 0x5071, KANJI_RARELY_USED, // 偱 + 0x503B, KANJI_RARELY_USED, // 倻 + 0x5081, KANJI_RARELY_USED, // 傁 + 0x5083, KANJI_RARELY_USED, // 傃 + 0x5084, KANJI_RARELY_USED, // 傄 + 0x5086, KANJI_RARELY_USED, // 傆 + 0x508A, KANJI_RARELY_USED, // 傊 + 0x508E, KANJI_RARELY_USED, // 傎 + 0x508F, KANJI_RARELY_USED, // 傏 + 0x5090, KANJI_RARELY_USED, // 傐 + 0x5092, KANJI_RARELY_USED, // 傒 + 0x5093, KANJI_RARELY_USED, // 傓 + 0x5094, KANJI_RARELY_USED, // 傔 + 0x5096, KANJI_RARELY_USED, // 傖 + 0x509B, KANJI_RARELY_USED, // 傛 + 0x509C, KANJI_RARELY_USED, // 傜 + 0x509E, KANJI_RARELY_USED, // 傞 + 0x509F, KANJI_RARELY_USED, // 傟 + 0x50A0, KANJI_RARELY_USED, // 傠 + 0x50A1, KANJI_RARELY_USED, // 傡 + 0x50A2, KANJI_RARELY_USED, // 傢 + 0x50AA, KANJI_RARELY_USED, // 傪 + 0x50AF, KANJI_RARELY_USED, // 傯 + 0x50B0, KANJI_RARELY_USED, // 傰 + 0x50B9, KANJI_RARELY_USED, // 傹 + 0x50BA, KANJI_RARELY_USED, // 傺 + 0x50BD, KANJI_RARELY_USED, // 傜 + 0x50C0, KANJI_RARELY_USED, // 僀 + 0x50C3, KANJI_RARELY_USED, // 僃 + 0x50C4, KANJI_RARELY_USED, // 僄 + 0x50C7, KANJI_RARELY_USED, // 僇 + 0x50CC, KANJI_RARELY_USED, // 僌 + 0x50CE, KANJI_RARELY_USED, // 僎 + 0x50D0, KANJI_RARELY_USED, // 僐 + 0x50D3, KANJI_RARELY_USED, // 僓 + 0x50D4, KANJI_RARELY_USED, // 僔 + 0x50D8, KANJI_RARELY_USED, // 僘 + 0x50DC, KANJI_RARELY_USED, // 僜 + 0x50DD, KANJI_RARELY_USED, // 僝 + 0x50DF, KANJI_RARELY_USED, // 僟 + 0x50E2, KANJI_RARELY_USED, // 僢 + 0x50E4, KANJI_RARELY_USED, // 僀 + 0x50E6, KANJI_RARELY_USED, // 僊 + 0x50E8, KANJI_RARELY_USED, // 僚 + 0x50E9, KANJI_RARELY_USED, // 僩 + 0x50EF, KANJI_RARELY_USED, // 僯 + 0x50F1, KANJI_RARELY_USED, // 僱 + 0x50F6, KANJI_RARELY_USED, // 僶 + 0x50FA, KANJI_RARELY_USED, // 僺 + 0x50FE, KANJI_RARELY_USED, // 僟 + 0x5103, KANJI_RARELY_USED, // 儃 + 0x5106, KANJI_RARELY_USED, // 儆 + 0x5107, KANJI_RARELY_USED, // 儇 + 0x5108, KANJI_RARELY_USED, // 儈 + 0x510B, KANJI_RARELY_USED, // 儋 + 0x510C, KANJI_RARELY_USED, // 儌 + 0x510D, KANJI_RARELY_USED, // 儍 + 0x510E, KANJI_RARELY_USED, // 儎 + 0x50F2, KANJI_RARELY_USED, // 僲 + 0x5110, KANJI_RARELY_USED, // 儐 + 0x5117, KANJI_RARELY_USED, // 儗 + 0x5119, KANJI_RARELY_USED, // 儙 + 0x511B, KANJI_RARELY_USED, // 儛 + 0x511C, KANJI_RARELY_USED, // 儜 + 0x511D, KANJI_RARELY_USED, // 儝 + 0x511E, KANJI_RARELY_USED, // 儞 + 0x5123, KANJI_RARELY_USED, // 儣 + 0x5127, KANJI_RARELY_USED, // 儧 + 0x5128, KANJI_RARELY_USED, // 儚 + 0x512C, KANJI_RARELY_USED, // 儬 + 0x512D, KANJI_RARELY_USED, // 儭 + 0x512F, KANJI_RARELY_USED, // 儯 + 0x5131, KANJI_RARELY_USED, // 儱 + 0x5133, KANJI_RARELY_USED, // 儳 + 0x5134, KANJI_RARELY_USED, // 儎 + 0x5135, KANJI_RARELY_USED, // 儵 + 0x5138, KANJI_RARELY_USED, // 儞 + 0x5139, KANJI_RARELY_USED, // 儹 + 0x5142, KANJI_RARELY_USED, // 兂 + 0x514A, KANJI_RARELY_USED, // 兊 + 0x514F, KANJI_RARELY_USED, // 兏 + 0x5153, KANJI_RARELY_USED, // 兓 + 0x5155, KANJI_RARELY_USED, // 兕 + 0x5157, KANJI_RARELY_USED, // 兗 + 0x5158, KANJI_RARELY_USED, // 兘 + 0x515F, KANJI_RARELY_USED, // 兟 + 0x5164, KANJI_RARELY_USED, // å…€ + 0x5166, KANJI_RARELY_USED, // å…Š + 0x517E, KANJI_RARELY_USED, // å…Ÿ + 0x5183, KANJI_RARELY_USED, // 冃 + 0x5184, KANJI_RARELY_USED, // 冄 + 0x518B, KANJI_RARELY_USED, // 冋 + 0x518E, KANJI_RARELY_USED, // 冎 + 0x5198, KANJI_RARELY_USED, // 冘 + 0x519D, KANJI_RARELY_USED, // 冝 + 0x51A1, KANJI_RARELY_USED, // 冡 + 0x51A3, KANJI_RARELY_USED, // 冣 + 0x51AD, KANJI_RARELY_USED, // 冭 + 0x51B8, KANJI_RARELY_USED, // 冞 + 0x51BA, KANJI_RARELY_USED, // 冺 + 0x51BC, KANJI_RARELY_USED, // 册 + 0x51BE, KANJI_RARELY_USED, // 冟 + 0x51BF, KANJI_RARELY_USED, // 冿 + 0x51C2, KANJI_RARELY_USED, // 凂 + 0x51C8, KANJI_RARELY_USED, // 凈 + 0x51CF, KANJI_RARELY_USED, // 减 + 0x51D1, KANJI_RARELY_USED, // 凑 + 0x51D2, KANJI_RARELY_USED, // 凒 + 0x51D3, KANJI_RARELY_USED, // 凓 + 0x51D5, KANJI_RARELY_USED, // 凕 + 0x51D8, KANJI_RARELY_USED, // 凘 + 0x51DE, KANJI_RARELY_USED, // 凞 + 0x51E2, KANJI_RARELY_USED, // 凢 + 0x51E5, KANJI_RARELY_USED, // 凥 + 0x51EE, KANJI_RARELY_USED, // 凮 + 0x51F2, KANJI_RARELY_USED, // 凲 + 0x51F3, KANJI_RARELY_USED, // 凳 + 0x51F4, KANJI_RARELY_USED, // 凎 + 0x51F7, KANJI_RARELY_USED, // 凷 + 0x5201, KANJI_RARELY_USED, // 刁 + 0x5202, KANJI_RARELY_USED, // 刂 + 0x5205, KANJI_RARELY_USED, // 刅 + 0x5212, KANJI_RARELY_USED, // 划 + 0x5213, KANJI_RARELY_USED, // 刓 + 0x5215, KANJI_RARELY_USED, // 刕 + 0x5216, KANJI_RARELY_USED, // 刖 + 0x5218, KANJI_RARELY_USED, // 刘 + 0x5222, KANJI_RARELY_USED, // 刢 + 0x5228, KANJI_RARELY_USED, // 刚 + 0x5231, KANJI_RARELY_USED, // 刱 + 0x5232, KANJI_RARELY_USED, // 刲 + 0x5235, KANJI_RARELY_USED, // 刵 + 0x523C, KANJI_RARELY_USED, // 刌 + 0x5245, KANJI_RARELY_USED, // 剅 + 0x5249, KANJI_RARELY_USED, // 剉 + 0x5255, KANJI_RARELY_USED, // 剕 + 0x5257, KANJI_RARELY_USED, // 剗 + 0x5258, KANJI_RARELY_USED, // 剘 + 0x525A, KANJI_RARELY_USED, // 剚 + 0x525C, KANJI_RARELY_USED, // 剜 + 0x525F, KANJI_RARELY_USED, // 剟 + 0x5260, KANJI_RARELY_USED, // 剠 + 0x5261, KANJI_RARELY_USED, // 剡 + 0x5266, KANJI_RARELY_USED, // 削 + 0x526E, KANJI_RARELY_USED, // 剮 + 0x5277, KANJI_RARELY_USED, // 剷 + 0x5278, KANJI_RARELY_USED, // 剞 + 0x5279, KANJI_RARELY_USED, // 剹 + 0x5280, KANJI_RARELY_USED, // 劀 + 0x5282, KANJI_RARELY_USED, // 劂 + 0x5285, KANJI_RARELY_USED, // 劅 + 0x528A, KANJI_RARELY_USED, // 劊 + 0x528C, KANJI_RARELY_USED, // 劌 + 0x5293, KANJI_RARELY_USED, // 劓 + 0x5295, KANJI_RARELY_USED, // 劕 + 0x5296, KANJI_RARELY_USED, // 劖 + 0x5297, KANJI_RARELY_USED, // 劗 + 0x5298, KANJI_RARELY_USED, // 劘 + 0x529A, KANJI_RARELY_USED, // 劚 + 0x529C, KANJI_RARELY_USED, // 劜 + 0x52A4, KANJI_RARELY_USED, // 劀 + 0x52A5, KANJI_RARELY_USED, // 劥 + 0x52A6, KANJI_RARELY_USED, // 劊 + 0x52A7, KANJI_RARELY_USED, // 劧 + 0x52AF, KANJI_RARELY_USED, // 劯 + 0x52B0, KANJI_RARELY_USED, // 劰 + 0x52B6, KANJI_RARELY_USED, // 劶 + 0x52B7, KANJI_RARELY_USED, // 劷 + 0x52B8, KANJI_RARELY_USED, // 办 + 0x52BA, KANJI_RARELY_USED, // 劺 + 0x52BB, KANJI_RARELY_USED, // 劻 + 0x52BD, KANJI_RARELY_USED, // 劜 + 0x52C0, KANJI_RARELY_USED, // 勀 + 0x52C4, KANJI_RARELY_USED, // 勄 + 0x52C6, KANJI_RARELY_USED, // 勆 + 0x52C8, KANJI_RARELY_USED, // 勈 + 0x52CC, KANJI_RARELY_USED, // 勌 + 0x52CF, KANJI_RARELY_USED, // 勏 + 0x52D1, KANJI_RARELY_USED, // 勑 + 0x52D4, KANJI_RARELY_USED, // 勔 + 0x52D6, KANJI_RARELY_USED, // 勖 + 0x52DB, KANJI_RARELY_USED, // 勛 + 0x52DC, KANJI_RARELY_USED, // 勜 + 0x52E1, KANJI_RARELY_USED, // 勡 + 0x52E5, KANJI_RARELY_USED, // 勥 + 0x52E8, KANJI_RARELY_USED, // 勚 + 0x52E9, KANJI_RARELY_USED, // 勩 + 0x52EA, KANJI_RARELY_USED, // 勪 + 0x52EC, KANJI_RARELY_USED, // 勬 + 0x52F0, KANJI_RARELY_USED, // 勰 + 0x52F1, KANJI_RARELY_USED, // 勱 + 0x52F4, KANJI_RARELY_USED, // 勎 + 0x52F6, KANJI_RARELY_USED, // 勶 + 0x52F7, KANJI_RARELY_USED, // 勷 + 0x5300, KANJI_RARELY_USED, // 匀 + 0x5303, KANJI_RARELY_USED, // 匃 + 0x530A, KANJI_RARELY_USED, // 匊 + 0x530B, KANJI_RARELY_USED, // 匋 + 0x530C, KANJI_RARELY_USED, // 匌 + 0x5311, KANJI_RARELY_USED, // 匑 + 0x5313, KANJI_RARELY_USED, // 匓 + 0x5318, KANJI_RARELY_USED, // 匘 + 0x531B, KANJI_RARELY_USED, // 匛 + 0x531C, KANJI_RARELY_USED, // 匜 + 0x531E, KANJI_RARELY_USED, // 匞 + 0x531F, KANJI_RARELY_USED, // 匟 + 0x5325, KANJI_RARELY_USED, // 匥 + 0x5327, KANJI_RARELY_USED, // 匧 + 0x5328, KANJI_RARELY_USED, // 匚 + 0x5329, KANJI_RARELY_USED, // 匩 + 0x532B, KANJI_RARELY_USED, // 匫 + 0x532C, KANJI_RARELY_USED, // 匬 + 0x532D, KANJI_RARELY_USED, // 匭 + 0x5330, KANJI_RARELY_USED, // 匰 + 0x5332, KANJI_RARELY_USED, // 匲 + 0x5335, KANJI_RARELY_USED, // 匵 + 0x533C, KANJI_RARELY_USED, // 匌 + 0x533D, KANJI_RARELY_USED, // 匜 + 0x533E, KANJI_RARELY_USED, // 匟 + 0x5342, KANJI_RARELY_USED, // 卂 + 0x534C, KANJI_RARELY_USED, // 卌 + 0x534B, KANJI_RARELY_USED, // 卋 + 0x5359, KANJI_RARELY_USED, // 卙 + 0x535B, KANJI_RARELY_USED, // 卛 + 0x5361, KANJI_RARELY_USED, // 卡 + 0x5363, KANJI_RARELY_USED, // 卣 + 0x5365, KANJI_RARELY_USED, // 卥 + 0x536C, KANJI_RARELY_USED, // 卬 + 0x536D, KANJI_RARELY_USED, // 卭 + 0x5372, KANJI_RARELY_USED, // 卲 + 0x5379, KANJI_RARELY_USED, // 卹 + 0x537E, KANJI_RARELY_USED, // 卟 + 0x5383, KANJI_RARELY_USED, // 厃 + 0x5387, KANJI_RARELY_USED, // 厇 + 0x5388, KANJI_RARELY_USED, // 厈 + 0x538E, KANJI_RARELY_USED, // 厎 + 0x5393, KANJI_RARELY_USED, // 厓 + 0x5394, KANJI_RARELY_USED, // 厔 + 0x5399, KANJI_RARELY_USED, // 厙 + 0x539D, KANJI_RARELY_USED, // 厝 + 0x53A1, KANJI_RARELY_USED, // 厡 + 0x53A4, KANJI_RARELY_USED, // 厀 + 0x53AA, KANJI_RARELY_USED, // 厪 + 0x53AB, KANJI_RARELY_USED, // 厫 + 0x53AF, KANJI_RARELY_USED, // 厯 + 0x53B2, KANJI_RARELY_USED, // 厲 + 0x53B4, KANJI_RARELY_USED, // 厎 + 0x53B5, KANJI_RARELY_USED, // 厵 + 0x53B7, KANJI_RARELY_USED, // 厷 + 0x53B8, KANJI_RARELY_USED, // 厞 + 0x53BA, KANJI_RARELY_USED, // 厺 + 0x53BD, KANJI_RARELY_USED, // 厜 + 0x53C0, KANJI_RARELY_USED, // 叀 + 0x53C5, KANJI_RARELY_USED, // 叅 + 0x53CF, KANJI_RARELY_USED, // 叏 + 0x53D2, KANJI_RARELY_USED, // 叒 + 0x53D3, KANJI_RARELY_USED, // 叓 + 0x53D5, KANJI_RARELY_USED, // 叕 + 0x53DA, KANJI_RARELY_USED, // 叚 + 0x53DD, KANJI_RARELY_USED, // 叝 + 0x53DE, KANJI_RARELY_USED, // 叞 + 0x53E0, KANJI_RARELY_USED, // 叠 + 0x53E6, KANJI_RARELY_USED, // 及 + 0x53E7, KANJI_RARELY_USED, // 叧 + 0x53F5, KANJI_RARELY_USED, // 叵 + 0x5402, KANJI_RARELY_USED, // 吂 + 0x5413, KANJI_RARELY_USED, // 吓 + 0x541A, KANJI_RARELY_USED, // 吚 + 0x5421, KANJI_RARELY_USED, // 吡 + 0x5427, KANJI_RARELY_USED, // 吧 + 0x5428, KANJI_RARELY_USED, // 吚 + 0x542A, KANJI_RARELY_USED, // 吪 + 0x542F, KANJI_RARELY_USED, // 启 + 0x5431, KANJI_RARELY_USED, // 吱 + 0x5434, KANJI_RARELY_USED, // 后 + 0x5435, KANJI_RARELY_USED, // 吵 + 0x5443, KANJI_RARELY_USED, // 呃 + 0x5444, KANJI_RARELY_USED, // 呄 + 0x5447, KANJI_RARELY_USED, // 呇 + 0x544D, KANJI_RARELY_USED, // 呍 + 0x544F, KANJI_RARELY_USED, // 呏 + 0x545E, KANJI_RARELY_USED, // 呞 + 0x5462, KANJI_RARELY_USED, // 呢 + 0x5464, KANJI_RARELY_USED, // å‘€ + 0x5466, KANJI_RARELY_USED, // 告 + 0x5467, KANJI_RARELY_USED, // 呧 + 0x5469, KANJI_RARELY_USED, // 呩 + 0x546B, KANJI_RARELY_USED, // 呫 + 0x546D, KANJI_RARELY_USED, // 呭 + 0x546E, KANJI_RARELY_USED, // 呮 + 0x5474, KANJI_RARELY_USED, // 呎 + 0x547F, KANJI_RARELY_USED, // 呿 + 0x5481, KANJI_RARELY_USED, // 咁 + 0x5483, KANJI_RARELY_USED, // 咃 + 0x5485, KANJI_RARELY_USED, // 咅 + 0x5488, KANJI_RARELY_USED, // 咈 + 0x5489, KANJI_RARELY_USED, // 咉 + 0x548D, KANJI_RARELY_USED, // 咍 + 0x5491, KANJI_RARELY_USED, // 咑 + 0x5495, KANJI_RARELY_USED, // 咕 + 0x5496, KANJI_RARELY_USED, // 咖 + 0x549C, KANJI_RARELY_USED, // 咜 + 0x549F, KANJI_RARELY_USED, // 咟 + 0x54A1, KANJI_RARELY_USED, // 咡 + 0x54A6, KANJI_RARELY_USED, // å’Š + 0x54A7, KANJI_RARELY_USED, // 咧 + 0x54A9, KANJI_RARELY_USED, // 咩 + 0x54AA, KANJI_RARELY_USED, // 咪 + 0x54AD, KANJI_RARELY_USED, // 咭 + 0x54AE, KANJI_RARELY_USED, // 咮 + 0x54B1, KANJI_RARELY_USED, // 咱 + 0x54B7, KANJI_RARELY_USED, // 咷 + 0x54B9, KANJI_RARELY_USED, // 咹 + 0x54BA, KANJI_RARELY_USED, // 咺 + 0x54BB, KANJI_RARELY_USED, // 咻 + 0x54BF, KANJI_RARELY_USED, // 咿 + 0x54C6, KANJI_RARELY_USED, // 哆 + 0x54CA, KANJI_RARELY_USED, // 哊 + 0x54CD, KANJI_RARELY_USED, // 响 + 0x54CE, KANJI_RARELY_USED, // 哎 + 0x54E0, KANJI_RARELY_USED, // 哠 + 0x54EA, KANJI_RARELY_USED, // 哪 + 0x54EC, KANJI_RARELY_USED, // 哬 + 0x54EF, KANJI_RARELY_USED, // 哯 + 0x54F6, KANJI_RARELY_USED, // 哶 + 0x54FC, KANJI_RARELY_USED, // 哌 + 0x54FE, KANJI_RARELY_USED, // 哟 + 0x54FF, KANJI_RARELY_USED, // 哿 + 0x5500, KANJI_RARELY_USED, // 唀 + 0x5501, KANJI_RARELY_USED, // 唁 + 0x5505, KANJI_RARELY_USED, // 唅 + 0x5508, KANJI_RARELY_USED, // 唈 + 0x5509, KANJI_RARELY_USED, // 唉 + 0x550C, KANJI_RARELY_USED, // 唌 + 0x550D, KANJI_RARELY_USED, // 唍 + 0x550E, KANJI_RARELY_USED, // 唎 + 0x5515, KANJI_RARELY_USED, // 唕 + 0x552A, KANJI_RARELY_USED, // 唪 + 0x552B, KANJI_RARELY_USED, // 唫 + 0x5532, KANJI_RARELY_USED, // 唲 + 0x5535, KANJI_RARELY_USED, // 唵 + 0x5536, KANJI_RARELY_USED, // 唶 + 0x553B, KANJI_RARELY_USED, // 唻 + 0x553C, KANJI_RARELY_USED, // 唌 + 0x553D, KANJI_RARELY_USED, // 唜 + 0x5541, KANJI_RARELY_USED, // 啁 + 0x5547, KANJI_RARELY_USED, // 啇 + 0x5549, KANJI_RARELY_USED, // 啉 + 0x554A, KANJI_RARELY_USED, // 啊 + 0x554D, KANJI_RARELY_USED, // 啍 + 0x5550, KANJI_RARELY_USED, // 啐 + 0x5551, KANJI_RARELY_USED, // 啑 + 0x5558, KANJI_RARELY_USED, // 啘 + 0x555A, KANJI_RARELY_USED, // 啚 + 0x555B, KANJI_RARELY_USED, // 啛 + 0x555E, KANJI_RARELY_USED, // 啞 + 0x5560, KANJI_RARELY_USED, // 啠 + 0x5561, KANJI_RARELY_USED, // 啡 + 0x5564, KANJI_RARELY_USED, // å•€ + 0x5566, KANJI_RARELY_USED, // 啊 + 0x557F, KANJI_RARELY_USED, // 啿 + 0x5581, KANJI_RARELY_USED, // 喁 + 0x5582, KANJI_RARELY_USED, // 喂 + 0x5586, KANJI_RARELY_USED, // 喆 + 0x5588, KANJI_RARELY_USED, // 喈 + 0x558E, KANJI_RARELY_USED, // 喎 + 0x558F, KANJI_RARELY_USED, // 喏 + 0x5591, KANJI_RARELY_USED, // 喑 + 0x5592, KANJI_RARELY_USED, // 喒 + 0x5593, KANJI_RARELY_USED, // 喓 + 0x5594, KANJI_RARELY_USED, // 喔 + 0x5597, KANJI_RARELY_USED, // 喗 + 0x55A3, KANJI_RARELY_USED, // 喣 + 0x55A4, KANJI_RARELY_USED, // å–€ + 0x55AD, KANJI_RARELY_USED, // 喭 + 0x55B2, KANJI_RARELY_USED, // 喲 + 0x55BF, KANJI_RARELY_USED, // 喿 + 0x55C1, KANJI_RARELY_USED, // 嗁 + 0x55C3, KANJI_RARELY_USED, // 嗃 + 0x55C6, KANJI_RARELY_USED, // 嗆 + 0x55C9, KANJI_RARELY_USED, // 嗉 + 0x55CB, KANJI_RARELY_USED, // 嗋 + 0x55CC, KANJI_RARELY_USED, // 嗌 + 0x55CE, KANJI_RARELY_USED, // 嗎 + 0x55D1, KANJI_RARELY_USED, // 嗑 + 0x55D2, KANJI_RARELY_USED, // 嗒 + 0x55D3, KANJI_RARELY_USED, // 嗓 + 0x55D7, KANJI_RARELY_USED, // 嗗 + 0x55D8, KANJI_RARELY_USED, // 嗘 + 0x55DB, KANJI_RARELY_USED, // 嗛 + 0x55DE, KANJI_RARELY_USED, // 嗞 + 0x55E2, KANJI_RARELY_USED, // 嗢 + 0x55E9, KANJI_RARELY_USED, // 嗩 + 0x55F6, KANJI_RARELY_USED, // 嗶 + 0x55FF, KANJI_RARELY_USED, // 嗿 + 0x5605, KANJI_RARELY_USED, // 嘅 + 0x5608, KANJI_RARELY_USED, // 嘈 + 0x560A, KANJI_RARELY_USED, // 嘊 + 0x560D, KANJI_RARELY_USED, // 嘍 + 0x560E, KANJI_RARELY_USED, // 嘎 + 0x560F, KANJI_RARELY_USED, // 嘏 + 0x5610, KANJI_RARELY_USED, // 嘐 + 0x5611, KANJI_RARELY_USED, // 嘑 + 0x5612, KANJI_RARELY_USED, // 嘒 + 0x5619, KANJI_RARELY_USED, // 嘙 + 0x562C, KANJI_RARELY_USED, // 嘬 + 0x5630, KANJI_RARELY_USED, // 嘰 + 0x5633, KANJI_RARELY_USED, // 嘳 + 0x5635, KANJI_RARELY_USED, // 嘵 + 0x5637, KANJI_RARELY_USED, // 嘷 + 0x5639, KANJI_RARELY_USED, // 嘹 + 0x563B, KANJI_RARELY_USED, // 嘻 + 0x563C, KANJI_RARELY_USED, // 嘌 + 0x563D, KANJI_RARELY_USED, // 嘜 + 0x563F, KANJI_RARELY_USED, // 嘿 + 0x5640, KANJI_RARELY_USED, // 噀 + 0x5641, KANJI_RARELY_USED, // 噁 + 0x5643, KANJI_RARELY_USED, // 噃 + 0x5644, KANJI_RARELY_USED, // 噄 + 0x5646, KANJI_RARELY_USED, // 噆 + 0x5649, KANJI_RARELY_USED, // 噉 + 0x564B, KANJI_RARELY_USED, // 噋 + 0x564D, KANJI_RARELY_USED, // 噍 + 0x564F, KANJI_RARELY_USED, // 噏 + 0x5654, KANJI_RARELY_USED, // 噔 + 0x565E, KANJI_RARELY_USED, // 噞 + 0x5660, KANJI_RARELY_USED, // 噠 + 0x5661, KANJI_RARELY_USED, // 噡 + 0x5662, KANJI_RARELY_USED, // 噢 + 0x5663, KANJI_RARELY_USED, // 噣 + 0x5666, KANJI_RARELY_USED, // 噊 + 0x5669, KANJI_RARELY_USED, // 噩 + 0x566D, KANJI_RARELY_USED, // 噭 + 0x566F, KANJI_RARELY_USED, // 噯 + 0x5671, KANJI_RARELY_USED, // 噱 + 0x5672, KANJI_RARELY_USED, // 噲 + 0x5675, KANJI_RARELY_USED, // 噵 + 0x5684, KANJI_RARELY_USED, // 嚄 + 0x5685, KANJI_RARELY_USED, // 嚅 + 0x5688, KANJI_RARELY_USED, // 嚈 + 0x568B, KANJI_RARELY_USED, // 嚋 + 0x568C, KANJI_RARELY_USED, // 嚌 + 0x5695, KANJI_RARELY_USED, // 嚕 + 0x5699, KANJI_RARELY_USED, // 嚙 + 0x569A, KANJI_RARELY_USED, // 嚚 + 0x569D, KANJI_RARELY_USED, // 嚝 + 0x569E, KANJI_RARELY_USED, // 嚞 + 0x569F, KANJI_RARELY_USED, // 嚟 + 0x56A6, KANJI_RARELY_USED, // 嚊 + 0x56A7, KANJI_RARELY_USED, // 嚧 + 0x56A8, KANJI_RARELY_USED, // åšš + 0x56A9, KANJI_RARELY_USED, // 嚩 + 0x56AB, KANJI_RARELY_USED, // 嚫 + 0x56AC, KANJI_RARELY_USED, // 嚬 + 0x56AD, KANJI_RARELY_USED, // 嚭 + 0x56B1, KANJI_RARELY_USED, // 嚱 + 0x56B3, KANJI_RARELY_USED, // 嚳 + 0x56B7, KANJI_RARELY_USED, // 嚷 + 0x56BE, KANJI_RARELY_USED, // 嚟 + 0x56C5, KANJI_RARELY_USED, // 囅 + 0x56C9, KANJI_RARELY_USED, // 囉 + 0x56CA, KANJI_RARELY_USED, // 囊 + 0x56CB, KANJI_RARELY_USED, // 囋 + 0x56CF, KANJI_RARELY_USED, // 囏 + 0x56D0, KANJI_RARELY_USED, // 囐 + 0x56CC, KANJI_RARELY_USED, // 囌 + 0x56CD, KANJI_RARELY_USED, // 囍 + 0x56D9, KANJI_RARELY_USED, // 囙 + 0x56DC, KANJI_RARELY_USED, // 囜 + 0x56DD, KANJI_RARELY_USED, // 囝 + 0x56DF, KANJI_RARELY_USED, // 囟 + 0x56E1, KANJI_RARELY_USED, // 囡 + 0x56E4, KANJI_RARELY_USED, // 囀 + 0x56E5, KANJI_RARELY_USED, // 囥 + 0x56E6, KANJI_RARELY_USED, // 囊 + 0x56E7, KANJI_RARELY_USED, // 囧 + 0x56E8, KANJI_RARELY_USED, // 囚 + 0x56F1, KANJI_RARELY_USED, // 囱 + 0x56EB, KANJI_RARELY_USED, // 囫 + 0x56ED, KANJI_RARELY_USED, // 园 + 0x56F6, KANJI_RARELY_USED, // 囶 + 0x56F7, KANJI_RARELY_USED, // 囷 + 0x5701, KANJI_RARELY_USED, // 圁 + 0x5702, KANJI_RARELY_USED, // 圂 + 0x5707, KANJI_RARELY_USED, // 圇 + 0x570A, KANJI_RARELY_USED, // 圊 + 0x570C, KANJI_RARELY_USED, // 圌 + 0x5711, KANJI_RARELY_USED, // 圑 + 0x5715, KANJI_RARELY_USED, // 圕 + 0x571A, KANJI_RARELY_USED, // 圚 + 0x571B, KANJI_RARELY_USED, // 圛 + 0x571D, KANJI_RARELY_USED, // 圝 + 0x5720, KANJI_RARELY_USED, // 圠 + 0x5722, KANJI_RARELY_USED, // 圢 + 0x5723, KANJI_RARELY_USED, // 圣 + 0x5724, KANJI_RARELY_USED, // 圀 + 0x5725, KANJI_RARELY_USED, // 圥 + 0x5729, KANJI_RARELY_USED, // 圩 + 0x572A, KANJI_RARELY_USED, // 圪 + 0x572C, KANJI_RARELY_USED, // 圬 + 0x572E, KANJI_RARELY_USED, // 圮 + 0x572F, KANJI_RARELY_USED, // 圯 + 0x5733, KANJI_RARELY_USED, // 圳 + 0x5734, KANJI_RARELY_USED, // 圎 + 0x573D, KANJI_RARELY_USED, // 圜 + 0x573E, KANJI_RARELY_USED, // 土 + 0x573F, KANJI_RARELY_USED, // 圿 + 0x5745, KANJI_RARELY_USED, // 坅 + 0x5746, KANJI_RARELY_USED, // 坆 + 0x574C, KANJI_RARELY_USED, // 坌 + 0x574D, KANJI_RARELY_USED, // 坍 + 0x5752, KANJI_RARELY_USED, // 坒 + 0x5762, KANJI_RARELY_USED, // 坢 + 0x5765, KANJI_RARELY_USED, // 坥 + 0x5767, KANJI_RARELY_USED, // 坧 + 0x5768, KANJI_RARELY_USED, // 坚 + 0x576B, KANJI_RARELY_USED, // 坫 + 0x576D, KANJI_RARELY_USED, // 坭 + 0x576E, KANJI_RARELY_USED, // 坮 + 0x576F, KANJI_RARELY_USED, // 坯 + 0x5770, KANJI_RARELY_USED, // 坰 + 0x5771, KANJI_RARELY_USED, // 坱 + 0x5773, KANJI_RARELY_USED, // 坳 + 0x5774, KANJI_RARELY_USED, // 坎 + 0x5775, KANJI_RARELY_USED, // 坵 + 0x5777, KANJI_RARELY_USED, // 坷 + 0x5779, KANJI_RARELY_USED, // 坹 + 0x577A, KANJI_RARELY_USED, // 坺 + 0x577B, KANJI_RARELY_USED, // 坻 + 0x577C, KANJI_RARELY_USED, // 坌 + 0x577E, KANJI_RARELY_USED, // 坟 + 0x5781, KANJI_RARELY_USED, // 垁 + 0x5783, KANJI_RARELY_USED, // 垃 + 0x578C, KANJI_RARELY_USED, // 垌 + 0x5794, KANJI_RARELY_USED, // 垔 + 0x5797, KANJI_RARELY_USED, // 垗 + 0x5799, KANJI_RARELY_USED, // 垙 + 0x579A, KANJI_RARELY_USED, // 垚 + 0x579C, KANJI_RARELY_USED, // 垜 + 0x579D, KANJI_RARELY_USED, // 垝 + 0x579E, KANJI_RARELY_USED, // 垞 + 0x579F, KANJI_RARELY_USED, // 垟 + 0x57A1, KANJI_RARELY_USED, // 垡 + 0x5795, KANJI_RARELY_USED, // 垕 + 0x57A7, KANJI_RARELY_USED, // 垧 + 0x57A8, KANJI_RARELY_USED, // 垚 + 0x57A9, KANJI_RARELY_USED, // 垩 + 0x57AC, KANJI_RARELY_USED, // 垬 + 0x57B8, KANJI_RARELY_USED, // åžž + 0x57BD, KANJI_RARELY_USED, // 垜 + 0x57C7, KANJI_RARELY_USED, // 埇 + 0x57C8, KANJI_RARELY_USED, // 埈 + 0x57CC, KANJI_RARELY_USED, // 埌 + 0x57CF, KANJI_RARELY_USED, // 埏 + 0x57D5, KANJI_RARELY_USED, // 埕 + 0x57DD, KANJI_RARELY_USED, // 埝 + 0x57DE, KANJI_RARELY_USED, // 埞 + 0x57E4, KANJI_RARELY_USED, // 埀 + 0x57E6, KANJI_RARELY_USED, // 埊 + 0x57E7, KANJI_RARELY_USED, // 埧 + 0x57E9, KANJI_RARELY_USED, // 埩 + 0x57ED, KANJI_RARELY_USED, // 埭 + 0x57F0, KANJI_RARELY_USED, // 埰 + 0x57F5, KANJI_RARELY_USED, // 埵 + 0x57F6, KANJI_RARELY_USED, // 埶 + 0x57F8, KANJI_RARELY_USED, // 埞 + 0x57FD, KANJI_RARELY_USED, // 埜 + 0x57FE, KANJI_RARELY_USED, // 域 + 0x57FF, KANJI_RARELY_USED, // 埿 + 0x5803, KANJI_RARELY_USED, // 堃 + 0x5804, KANJI_RARELY_USED, // 堄 + 0x5808, KANJI_RARELY_USED, // 堈 + 0x5809, KANJI_RARELY_USED, // 堉 + 0x57E1, KANJI_RARELY_USED, // 埡 + 0x580C, KANJI_RARELY_USED, // 堌 + 0x580D, KANJI_RARELY_USED, // 堍 + 0x581B, KANJI_RARELY_USED, // 堛 + 0x581E, KANJI_RARELY_USED, // 堞 + 0x581F, KANJI_RARELY_USED, // 堟 + 0x5820, KANJI_RARELY_USED, // å   + 0x5826, KANJI_RARELY_USED, // å Š + 0x5827, KANJI_RARELY_USED, // å § + 0x582D, KANJI_RARELY_USED, // å ­ + 0x5832, KANJI_RARELY_USED, // å ² + 0x5839, KANJI_RARELY_USED, // å ¹ + 0x583F, KANJI_RARELY_USED, // å ¿ + 0x5849, KANJI_RARELY_USED, // 塉 + 0x584C, KANJI_RARELY_USED, // 塌 + 0x584D, KANJI_RARELY_USED, // 塍 + 0x584F, KANJI_RARELY_USED, // 塏 + 0x5850, KANJI_RARELY_USED, // 塐 + 0x5855, KANJI_RARELY_USED, // 塕 + 0x585F, KANJI_RARELY_USED, // 塟 + 0x5861, KANJI_RARELY_USED, // å¡¡ + 0x5864, KANJI_RARELY_USED, // å¡€ + 0x5867, KANJI_RARELY_USED, // å¡§ + 0x5868, KANJI_RARELY_USED, // 塚 + 0x5878, KANJI_RARELY_USED, // 塞 + 0x587C, KANJI_RARELY_USED, // 塌 + 0x587F, KANJI_RARELY_USED, // å¡¿ + 0x5880, KANJI_RARELY_USED, // 墀 + 0x5881, KANJI_RARELY_USED, // 墁 + 0x5887, KANJI_RARELY_USED, // 墇 + 0x5888, KANJI_RARELY_USED, // 墈 + 0x5889, KANJI_RARELY_USED, // 墉 + 0x588A, KANJI_RARELY_USED, // 墊 + 0x588C, KANJI_RARELY_USED, // 墌 + 0x588D, KANJI_RARELY_USED, // 墍 + 0x588F, KANJI_RARELY_USED, // 墏 + 0x5890, KANJI_RARELY_USED, // 墐 + 0x5894, KANJI_RARELY_USED, // 墔 + 0x5896, KANJI_RARELY_USED, // 墖 + 0x589D, KANJI_RARELY_USED, // 墝 + 0x58A0, KANJI_RARELY_USED, // 墠 + 0x58A1, KANJI_RARELY_USED, // 墡 + 0x58A2, KANJI_RARELY_USED, // 墢 + 0x58A6, KANJI_RARELY_USED, // 墊 + 0x58A9, KANJI_RARELY_USED, // 墩 + 0x58B1, KANJI_RARELY_USED, // 墱 + 0x58B2, KANJI_RARELY_USED, // 墲 + 0x58C4, KANJI_RARELY_USED, // 壄 + 0x58BC, KANJI_RARELY_USED, // 墌 + 0x58C2, KANJI_RARELY_USED, // 壂 + 0x58C8, KANJI_RARELY_USED, // 壈 + 0x58CD, KANJI_RARELY_USED, // 壍 + 0x58CE, KANJI_RARELY_USED, // 壎 + 0x58D0, KANJI_RARELY_USED, // 壐 + 0x58D2, KANJI_RARELY_USED, // 壒 + 0x58D4, KANJI_RARELY_USED, // 壔 + 0x58D6, KANJI_RARELY_USED, // 壖 + 0x58DA, KANJI_RARELY_USED, // 壚 + 0x58DD, KANJI_RARELY_USED, // 壝 + 0x58E1, KANJI_RARELY_USED, // 壡 + 0x58E2, KANJI_RARELY_USED, // 壢 + 0x58E9, KANJI_RARELY_USED, // 壩 + 0x58F3, KANJI_RARELY_USED, // 壳 + 0x5905, KANJI_RARELY_USED, // 倅 + 0x5906, KANJI_RARELY_USED, // 倆 + 0x590B, KANJI_RARELY_USED, // 個 + 0x590C, KANJI_RARELY_USED, // 倌 + 0x5912, KANJI_RARELY_USED, // 倒 + 0x5913, KANJI_RARELY_USED, // 倓 + 0x5914, KANJI_RARELY_USED, // 倔 + 0x8641, KANJI_RARELY_USED, // 虁 + 0x591D, KANJI_RARELY_USED, // 倝 + 0x5921, KANJI_RARELY_USED, // 倡 + 0x5923, KANJI_RARELY_USED, // 倣 + 0x5924, KANJI_RARELY_USED, // 倀 + 0x5928, KANJI_RARELY_USED, // 倚 + 0x592F, KANJI_RARELY_USED, // 倯 + 0x5930, KANJI_RARELY_USED, // 倰 + 0x5933, KANJI_RARELY_USED, // 倳 + 0x5935, KANJI_RARELY_USED, // 倵 + 0x5936, KANJI_RARELY_USED, // 倶 + 0x593F, KANJI_RARELY_USED, // 倿 + 0x5943, KANJI_RARELY_USED, // 奃 + 0x5946, KANJI_RARELY_USED, // 奆 + 0x5952, KANJI_RARELY_USED, // 奒 + 0x5953, KANJI_RARELY_USED, // 奓 + 0x5959, KANJI_RARELY_USED, // 奙 + 0x595B, KANJI_RARELY_USED, // 奛 + 0x595D, KANJI_RARELY_USED, // 奝 + 0x595E, KANJI_RARELY_USED, // 奞 + 0x595F, KANJI_RARELY_USED, // 奟 + 0x5961, KANJI_RARELY_USED, // 奡 + 0x5963, KANJI_RARELY_USED, // 奣 + 0x596B, KANJI_RARELY_USED, // 奫 + 0x596D, KANJI_RARELY_USED, // 奭 + 0x596F, KANJI_RARELY_USED, // 奯 + 0x5972, KANJI_RARELY_USED, // 奲 + 0x5975, KANJI_RARELY_USED, // 奵 + 0x5976, KANJI_RARELY_USED, // 奶 + 0x5979, KANJI_RARELY_USED, // 她 + 0x597B, KANJI_RARELY_USED, // 奻 + 0x597C, KANJI_RARELY_USED, // 奌 + 0x598B, KANJI_RARELY_USED, // 劋 + 0x598C, KANJI_RARELY_USED, // 劌 + 0x598E, KANJI_RARELY_USED, // 劎 + 0x5992, KANJI_RARELY_USED, // 劒 + 0x5995, KANJI_RARELY_USED, // 劕 + 0x5997, KANJI_RARELY_USED, // 劗 + 0x599F, KANJI_RARELY_USED, // 功 + 0x59A4, KANJI_RARELY_USED, // 劀 + 0x59A7, KANJI_RARELY_USED, // 劧 + 0x59AD, KANJI_RARELY_USED, // 劭 + 0x59AE, KANJI_RARELY_USED, // 劮 + 0x59AF, KANJI_RARELY_USED, // 劯 + 0x59B0, KANJI_RARELY_USED, // 劰 + 0x59B3, KANJI_RARELY_USED, // 劳 + 0x59B7, KANJI_RARELY_USED, // 劷 + 0x59BA, KANJI_RARELY_USED, // 劺 + 0x59BC, KANJI_RARELY_USED, // 劌 + 0x59C1, KANJI_RARELY_USED, // 姁 + 0x59C3, KANJI_RARELY_USED, // 姃 + 0x59C4, KANJI_RARELY_USED, // 姄 + 0x59C8, KANJI_RARELY_USED, // 姈 + 0x59CA, KANJI_RARELY_USED, // 姊 + 0x59CD, KANJI_RARELY_USED, // 姍 + 0x59D2, KANJI_RARELY_USED, // 姒 + 0x59DD, KANJI_RARELY_USED, // 姝 + 0x59DE, KANJI_RARELY_USED, // 姞 + 0x59DF, KANJI_RARELY_USED, // 姟 + 0x59E3, KANJI_RARELY_USED, // å§£ + 0x59E4, KANJI_RARELY_USED, // å§€ + 0x59E7, KANJI_RARELY_USED, // å§§ + 0x59EE, KANJI_RARELY_USED, // å§® + 0x59EF, KANJI_RARELY_USED, // 姯 + 0x59F1, KANJI_RARELY_USED, // å§± + 0x59F2, KANJI_RARELY_USED, // å§² + 0x59F4, KANJI_RARELY_USED, // å§Ž + 0x59F7, KANJI_RARELY_USED, // å§· + 0x5A00, KANJI_RARELY_USED, // 嚀 + 0x5A04, KANJI_RARELY_USED, // åš„ + 0x5A0C, KANJI_RARELY_USED, // 嚌 + 0x5A0D, KANJI_RARELY_USED, // 嚍 + 0x5A0E, KANJI_RARELY_USED, // 嚎 + 0x5A12, KANJI_RARELY_USED, // åš’ + 0x5A13, KANJI_RARELY_USED, // åš“ + 0x5A1E, KANJI_RARELY_USED, // 嚞 + 0x5A23, KANJI_RARELY_USED, // 嚣 + 0x5A24, KANJI_RARELY_USED, // 嚀 + 0x5A27, KANJI_RARELY_USED, // åš§ + 0x5A28, KANJI_RARELY_USED, // åšš + 0x5A2A, KANJI_RARELY_USED, // 嚪 + 0x5A2D, KANJI_RARELY_USED, // åš­ + 0x5A30, KANJI_RARELY_USED, // åš° + 0x5A44, KANJI_RARELY_USED, // 婄 + 0x5A45, KANJI_RARELY_USED, // 婅 + 0x5A47, KANJI_RARELY_USED, // 婇 + 0x5A48, KANJI_RARELY_USED, // 婈 + 0x5A4C, KANJI_RARELY_USED, // 婌 + 0x5A50, KANJI_RARELY_USED, // 婐 + 0x5A55, KANJI_RARELY_USED, // 婕 + 0x5A5E, KANJI_RARELY_USED, // 婞 + 0x5A63, KANJI_RARELY_USED, // å©£ + 0x5A65, KANJI_RARELY_USED, // å©¥ + 0x5A67, KANJI_RARELY_USED, // å©§ + 0x5A6D, KANJI_RARELY_USED, // å©­ + 0x5A77, KANJI_RARELY_USED, // å©· + 0x5A7A, KANJI_RARELY_USED, // 婺 + 0x5A7B, KANJI_RARELY_USED, // å©» + 0x5A7E, KANJI_RARELY_USED, // 婟 + 0x5A8B, KANJI_RARELY_USED, // 媋 + 0x5A90, KANJI_RARELY_USED, // 媐 + 0x5A93, KANJI_RARELY_USED, // 媓 + 0x5A96, KANJI_RARELY_USED, // 媖 + 0x5A99, KANJI_RARELY_USED, // 媙 + 0x5A9C, KANJI_RARELY_USED, // 媜 + 0x5A9E, KANJI_RARELY_USED, // 媞 + 0x5A9F, KANJI_RARELY_USED, // 媟 + 0x5AA0, KANJI_RARELY_USED, // 媠 + 0x5AA2, KANJI_RARELY_USED, // 媢 + 0x5AA7, KANJI_RARELY_USED, // 媧 + 0x5AAC, KANJI_RARELY_USED, // 媬 + 0x5AB1, KANJI_RARELY_USED, // 媱 + 0x5AB2, KANJI_RARELY_USED, // 媲 + 0x5AB3, KANJI_RARELY_USED, // 媳 + 0x5AB5, KANJI_RARELY_USED, // 媵 + 0x5AB8, KANJI_RARELY_USED, // 媞 + 0x5ABA, KANJI_RARELY_USED, // 媺 + 0x5ABB, KANJI_RARELY_USED, // 媻 + 0x5ABF, KANJI_RARELY_USED, // 媿 + 0x5AC4, KANJI_RARELY_USED, // 嫄 + 0x5AC6, KANJI_RARELY_USED, // 嫆 + 0x5AC8, KANJI_RARELY_USED, // 嫈 + 0x5ACF, KANJI_RARELY_USED, // 嫏 + 0x5ADA, KANJI_RARELY_USED, // 嫚 + 0x5ADC, KANJI_RARELY_USED, // 嫜 + 0x5AE0, KANJI_RARELY_USED, // å«  + 0x5AE5, KANJI_RARELY_USED, // å«¥ + 0x5AEA, KANJI_RARELY_USED, // 嫪 + 0x5AEE, KANJI_RARELY_USED, // å«® + 0x5AF5, KANJI_RARELY_USED, // 嫵 + 0x5AF6, KANJI_RARELY_USED, // å«¶ + 0x5AFD, KANJI_RARELY_USED, // 嫜 + 0x5B00, KANJI_RARELY_USED, // 嬀 + 0x5B01, KANJI_RARELY_USED, // 嬁 + 0x5B08, KANJI_RARELY_USED, // 嬈 + 0x5B17, KANJI_RARELY_USED, // 嬗 + 0x5B34, KANJI_RARELY_USED, // 嬎 + 0x5B19, KANJI_RARELY_USED, // 嬙 + 0x5B1B, KANJI_RARELY_USED, // 嬛 + 0x5B1D, KANJI_RARELY_USED, // 嬝 + 0x5B21, KANJI_RARELY_USED, // 嬡 + 0x5B25, KANJI_RARELY_USED, // 嬥 + 0x5B2D, KANJI_RARELY_USED, // 嬭 + 0x5B38, KANJI_RARELY_USED, // 嬞 + 0x5B41, KANJI_RARELY_USED, // 孁 + 0x5B4B, KANJI_RARELY_USED, // 孋 + 0x5B4C, KANJI_RARELY_USED, // 孌 + 0x5B52, KANJI_RARELY_USED, // 孒 + 0x5B56, KANJI_RARELY_USED, // 孖 + 0x5B5E, KANJI_RARELY_USED, // 孞 + 0x5B68, KANJI_RARELY_USED, // å­š + 0x5B6E, KANJI_RARELY_USED, // å­® + 0x5B6F, KANJI_RARELY_USED, // å­¯ + 0x5B7C, KANJI_RARELY_USED, // å­Œ + 0x5B7D, KANJI_RARELY_USED, // å­œ + 0x5B7E, KANJI_RARELY_USED, // å­Ÿ + 0x5B7F, KANJI_RARELY_USED, // å­¿ + 0x5B81, KANJI_RARELY_USED, // 宁 + 0x5B84, KANJI_RARELY_USED, // 宄 + 0x5B86, KANJI_RARELY_USED, // 宆 + 0x5B8A, KANJI_RARELY_USED, // 宊 + 0x5B8E, KANJI_RARELY_USED, // 宎 + 0x5B90, KANJI_RARELY_USED, // 宐 + 0x5B91, KANJI_RARELY_USED, // 宑 + 0x5B93, KANJI_RARELY_USED, // 宓 + 0x5B94, KANJI_RARELY_USED, // 宔 + 0x5B96, KANJI_RARELY_USED, // 宖 + 0x5BA8, KANJI_RARELY_USED, // 定 + 0x5BA9, KANJI_RARELY_USED, // 宩 + 0x5BAC, KANJI_RARELY_USED, // 宬 + 0x5BAD, KANJI_RARELY_USED, // å®­ + 0x5BAF, KANJI_RARELY_USED, // 宯 + 0x5BB1, KANJI_RARELY_USED, // å®± + 0x5BB2, KANJI_RARELY_USED, // 宲 + 0x5BB7, KANJI_RARELY_USED, // å®· + 0x5BBA, KANJI_RARELY_USED, // 宺 + 0x5BBC, KANJI_RARELY_USED, // 完 + 0x5BC0, KANJI_RARELY_USED, // 寀 + 0x5BC1, KANJI_RARELY_USED, // 寁 + 0x5BCD, KANJI_RARELY_USED, // 寍 + 0x5BCF, KANJI_RARELY_USED, // 寏 + 0x5BD6, KANJI_RARELY_USED, // 寖 + 0x5BD7, KANJI_RARELY_USED, // 寗 + 0x5BD8, KANJI_RARELY_USED, // 寘 + 0x5BD9, KANJI_RARELY_USED, // 寙 + 0x5BDA, KANJI_RARELY_USED, // 寚 + 0x5BE0, KANJI_RARELY_USED, // 寠 + 0x5BEF, KANJI_RARELY_USED, // 寯 + 0x5BF1, KANJI_RARELY_USED, // 寱 + 0x5BF4, KANJI_RARELY_USED, // 寎 + 0x5BFD, KANJI_RARELY_USED, // 寜 + 0x5C0C, KANJI_RARELY_USED, // 尌 + 0x5C17, KANJI_RARELY_USED, // 尗 + 0x5C1E, KANJI_RARELY_USED, // 尞 + 0x5C1F, KANJI_RARELY_USED, // 尟 + 0x5C23, KANJI_RARELY_USED, // å°£ + 0x5C26, KANJI_RARELY_USED, // å°Š + 0x5C29, KANJI_RARELY_USED, // å°© + 0x5C2B, KANJI_RARELY_USED, // å°« + 0x5C2C, KANJI_RARELY_USED, // å°¬ + 0x5C2E, KANJI_RARELY_USED, // å°® + 0x5C30, KANJI_RARELY_USED, // å°° + 0x5C32, KANJI_RARELY_USED, // å°² + 0x5C35, KANJI_RARELY_USED, // å°µ + 0x5C36, KANJI_RARELY_USED, // å°¶ + 0x5C59, KANJI_RARELY_USED, // 屙 + 0x5C5A, KANJI_RARELY_USED, // 屚 + 0x5C5C, KANJI_RARELY_USED, // 屜 + 0x5C62, KANJI_RARELY_USED, // å±¢ + 0x5C63, KANJI_RARELY_USED, // å±£ + 0x5C67, KANJI_RARELY_USED, // å±§ + 0x5C68, KANJI_RARELY_USED, // 屚 + 0x5C69, KANJI_RARELY_USED, // 屩 + 0x5C6D, KANJI_RARELY_USED, // å±­ + 0x5C70, KANJI_RARELY_USED, // å±° + 0x5C74, KANJI_RARELY_USED, // 屎 + 0x5C75, KANJI_RARELY_USED, // å±µ + 0x5C7A, KANJI_RARELY_USED, // 屺 + 0x5C7B, KANJI_RARELY_USED, // å±» + 0x5C7C, KANJI_RARELY_USED, // 屌 + 0x5C7D, KANJI_RARELY_USED, // 屜 + 0x5C87, KANJI_RARELY_USED, // 岇 + 0x5C88, KANJI_RARELY_USED, // 岈 + 0x5C8A, KANJI_RARELY_USED, // 岊 + 0x5C8F, KANJI_RARELY_USED, // 岏 + 0x5C92, KANJI_RARELY_USED, // 岒 + 0x5C9D, KANJI_RARELY_USED, // 岝 + 0x5C9F, KANJI_RARELY_USED, // 岟 + 0x5CA0, KANJI_RARELY_USED, // å²  + 0x5CA2, KANJI_RARELY_USED, // å²¢ + 0x5CA3, KANJI_RARELY_USED, // å²£ + 0x5CA6, KANJI_RARELY_USED, // 岊 + 0x5CAA, KANJI_RARELY_USED, // 岪 + 0x5CB2, KANJI_RARELY_USED, // å²² + 0x5CB4, KANJI_RARELY_USED, // 岎 + 0x5CB5, KANJI_RARELY_USED, // å²µ + 0x5CBA, KANJI_RARELY_USED, // 岺 + 0x5CC9, KANJI_RARELY_USED, // 峉 + 0x5CCB, KANJI_RARELY_USED, // 峋 + 0x5CD2, KANJI_RARELY_USED, // 峒 + 0x5CDD, KANJI_RARELY_USED, // 峝 + 0x5CD7, KANJI_RARELY_USED, // 峗 + 0x5CEE, KANJI_RARELY_USED, // å³® + 0x5CF1, KANJI_RARELY_USED, // å³± + 0x5CF2, KANJI_RARELY_USED, // å³² + 0x5CF4, KANJI_RARELY_USED, // 峎 + 0x5D01, KANJI_RARELY_USED, // 厁 + 0x5D06, KANJI_RARELY_USED, // 历 + 0x5D0D, KANJI_RARELY_USED, // 厍 + 0x5D12, KANJI_RARELY_USED, // 厒 + 0x5D2B, KANJI_RARELY_USED, // 厫 + 0x5D23, KANJI_RARELY_USED, // 厣 + 0x5D24, KANJI_RARELY_USED, // 厀 + 0x5D26, KANJI_RARELY_USED, // 厊 + 0x5D27, KANJI_RARELY_USED, // 厧 + 0x5D31, KANJI_RARELY_USED, // 厱 + 0x5D34, KANJI_RARELY_USED, // 厎 + 0x5D39, KANJI_RARELY_USED, // 厹 + 0x5D3D, KANJI_RARELY_USED, // 厜 + 0x5D3F, KANJI_RARELY_USED, // 县 + 0x5D42, KANJI_RARELY_USED, // 嵂 + 0x5D43, KANJI_RARELY_USED, // 嵃 + 0x5D46, KANJI_RARELY_USED, // 嵆 + 0x5D48, KANJI_RARELY_USED, // 嵈 + 0x5D55, KANJI_RARELY_USED, // 嵕 + 0x5D51, KANJI_RARELY_USED, // 嵑 + 0x5D59, KANJI_RARELY_USED, // 嵙 + 0x5D4A, KANJI_RARELY_USED, // 嵊 + 0x5D5F, KANJI_RARELY_USED, // 嵟 + 0x5D60, KANJI_RARELY_USED, // åµ  + 0x5D61, KANJI_RARELY_USED, // 嵡 + 0x5D62, KANJI_RARELY_USED, // åµ¢ + 0x5D64, KANJI_RARELY_USED, // åµ€ + 0x5D6A, KANJI_RARELY_USED, // 嵪 + 0x5D6D, KANJI_RARELY_USED, // åµ­ + 0x5D70, KANJI_RARELY_USED, // åµ° + 0x5D79, KANJI_RARELY_USED, // åµ¹ + 0x5D7A, KANJI_RARELY_USED, // 嵺 + 0x5D7E, KANJI_RARELY_USED, // 嵟 + 0x5D7F, KANJI_RARELY_USED, // 嵿 + 0x5D81, KANJI_RARELY_USED, // 嶁 + 0x5D83, KANJI_RARELY_USED, // 嶃 + 0x5D88, KANJI_RARELY_USED, // 嶈 + 0x5D8A, KANJI_RARELY_USED, // 嶊 + 0x5D92, KANJI_RARELY_USED, // 嶒 + 0x5D93, KANJI_RARELY_USED, // 嶓 + 0x5D94, KANJI_RARELY_USED, // 嶔 + 0x5D95, KANJI_RARELY_USED, // 嶕 + 0x5D99, KANJI_RARELY_USED, // 嶙 + 0x5D9B, KANJI_RARELY_USED, // 嶛 + 0x5D9F, KANJI_RARELY_USED, // 嶟 + 0x5DA0, KANJI_RARELY_USED, // å¶  + 0x5DA7, KANJI_RARELY_USED, // å¶§ + 0x5DAB, KANJI_RARELY_USED, // å¶« + 0x5DB0, KANJI_RARELY_USED, // å¶° + 0x5DB4, KANJI_RARELY_USED, // å¶Ž + 0x5DB8, KANJI_RARELY_USED, // å¶ž + 0x5DB9, KANJI_RARELY_USED, // å¶¹ + 0x5DC3, KANJI_RARELY_USED, // 巃 + 0x5DC7, KANJI_RARELY_USED, // 巇 + 0x5DCB, KANJI_RARELY_USED, // 巋 + 0x5DD0, KANJI_RARELY_USED, // 巐 + 0x5DCE, KANJI_RARELY_USED, // 巎 + 0x5DD8, KANJI_RARELY_USED, // 巘 + 0x5DD9, KANJI_RARELY_USED, // 巙 + 0x5DE0, KANJI_RARELY_USED, // å·  + 0x5DE4, KANJI_RARELY_USED, // å·€ + 0x5DE9, KANJI_RARELY_USED, // å·© + 0x5DF8, KANJI_RARELY_USED, // å·ž + 0x5DF9, KANJI_RARELY_USED, // å·¹ + 0x5E00, KANJI_RARELY_USED, // 垀 + 0x5E07, KANJI_RARELY_USED, // 垇 + 0x5E0D, KANJI_RARELY_USED, // 垍 + 0x5E12, KANJI_RARELY_USED, // åž’ + 0x5E14, KANJI_RARELY_USED, // åž” + 0x5E15, KANJI_RARELY_USED, // åž• + 0x5E18, KANJI_RARELY_USED, // 垘 + 0x5E1F, KANJI_RARELY_USED, // 垟 + 0x5E20, KANJI_RARELY_USED, // åž  + 0x5E2E, KANJI_RARELY_USED, // åž® + 0x5E28, KANJI_RARELY_USED, // åžš + 0x5E32, KANJI_RARELY_USED, // åž² + 0x5E35, KANJI_RARELY_USED, // åžµ + 0x5E3E, KANJI_RARELY_USED, // 垟 + 0x5E4B, KANJI_RARELY_USED, // 幋 + 0x5E50, KANJI_RARELY_USED, // 幐 + 0x5E49, KANJI_RARELY_USED, // 幉 + 0x5E51, KANJI_RARELY_USED, // 幑 + 0x5E56, KANJI_RARELY_USED, // 幖 + 0x5E58, KANJI_RARELY_USED, // 幘 + 0x5E5B, KANJI_RARELY_USED, // 幛 + 0x5E5C, KANJI_RARELY_USED, // 幜 + 0x5E5E, KANJI_RARELY_USED, // 幞 + 0x5E68, KANJI_RARELY_USED, // 幚 + 0x5E6A, KANJI_RARELY_USED, // 幪 + 0x5E6B, KANJI_RARELY_USED, // 幫 + 0x5E6C, KANJI_RARELY_USED, // 幬 + 0x5E6D, KANJI_RARELY_USED, // å¹­ + 0x5E6E, KANJI_RARELY_USED, // å¹® + 0x5E70, KANJI_RARELY_USED, // å¹° + 0x5E80, KANJI_RARELY_USED, // 庀 + 0x5E8B, KANJI_RARELY_USED, // 庋 + 0x5E8E, KANJI_RARELY_USED, // 庎 + 0x5EA2, KANJI_RARELY_USED, // 庢 + 0x5EA4, KANJI_RARELY_USED, // 庀 + 0x5EA5, KANJI_RARELY_USED, // 庥 + 0x5EA8, KANJI_RARELY_USED, // 庚 + 0x5EAA, KANJI_RARELY_USED, // 庪 + 0x5EAC, KANJI_RARELY_USED, // 庬 + 0x5EB1, KANJI_RARELY_USED, // 庱 + 0x5EB3, KANJI_RARELY_USED, // 庳 + 0x5EBD, KANJI_RARELY_USED, // 府 + 0x5EBE, KANJI_RARELY_USED, // 废 + 0x5EBF, KANJI_RARELY_USED, // 庿 + 0x5EC6, KANJI_RARELY_USED, // 廆 + 0x5ECC, KANJI_RARELY_USED, // 廌 + 0x5ECB, KANJI_RARELY_USED, // 廋 + 0x5ECE, KANJI_RARELY_USED, // 廎 + 0x5ED1, KANJI_RARELY_USED, // 廑 + 0x5ED2, KANJI_RARELY_USED, // 廒 + 0x5ED4, KANJI_RARELY_USED, // 廔 + 0x5ED5, KANJI_RARELY_USED, // 廕 + 0x5EDC, KANJI_RARELY_USED, // 廜 + 0x5EDE, KANJI_RARELY_USED, // 廞 + 0x5EE5, KANJI_RARELY_USED, // 廥 + 0x5EEB, KANJI_RARELY_USED, // 廫 + 0x5F02, KANJI_RARELY_USED, // 匂 + 0x5F06, KANJI_RARELY_USED, // 匆 + 0x5F07, KANJI_RARELY_USED, // 匇 + 0x5F08, KANJI_RARELY_USED, // 匈 + 0x5F0E, KANJI_RARELY_USED, // 匎 + 0x5F19, KANJI_RARELY_USED, // 匙 + 0x5F1C, KANJI_RARELY_USED, // 匜 + 0x5F1D, KANJI_RARELY_USED, // 匝 + 0x5F21, KANJI_RARELY_USED, // 匡 + 0x5F22, KANJI_RARELY_USED, // 匢 + 0x5F23, KANJI_RARELY_USED, // 匣 + 0x5F24, KANJI_RARELY_USED, // 匀 + 0x5F28, KANJI_RARELY_USED, // 匚 + 0x5F2B, KANJI_RARELY_USED, // 匫 + 0x5F2C, KANJI_RARELY_USED, // 匬 + 0x5F2E, KANJI_RARELY_USED, // 匮 + 0x5F30, KANJI_RARELY_USED, // 匰 + 0x5F34, KANJI_RARELY_USED, // 匎 + 0x5F36, KANJI_RARELY_USED, // 匶 + 0x5F3B, KANJI_RARELY_USED, // 医 + 0x5F3D, KANJI_RARELY_USED, // 匜 + 0x5F3F, KANJI_RARELY_USED, // 匿 + 0x5F40, KANJI_RARELY_USED, // 圀 + 0x5F44, KANJI_RARELY_USED, // 圄 + 0x5F45, KANJI_RARELY_USED, // 圅 + 0x5F47, KANJI_RARELY_USED, // 圇 + 0x5F4D, KANJI_RARELY_USED, // 圍 + 0x5F50, KANJI_RARELY_USED, // 圐 + 0x5F54, KANJI_RARELY_USED, // 圔 + 0x5F58, KANJI_RARELY_USED, // 團 + 0x5F5B, KANJI_RARELY_USED, // 圛 + 0x5F60, KANJI_RARELY_USED, // 圠 + 0x5F63, KANJI_RARELY_USED, // 圣 + 0x5F64, KANJI_RARELY_USED, // 圀 + 0x5F67, KANJI_RARELY_USED, // 圧 + 0x5F6F, KANJI_RARELY_USED, // 圯 + 0x5F72, KANJI_RARELY_USED, // 圲 + 0x5F74, KANJI_RARELY_USED, // 圎 + 0x5F75, KANJI_RARELY_USED, // 圵 + 0x5F78, KANJI_RARELY_USED, // 圞 + 0x5F7A, KANJI_RARELY_USED, // 场 + 0x5F7D, KANJI_RARELY_USED, // 圜 + 0x5F7E, KANJI_RARELY_USED, // 土 + 0x5F89, KANJI_RARELY_USED, // 埉 + 0x5F8D, KANJI_RARELY_USED, // 埍 + 0x5F8F, KANJI_RARELY_USED, // 埏 + 0x5F96, KANJI_RARELY_USED, // 埖 + 0x5F9C, KANJI_RARELY_USED, // 埜 + 0x5F9D, KANJI_RARELY_USED, // 埝 + 0x5FA2, KANJI_RARELY_USED, // 埢 + 0x5FA7, KANJI_RARELY_USED, // 埧 + 0x5FAB, KANJI_RARELY_USED, // 埫 + 0x5FA4, KANJI_RARELY_USED, // 埀 + 0x5FAC, KANJI_RARELY_USED, // 埬 + 0x5FAF, KANJI_RARELY_USED, // 埯 + 0x5FB0, KANJI_RARELY_USED, // 埰 + 0x5FB1, KANJI_RARELY_USED, // 埱 + 0x5FB8, KANJI_RARELY_USED, // 埞 + 0x5FC4, KANJI_RARELY_USED, // 忄 + 0x5FC7, KANJI_RARELY_USED, // 忇 + 0x5FC8, KANJI_RARELY_USED, // 忈 + 0x5FC9, KANJI_RARELY_USED, // 忉 + 0x5FCB, KANJI_RARELY_USED, // 忋 + 0x5FD0, KANJI_RARELY_USED, // 忐 + 0x5FD1, KANJI_RARELY_USED, // 忑 + 0x5FD2, KANJI_RARELY_USED, // 忒 + 0x5FD3, KANJI_RARELY_USED, // 忓 + 0x5FD4, KANJI_RARELY_USED, // 忔 + 0x5FDE, KANJI_RARELY_USED, // 忞 + 0x5FE1, KANJI_RARELY_USED, // å¿¡ + 0x5FE2, KANJI_RARELY_USED, // å¿¢ + 0x5FE8, KANJI_RARELY_USED, // 忚 + 0x5FE9, KANJI_RARELY_USED, // å¿© + 0x5FEA, KANJI_RARELY_USED, // 忪 + 0x5FEC, KANJI_RARELY_USED, // 忬 + 0x5FED, KANJI_RARELY_USED, // å¿­ + 0x5FEE, KANJI_RARELY_USED, // å¿® + 0x5FEF, KANJI_RARELY_USED, // 忯 + 0x5FF2, KANJI_RARELY_USED, // 忲 + 0x5FF3, KANJI_RARELY_USED, // 忳 + 0x5FF6, KANJI_RARELY_USED, // å¿¶ + 0x5FFA, KANJI_RARELY_USED, // 忺 + 0x5FFC, KANJI_RARELY_USED, // 忌 + 0x6007, KANJI_RARELY_USED, // 怇 + 0x600A, KANJI_RARELY_USED, // 怊 + 0x600D, KANJI_RARELY_USED, // 怍 + 0x6013, KANJI_RARELY_USED, // 怓 + 0x6014, KANJI_RARELY_USED, // 怔 + 0x6017, KANJI_RARELY_USED, // 怗 + 0x6018, KANJI_RARELY_USED, // 怘 + 0x601A, KANJI_RARELY_USED, // 怚 + 0x601F, KANJI_RARELY_USED, // 怟 + 0x6024, KANJI_RARELY_USED, // 怀 + 0x602D, KANJI_RARELY_USED, // 怭 + 0x6033, KANJI_RARELY_USED, // 怳 + 0x6035, KANJI_RARELY_USED, // 怵 + 0x6040, KANJI_RARELY_USED, // 恀 + 0x6047, KANJI_RARELY_USED, // 恇 + 0x6048, KANJI_RARELY_USED, // 恈 + 0x6049, KANJI_RARELY_USED, // 恉 + 0x604C, KANJI_RARELY_USED, // 恌 + 0x6051, KANJI_RARELY_USED, // 恑 + 0x6054, KANJI_RARELY_USED, // 恔 + 0x6056, KANJI_RARELY_USED, // 恖 + 0x6057, KANJI_RARELY_USED, // 恗 + 0x605D, KANJI_RARELY_USED, // 恝 + 0x6061, KANJI_RARELY_USED, // 恡 + 0x6067, KANJI_RARELY_USED, // 恧 + 0x6071, KANJI_RARELY_USED, // 恱 + 0x607E, KANJI_RARELY_USED, // 恟 + 0x607F, KANJI_RARELY_USED, // 恿 + 0x6082, KANJI_RARELY_USED, // 悂 + 0x6086, KANJI_RARELY_USED, // 悆 + 0x6088, KANJI_RARELY_USED, // 悈 + 0x608A, KANJI_RARELY_USED, // 悊 + 0x608E, KANJI_RARELY_USED, // 悎 + 0x6091, KANJI_RARELY_USED, // 悑 + 0x6093, KANJI_RARELY_USED, // 悓 + 0x6095, KANJI_RARELY_USED, // 悕 + 0x6098, KANJI_RARELY_USED, // 悘 + 0x609D, KANJI_RARELY_USED, // 悝 + 0x609E, KANJI_RARELY_USED, // 悞 + 0x60A2, KANJI_RARELY_USED, // 悢 + 0x60A4, KANJI_RARELY_USED, // æ‚€ + 0x60A5, KANJI_RARELY_USED, // 悥 + 0x60A8, KANJI_RARELY_USED, // 悚 + 0x60B0, KANJI_RARELY_USED, // 悰 + 0x60B1, KANJI_RARELY_USED, // 悱 + 0x60B7, KANJI_RARELY_USED, // 悷 + 0x60BB, KANJI_RARELY_USED, // 悻 + 0x60BE, KANJI_RARELY_USED, // 悟 + 0x60C2, KANJI_RARELY_USED, // 惂 + 0x60C4, KANJI_RARELY_USED, // 惄 + 0x60C8, KANJI_RARELY_USED, // 惈 + 0x60C9, KANJI_RARELY_USED, // 惉 + 0x60CA, KANJI_RARELY_USED, // 惊 + 0x60CB, KANJI_RARELY_USED, // 惋 + 0x60CE, KANJI_RARELY_USED, // 惎 + 0x60CF, KANJI_RARELY_USED, // 惏 + 0x60D4, KANJI_RARELY_USED, // 惔 + 0x60D5, KANJI_RARELY_USED, // 惕 + 0x60D9, KANJI_RARELY_USED, // 惙 + 0x60DB, KANJI_RARELY_USED, // 惛 + 0x60DD, KANJI_RARELY_USED, // 惝 + 0x60DE, KANJI_RARELY_USED, // 惞 + 0x60E2, KANJI_RARELY_USED, // 惢 + 0x60E5, KANJI_RARELY_USED, // 惥 + 0x60F2, KANJI_RARELY_USED, // 惲 + 0x60F5, KANJI_RARELY_USED, // 惵 + 0x60F8, KANJI_RARELY_USED, // 惞 + 0x60FC, KANJI_RARELY_USED, // 惌 + 0x60FD, KANJI_RARELY_USED, // 惜 + 0x6102, KANJI_RARELY_USED, // 愂 + 0x6107, KANJI_RARELY_USED, // 愇 + 0x610A, KANJI_RARELY_USED, // 愊 + 0x610C, KANJI_RARELY_USED, // 愌 + 0x6110, KANJI_RARELY_USED, // 愐 + 0x6111, KANJI_RARELY_USED, // 愑 + 0x6112, KANJI_RARELY_USED, // 愒 + 0x6113, KANJI_RARELY_USED, // 愓 + 0x6114, KANJI_RARELY_USED, // 愔 + 0x6116, KANJI_RARELY_USED, // 愖 + 0x6117, KANJI_RARELY_USED, // 愗 + 0x6119, KANJI_RARELY_USED, // 愙 + 0x611C, KANJI_RARELY_USED, // 愜 + 0x611E, KANJI_RARELY_USED, // 愞 + 0x6122, KANJI_RARELY_USED, // 愢 + 0x612A, KANJI_RARELY_USED, // 愪 + 0x612B, KANJI_RARELY_USED, // 愫 + 0x6130, KANJI_RARELY_USED, // 愰 + 0x6131, KANJI_RARELY_USED, // 愱 + 0x6135, KANJI_RARELY_USED, // 愵 + 0x6136, KANJI_RARELY_USED, // 愶 + 0x6137, KANJI_RARELY_USED, // 愷 + 0x6139, KANJI_RARELY_USED, // 愹 + 0x6141, KANJI_RARELY_USED, // 慁 + 0x6145, KANJI_RARELY_USED, // 慅 + 0x6146, KANJI_RARELY_USED, // 慆 + 0x6149, KANJI_RARELY_USED, // 慉 + 0x615E, KANJI_RARELY_USED, // 慞 + 0x6160, KANJI_RARELY_USED, // 慠 + 0x616C, KANJI_RARELY_USED, // 慬 + 0x6172, KANJI_RARELY_USED, // 慲 + 0x6178, KANJI_RARELY_USED, // æ…ž + 0x617B, KANJI_RARELY_USED, // 慻 + 0x617C, KANJI_RARELY_USED, // æ…Œ + 0x617F, KANJI_RARELY_USED, // 慿 + 0x6180, KANJI_RARELY_USED, // 憀 + 0x6181, KANJI_RARELY_USED, // 憁 + 0x6183, KANJI_RARELY_USED, // 憃 + 0x6184, KANJI_RARELY_USED, // 憄 + 0x618B, KANJI_RARELY_USED, // 憋 + 0x618D, KANJI_RARELY_USED, // 憍 + 0x6192, KANJI_RARELY_USED, // 憒 + 0x6193, KANJI_RARELY_USED, // 憓 + 0x6197, KANJI_RARELY_USED, // 憗 + 0x6198, KANJI_RARELY_USED, // 憘 + 0x619C, KANJI_RARELY_USED, // 憜 + 0x619D, KANJI_RARELY_USED, // 憝 + 0x619F, KANJI_RARELY_USED, // 憟 + 0x61A0, KANJI_RARELY_USED, // 憠 + 0x61A5, KANJI_RARELY_USED, // 憥 + 0x61A8, KANJI_RARELY_USED, // 憚 + 0x61AA, KANJI_RARELY_USED, // 憪 + 0x61AD, KANJI_RARELY_USED, // 憭 + 0x61B8, KANJI_RARELY_USED, // 憞 + 0x61B9, KANJI_RARELY_USED, // 憹 + 0x61BC, KANJI_RARELY_USED, // 憌 + 0x61C0, KANJI_RARELY_USED, // 懀 + 0x61C1, KANJI_RARELY_USED, // 懁 + 0x61C2, KANJI_RARELY_USED, // 懂 + 0x61CE, KANJI_RARELY_USED, // 懎 + 0x61CF, KANJI_RARELY_USED, // 懏 + 0x61D5, KANJI_RARELY_USED, // 懕 + 0x61DC, KANJI_RARELY_USED, // 懜 + 0x61DD, KANJI_RARELY_USED, // 懝 + 0x61DE, KANJI_RARELY_USED, // 懞 + 0x61DF, KANJI_RARELY_USED, // 懟 + 0x61E1, KANJI_RARELY_USED, // 懡 + 0x61E2, KANJI_RARELY_USED, // 懢 + 0x61E7, KANJI_RARELY_USED, // 懧 + 0x61E9, KANJI_RARELY_USED, // 懩 + 0x61E5, KANJI_RARELY_USED, // 懥 + 0x61EC, KANJI_RARELY_USED, // 懬 + 0x61ED, KANJI_RARELY_USED, // 懭 + 0x61EF, KANJI_RARELY_USED, // 懯 + 0x6201, KANJI_RARELY_USED, // 戁 + 0x6203, KANJI_RARELY_USED, // 戃 + 0x6204, KANJI_RARELY_USED, // 戄 + 0x6207, KANJI_RARELY_USED, // 戇 + 0x6213, KANJI_RARELY_USED, // 戓 + 0x6215, KANJI_RARELY_USED, // 戕 + 0x621C, KANJI_RARELY_USED, // 戜 + 0x6220, KANJI_RARELY_USED, // 戠 + 0x6222, KANJI_RARELY_USED, // 戢 + 0x6223, KANJI_RARELY_USED, // 戣 + 0x6227, KANJI_RARELY_USED, // 戧 + 0x6229, KANJI_RARELY_USED, // 戩 + 0x622B, KANJI_RARELY_USED, // 戫 + 0x6239, KANJI_RARELY_USED, // 戹 + 0x623D, KANJI_RARELY_USED, // 戜 + 0x6242, KANJI_RARELY_USED, // 扂 + 0x6243, KANJI_RARELY_USED, // 扃 + 0x6244, KANJI_RARELY_USED, // 扄 + 0x6246, KANJI_RARELY_USED, // 扆 + 0x624C, KANJI_RARELY_USED, // 扌 + 0x6250, KANJI_RARELY_USED, // 扐 + 0x6251, KANJI_RARELY_USED, // 扑 + 0x6252, KANJI_RARELY_USED, // 扒 + 0x6254, KANJI_RARELY_USED, // 扔 + 0x6256, KANJI_RARELY_USED, // 扖 + 0x625A, KANJI_RARELY_USED, // 扚 + 0x625C, KANJI_RARELY_USED, // 扜 + 0x6264, KANJI_RARELY_USED, // 所 + 0x626D, KANJI_RARELY_USED, // 扭 + 0x626F, KANJI_RARELY_USED, // 扯 + 0x6273, KANJI_RARELY_USED, // 扳 + 0x627A, KANJI_RARELY_USED, // 扺 + 0x627D, KANJI_RARELY_USED, // 扜 + 0x628D, KANJI_RARELY_USED, // 抍 + 0x628E, KANJI_RARELY_USED, // 抎 + 0x628F, KANJI_RARELY_USED, // 抏 + 0x6290, KANJI_RARELY_USED, // 抐 + 0x62A6, KANJI_RARELY_USED, // 把 + 0x62A8, KANJI_RARELY_USED, // 抚 + 0x62B3, KANJI_RARELY_USED, // 抳 + 0x62B6, KANJI_RARELY_USED, // 抶 + 0x62B7, KANJI_RARELY_USED, // 抷 + 0x62BA, KANJI_RARELY_USED, // 抺 + 0x62BE, KANJI_RARELY_USED, // 抟 + 0x62BF, KANJI_RARELY_USED, // 抿 + 0x62C4, KANJI_RARELY_USED, // 拄 + 0x62CE, KANJI_RARELY_USED, // 拎 + 0x62D5, KANJI_RARELY_USED, // 拕 + 0x62D6, KANJI_RARELY_USED, // 拖 + 0x62DA, KANJI_RARELY_USED, // 拚 + 0x62EA, KANJI_RARELY_USED, // 拪 + 0x62F2, KANJI_RARELY_USED, // 拲 + 0x62F4, KANJI_RARELY_USED, // 拎 + 0x62FC, KANJI_RARELY_USED, // 拌 + 0x62FD, KANJI_RARELY_USED, // 拜 + 0x6303, KANJI_RARELY_USED, // 挃 + 0x6304, KANJI_RARELY_USED, // 挄 + 0x630A, KANJI_RARELY_USED, // 挊 + 0x630B, KANJI_RARELY_USED, // 挋 + 0x630D, KANJI_RARELY_USED, // 挍 + 0x6310, KANJI_RARELY_USED, // 挐 + 0x6313, KANJI_RARELY_USED, // 挓 + 0x6316, KANJI_RARELY_USED, // 挖 + 0x6318, KANJI_RARELY_USED, // 挘 + 0x6329, KANJI_RARELY_USED, // 挩 + 0x632A, KANJI_RARELY_USED, // 挪 + 0x632D, KANJI_RARELY_USED, // 挭 + 0x6335, KANJI_RARELY_USED, // 挵 + 0x6336, KANJI_RARELY_USED, // 挶 + 0x6339, KANJI_RARELY_USED, // 挹 + 0x633C, KANJI_RARELY_USED, // 挌 + 0x6341, KANJI_RARELY_USED, // 捁 + 0x6342, KANJI_RARELY_USED, // 捂 + 0x6343, KANJI_RARELY_USED, // 捃 + 0x6344, KANJI_RARELY_USED, // 捄 + 0x6346, KANJI_RARELY_USED, // 捆 + 0x634A, KANJI_RARELY_USED, // 捊 + 0x634B, KANJI_RARELY_USED, // 捋 + 0x634E, KANJI_RARELY_USED, // 捎 + 0x6352, KANJI_RARELY_USED, // 捒 + 0x6353, KANJI_RARELY_USED, // 捓 + 0x6354, KANJI_RARELY_USED, // 捔 + 0x6358, KANJI_RARELY_USED, // 捘 + 0x635B, KANJI_RARELY_USED, // 捛 + 0x6365, KANJI_RARELY_USED, // 捥 + 0x6366, KANJI_RARELY_USED, // 捊 + 0x636C, KANJI_RARELY_USED, // 捬 + 0x636D, KANJI_RARELY_USED, // 捭 + 0x6371, KANJI_RARELY_USED, // 捱 + 0x6374, KANJI_RARELY_USED, // 捎 + 0x6375, KANJI_RARELY_USED, // 捵 + 0x6378, KANJI_RARELY_USED, // 捞 + 0x637C, KANJI_RARELY_USED, // 捌 + 0x637D, KANJI_RARELY_USED, // 捜 + 0x637F, KANJI_RARELY_USED, // 捿 + 0x6382, KANJI_RARELY_USED, // 掂 + 0x6384, KANJI_RARELY_USED, // 掄 + 0x6387, KANJI_RARELY_USED, // 掇 + 0x638A, KANJI_RARELY_USED, // 掊 + 0x6390, KANJI_RARELY_USED, // 掐 + 0x6394, KANJI_RARELY_USED, // 掔 + 0x6395, KANJI_RARELY_USED, // 掕 + 0x6399, KANJI_RARELY_USED, // 掙 + 0x639A, KANJI_RARELY_USED, // 掚 + 0x639E, KANJI_RARELY_USED, // 掞 + 0x63A4, KANJI_RARELY_USED, // 掀 + 0x63A6, KANJI_RARELY_USED, // 掊 + 0x63AD, KANJI_RARELY_USED, // 掭 + 0x63AE, KANJI_RARELY_USED, // 掮 + 0x63AF, KANJI_RARELY_USED, // 掯 + 0x63BD, KANJI_RARELY_USED, // 掜 + 0x63C1, KANJI_RARELY_USED, // 揁 + 0x63C5, KANJI_RARELY_USED, // 揅 + 0x63C8, KANJI_RARELY_USED, // 揈 + 0x63CE, KANJI_RARELY_USED, // 揎 + 0x63D1, KANJI_RARELY_USED, // 揑 + 0x63D3, KANJI_RARELY_USED, // 揓 + 0x63D4, KANJI_RARELY_USED, // 揔 + 0x63D5, KANJI_RARELY_USED, // 揕 + 0x63DC, KANJI_RARELY_USED, // 揜 + 0x63E0, KANJI_RARELY_USED, // 揠 + 0x63E5, KANJI_RARELY_USED, // 揥 + 0x63EA, KANJI_RARELY_USED, // 揪 + 0x63EC, KANJI_RARELY_USED, // 揬 + 0x63F2, KANJI_RARELY_USED, // 揲 + 0x63F3, KANJI_RARELY_USED, // 揳 + 0x63F5, KANJI_RARELY_USED, // 揵 + 0x63F8, KANJI_RARELY_USED, // 揞 + 0x63F9, KANJI_RARELY_USED, // 揹 + 0x6409, KANJI_RARELY_USED, // 搉 + 0x640A, KANJI_RARELY_USED, // 搊 + 0x6410, KANJI_RARELY_USED, // 搐 + 0x6412, KANJI_RARELY_USED, // 搒 + 0x6414, KANJI_RARELY_USED, // 搔 + 0x6418, KANJI_RARELY_USED, // 搘 + 0x641E, KANJI_RARELY_USED, // 搞 + 0x6420, KANJI_RARELY_USED, // 搠 + 0x6422, KANJI_RARELY_USED, // 搢 + 0x6424, KANJI_RARELY_USED, // 搀 + 0x6425, KANJI_RARELY_USED, // 搥 + 0x6429, KANJI_RARELY_USED, // 搩 + 0x642A, KANJI_RARELY_USED, // 搪 + 0x642F, KANJI_RARELY_USED, // 搯 + 0x6430, KANJI_RARELY_USED, // 搰 + 0x6435, KANJI_RARELY_USED, // 搵 + 0x643D, KANJI_RARELY_USED, // 搜 + 0x643F, KANJI_RARELY_USED, // 搿 + 0x644B, KANJI_RARELY_USED, // 摋 + 0x644F, KANJI_RARELY_USED, // 摏 + 0x6451, KANJI_RARELY_USED, // 摑 + 0x6452, KANJI_RARELY_USED, // 摒 + 0x6453, KANJI_RARELY_USED, // 摓 + 0x6454, KANJI_RARELY_USED, // 摔 + 0x645A, KANJI_RARELY_USED, // 摚 + 0x645B, KANJI_RARELY_USED, // 摛 + 0x645C, KANJI_RARELY_USED, // 摜 + 0x645D, KANJI_RARELY_USED, // 摝 + 0x645F, KANJI_RARELY_USED, // 摟 + 0x6460, KANJI_RARELY_USED, // 摠 + 0x6461, KANJI_RARELY_USED, // 摡 + 0x6463, KANJI_RARELY_USED, // 摣 + 0x646D, KANJI_RARELY_USED, // 摭 + 0x6473, KANJI_RARELY_USED, // 摳 + 0x6474, KANJI_RARELY_USED, // 摎 + 0x647B, KANJI_RARELY_USED, // 摻 + 0x647D, KANJI_RARELY_USED, // 摜 + 0x6485, KANJI_RARELY_USED, // 撅 + 0x6487, KANJI_RARELY_USED, // 撇 + 0x648F, KANJI_RARELY_USED, // 撏 + 0x6490, KANJI_RARELY_USED, // 撐 + 0x6491, KANJI_RARELY_USED, // 撑 + 0x6498, KANJI_RARELY_USED, // 撘 + 0x6499, KANJI_RARELY_USED, // 撙 + 0x649B, KANJI_RARELY_USED, // 撛 + 0x649D, KANJI_RARELY_USED, // 撝 + 0x649F, KANJI_RARELY_USED, // 撟 + 0x64A1, KANJI_RARELY_USED, // 撡 + 0x64A3, KANJI_RARELY_USED, // 撣 + 0x64A6, KANJI_RARELY_USED, // æ’Š + 0x64A8, KANJI_RARELY_USED, // æ’š + 0x64AC, KANJI_RARELY_USED, // 撬 + 0x64B3, KANJI_RARELY_USED, // 撳 + 0x64BD, KANJI_RARELY_USED, // æ’œ + 0x64BE, KANJI_RARELY_USED, // æ’Ÿ + 0x64BF, KANJI_RARELY_USED, // 撿 + 0x64C4, KANJI_RARELY_USED, // 擄 + 0x64C9, KANJI_RARELY_USED, // 擉 + 0x64CA, KANJI_RARELY_USED, // 擊 + 0x64CB, KANJI_RARELY_USED, // 擋 + 0x64CC, KANJI_RARELY_USED, // 擌 + 0x64CE, KANJI_RARELY_USED, // 擎 + 0x64D0, KANJI_RARELY_USED, // 擐 + 0x64D1, KANJI_RARELY_USED, // 擑 + 0x64D5, KANJI_RARELY_USED, // 擕 + 0x64D7, KANJI_RARELY_USED, // 擗 + 0x64E4, KANJI_RARELY_USED, // æ“€ + 0x64E5, KANJI_RARELY_USED, // 擥 + 0x64E9, KANJI_RARELY_USED, // 擩 + 0x64EA, KANJI_RARELY_USED, // 擪 + 0x64ED, KANJI_RARELY_USED, // 擭 + 0x64F0, KANJI_RARELY_USED, // 擰 + 0x64F5, KANJI_RARELY_USED, // 擵 + 0x64F7, KANJI_RARELY_USED, // 擷 + 0x64FB, KANJI_RARELY_USED, // 擻 + 0x64FF, KANJI_RARELY_USED, // 擿 + 0x6501, KANJI_RARELY_USED, // 攁 + 0x6504, KANJI_RARELY_USED, // 攄 + 0x6508, KANJI_RARELY_USED, // 攈 + 0x6509, KANJI_RARELY_USED, // 攉 + 0x650A, KANJI_RARELY_USED, // 攊 + 0x650F, KANJI_RARELY_USED, // 攏 + 0x6513, KANJI_RARELY_USED, // 攓 + 0x6514, KANJI_RARELY_USED, // 攔 + 0x6516, KANJI_RARELY_USED, // 攖 + 0x6519, KANJI_RARELY_USED, // 攙 + 0x651B, KANJI_RARELY_USED, // 攛 + 0x651E, KANJI_RARELY_USED, // 攞 + 0x651F, KANJI_RARELY_USED, // 攟 + 0x6522, KANJI_RARELY_USED, // 攢 + 0x6526, KANJI_RARELY_USED, // 攊 + 0x6529, KANJI_RARELY_USED, // 攩 + 0x652E, KANJI_RARELY_USED, // 攮 + 0x6531, KANJI_RARELY_USED, // 攱 + 0x653A, KANJI_RARELY_USED, // 攺 + 0x653C, KANJI_RARELY_USED, // 攌 + 0x653D, KANJI_RARELY_USED, // 攜 + 0x6543, KANJI_RARELY_USED, // 敃 + 0x6547, KANJI_RARELY_USED, // 敇 + 0x6549, KANJI_RARELY_USED, // 敉 + 0x6550, KANJI_RARELY_USED, // 敐 + 0x6552, KANJI_RARELY_USED, // 敒 + 0x6554, KANJI_RARELY_USED, // 敔 + 0x655F, KANJI_RARELY_USED, // 敟 + 0x6560, KANJI_RARELY_USED, // 敠 + 0x6567, KANJI_RARELY_USED, // 敧 + 0x656B, KANJI_RARELY_USED, // 敫 + 0x657A, KANJI_RARELY_USED, // 敺 + 0x657D, KANJI_RARELY_USED, // 敜 + 0x6581, KANJI_RARELY_USED, // 斁 + 0x6585, KANJI_RARELY_USED, // 斅 + 0x658A, KANJI_RARELY_USED, // 斊 + 0x6592, KANJI_RARELY_USED, // 斒 + 0x6595, KANJI_RARELY_USED, // 斕 + 0x6598, KANJI_RARELY_USED, // 斘 + 0x659D, KANJI_RARELY_USED, // 斝 + 0x65A0, KANJI_RARELY_USED, // 斠 + 0x65A3, KANJI_RARELY_USED, // 斣 + 0x65A6, KANJI_RARELY_USED, // æ–Š + 0x65AE, KANJI_RARELY_USED, // 斮 + 0x65B2, KANJI_RARELY_USED, // 斲 + 0x65B3, KANJI_RARELY_USED, // 斳 + 0x65B4, KANJI_RARELY_USED, // æ–Ž + 0x65BF, KANJI_RARELY_USED, // 斿 + 0x65C2, KANJI_RARELY_USED, // 旂 + 0x65C8, KANJI_RARELY_USED, // 旈 + 0x65C9, KANJI_RARELY_USED, // 旉 + 0x65CE, KANJI_RARELY_USED, // 旎 + 0x65D0, KANJI_RARELY_USED, // 旐 + 0x65D4, KANJI_RARELY_USED, // 旔 + 0x65D6, KANJI_RARELY_USED, // 旖 + 0x65D8, KANJI_RARELY_USED, // 旘 + 0x65DF, KANJI_RARELY_USED, // 旟 + 0x65F0, KANJI_RARELY_USED, // 旰 + 0x65F2, KANJI_RARELY_USED, // 旲 + 0x65F4, KANJI_RARELY_USED, // æ—Ž + 0x65F5, KANJI_RARELY_USED, // 旵 + 0x65F9, KANJI_RARELY_USED, // 旹 + 0x65FE, KANJI_RARELY_USED, // æ—Ÿ + 0x65FF, KANJI_RARELY_USED, // 旿 + 0x6600, KANJI_RARELY_USED, // 昀 + 0x6604, KANJI_RARELY_USED, // 昄 + 0x6608, KANJI_RARELY_USED, // 昈 + 0x6609, KANJI_RARELY_USED, // 昉 + 0x660D, KANJI_RARELY_USED, // 昍 + 0x6611, KANJI_RARELY_USED, // 昑 + 0x6612, KANJI_RARELY_USED, // 昒 + 0x6615, KANJI_RARELY_USED, // 昕 + 0x6616, KANJI_RARELY_USED, // 昖 + 0x661D, KANJI_RARELY_USED, // 昝 + 0x661E, KANJI_RARELY_USED, // 昞 + 0x6621, KANJI_RARELY_USED, // 昡 + 0x6622, KANJI_RARELY_USED, // 昢 + 0x6623, KANJI_RARELY_USED, // 昣 + 0x6624, KANJI_RARELY_USED, // 昀 + 0x6626, KANJI_RARELY_USED, // 昊 + 0x6629, KANJI_RARELY_USED, // 昩 + 0x662A, KANJI_RARELY_USED, // 昪 + 0x662B, KANJI_RARELY_USED, // 昫 + 0x662C, KANJI_RARELY_USED, // 昬 + 0x662E, KANJI_RARELY_USED, // 昮 + 0x6630, KANJI_RARELY_USED, // 昰 + 0x6631, KANJI_RARELY_USED, // 昱 + 0x6633, KANJI_RARELY_USED, // 昳 + 0x6639, KANJI_RARELY_USED, // 昹 + 0x6637, KANJI_RARELY_USED, // 昷 + 0x6640, KANJI_RARELY_USED, // 晀 + 0x6645, KANJI_RARELY_USED, // 晅 + 0x6646, KANJI_RARELY_USED, // 晆 + 0x664A, KANJI_RARELY_USED, // 晊 + 0x664C, KANJI_RARELY_USED, // 晌 + 0x6651, KANJI_RARELY_USED, // 晑 + 0x664E, KANJI_RARELY_USED, // 晎 + 0x6657, KANJI_RARELY_USED, // 晗 + 0x6658, KANJI_RARELY_USED, // 晘 + 0x6659, KANJI_RARELY_USED, // 晙 + 0x665B, KANJI_RARELY_USED, // 晛 + 0x665C, KANJI_RARELY_USED, // 晜 + 0x6660, KANJI_RARELY_USED, // 晠 + 0x6661, KANJI_RARELY_USED, // 晡 + 0x66FB, KANJI_RARELY_USED, // 曻 + 0x666A, KANJI_RARELY_USED, // 晪 + 0x666B, KANJI_RARELY_USED, // 晫 + 0x666C, KANJI_RARELY_USED, // 晬 + 0x667E, KANJI_RARELY_USED, // 晟 + 0x6673, KANJI_RARELY_USED, // 晳 + 0x6675, KANJI_RARELY_USED, // 晵 + 0x667F, KANJI_RARELY_USED, // 晿 + 0x6677, KANJI_RARELY_USED, // 晷 + 0x6678, KANJI_RARELY_USED, // 晞 + 0x6679, KANJI_RARELY_USED, // 晹 + 0x667B, KANJI_RARELY_USED, // 晻 + 0x6680, KANJI_RARELY_USED, // 暀 + 0x667C, KANJI_RARELY_USED, // 晌 + 0x668B, KANJI_RARELY_USED, // 暋 + 0x668C, KANJI_RARELY_USED, // 暌 + 0x668D, KANJI_RARELY_USED, // 暍 + 0x6690, KANJI_RARELY_USED, // 暐 + 0x6692, KANJI_RARELY_USED, // 暒 + 0x6699, KANJI_RARELY_USED, // 暙 + 0x669A, KANJI_RARELY_USED, // 暚 + 0x669B, KANJI_RARELY_USED, // 暛 + 0x669C, KANJI_RARELY_USED, // 暜 + 0x669F, KANJI_RARELY_USED, // 暟 + 0x66A0, KANJI_RARELY_USED, // 暠 + 0x66A4, KANJI_RARELY_USED, // 暀 + 0x66AD, KANJI_RARELY_USED, // 暭 + 0x66B1, KANJI_RARELY_USED, // 暱 + 0x66B2, KANJI_RARELY_USED, // 暲 + 0x66B5, KANJI_RARELY_USED, // 暵 + 0x66BB, KANJI_RARELY_USED, // 暻 + 0x66BF, KANJI_RARELY_USED, // 暿 + 0x66C0, KANJI_RARELY_USED, // 曀 + 0x66C2, KANJI_RARELY_USED, // 曂 + 0x66C3, KANJI_RARELY_USED, // 曃 + 0x66C8, KANJI_RARELY_USED, // 曈 + 0x66CC, KANJI_RARELY_USED, // 曌 + 0x66CE, KANJI_RARELY_USED, // 曎 + 0x66CF, KANJI_RARELY_USED, // 曏 + 0x66D4, KANJI_RARELY_USED, // 曔 + 0x66DB, KANJI_RARELY_USED, // 曛 + 0x66DF, KANJI_RARELY_USED, // 曟 + 0x66E8, KANJI_RARELY_USED, // 曚 + 0x66EB, KANJI_RARELY_USED, // 曫 + 0x66EC, KANJI_RARELY_USED, // 曬 + 0x66EE, KANJI_RARELY_USED, // 曮 + 0x66FA, KANJI_RARELY_USED, // 曺 + 0x6705, KANJI_RARELY_USED, // 朅 + 0x6707, KANJI_RARELY_USED, // 朇 + 0x670E, KANJI_RARELY_USED, // 朎 + 0x6713, KANJI_RARELY_USED, // 朓 + 0x6719, KANJI_RARELY_USED, // 朙 + 0x671C, KANJI_RARELY_USED, // 朜 + 0x6720, KANJI_RARELY_USED, // 朠 + 0x6722, KANJI_RARELY_USED, // 朢 + 0x6733, KANJI_RARELY_USED, // 朳 + 0x673E, KANJI_RARELY_USED, // 期 + 0x6745, KANJI_RARELY_USED, // 杅 + 0x6747, KANJI_RARELY_USED, // 杇 + 0x6748, KANJI_RARELY_USED, // 杈 + 0x674C, KANJI_RARELY_USED, // 杌 + 0x6754, KANJI_RARELY_USED, // 杔 + 0x6755, KANJI_RARELY_USED, // 杕 + 0x675D, KANJI_RARELY_USED, // 杝 + 0x6766, KANJI_RARELY_USED, // 杊 + 0x676C, KANJI_RARELY_USED, // 杬 + 0x676E, KANJI_RARELY_USED, // 杮 + 0x6774, KANJI_RARELY_USED, // 李 + 0x6776, KANJI_RARELY_USED, // 杶 + 0x677B, KANJI_RARELY_USED, // 杻 + 0x6781, KANJI_RARELY_USED, // 极 + 0x6784, KANJI_RARELY_USED, // 构 + 0x678E, KANJI_RARELY_USED, // 枎 + 0x678F, KANJI_RARELY_USED, // 枏 + 0x6791, KANJI_RARELY_USED, // 枑 + 0x6793, KANJI_RARELY_USED, // 枓 + 0x6796, KANJI_RARELY_USED, // 枖 + 0x6798, KANJI_RARELY_USED, // 枘 + 0x6799, KANJI_RARELY_USED, // 枙 + 0x679B, KANJI_RARELY_USED, // 枛 + 0x67B0, KANJI_RARELY_USED, // 枰 + 0x67B1, KANJI_RARELY_USED, // 枱 + 0x67B2, KANJI_RARELY_USED, // 枲 + 0x67B5, KANJI_RARELY_USED, // 枵 + 0x67BB, KANJI_RARELY_USED, // 枻 + 0x67BC, KANJI_RARELY_USED, // 枌 + 0x67BD, KANJI_RARELY_USED, // 果 + 0x67F9, KANJI_RARELY_USED, // 柹 + 0x67C0, KANJI_RARELY_USED, // 柀 + 0x67C2, KANJI_RARELY_USED, // 柂 + 0x67C3, KANJI_RARELY_USED, // 柃 + 0x67C5, KANJI_RARELY_USED, // 柅 + 0x67C8, KANJI_RARELY_USED, // 柈 + 0x67C9, KANJI_RARELY_USED, // 柉 + 0x67D2, KANJI_RARELY_USED, // 柒 + 0x67D7, KANJI_RARELY_USED, // 柗 + 0x67D9, KANJI_RARELY_USED, // 柙 + 0x67DC, KANJI_RARELY_USED, // 柜 + 0x67E1, KANJI_RARELY_USED, // 柡 + 0x67E6, KANJI_RARELY_USED, // 柊 + 0x67F0, KANJI_RARELY_USED, // 柰 + 0x67F2, KANJI_RARELY_USED, // 柲 + 0x67F6, KANJI_RARELY_USED, // 柶 + 0x67F7, KANJI_RARELY_USED, // 柷 + 0x6852, KANJI_RARELY_USED, // 桒 + 0x6814, KANJI_RARELY_USED, // 栔 + 0x6819, KANJI_RARELY_USED, // 栙 + 0x681D, KANJI_RARELY_USED, // 栝 + 0x681F, KANJI_RARELY_USED, // 栟 + 0x6828, KANJI_RARELY_USED, // æ š + 0x6827, KANJI_RARELY_USED, // æ § + 0x682C, KANJI_RARELY_USED, // æ ¬ + 0x682D, KANJI_RARELY_USED, // æ ­ + 0x682F, KANJI_RARELY_USED, // æ ¯ + 0x6830, KANJI_RARELY_USED, // æ ° + 0x6831, KANJI_RARELY_USED, // æ ± + 0x6833, KANJI_RARELY_USED, // æ ³ + 0x683B, KANJI_RARELY_USED, // æ » + 0x683F, KANJI_RARELY_USED, // æ ¿ + 0x6844, KANJI_RARELY_USED, // 桄 + 0x6845, KANJI_RARELY_USED, // 桅 + 0x684A, KANJI_RARELY_USED, // 桊 + 0x684C, KANJI_RARELY_USED, // 桌 + 0x6855, KANJI_RARELY_USED, // 桕 + 0x6857, KANJI_RARELY_USED, // 桗 + 0x6858, KANJI_RARELY_USED, // 桘 + 0x685B, KANJI_RARELY_USED, // 桛 + 0x686B, KANJI_RARELY_USED, // æ¡« + 0x686E, KANJI_RARELY_USED, // æ¡® + 0x686F, KANJI_RARELY_USED, // 桯 + 0x6870, KANJI_RARELY_USED, // æ¡° + 0x6871, KANJI_RARELY_USED, // 桱 + 0x6872, KANJI_RARELY_USED, // 桲 + 0x6875, KANJI_RARELY_USED, // 桵 + 0x6879, KANJI_RARELY_USED, // 桹 + 0x687A, KANJI_RARELY_USED, // 桺 + 0x687B, KANJI_RARELY_USED, // æ¡» + 0x687C, KANJI_RARELY_USED, // 桌 + 0x6882, KANJI_RARELY_USED, // 梂 + 0x6884, KANJI_RARELY_USED, // 梄 + 0x6886, KANJI_RARELY_USED, // 梆 + 0x6888, KANJI_RARELY_USED, // 梈 + 0x6896, KANJI_RARELY_USED, // 梖 + 0x6898, KANJI_RARELY_USED, // 梘 + 0x689A, KANJI_RARELY_USED, // 梚 + 0x689C, KANJI_RARELY_USED, // 梜 + 0x68A1, KANJI_RARELY_USED, // 梡 + 0x68A3, KANJI_RARELY_USED, // 梣 + 0x68A5, KANJI_RARELY_USED, // 梥 + 0x68A9, KANJI_RARELY_USED, // 梩 + 0x68AA, KANJI_RARELY_USED, // 梪 + 0x68AE, KANJI_RARELY_USED, // 梮 + 0x68B2, KANJI_RARELY_USED, // 梲 + 0x68BB, KANJI_RARELY_USED, // 梻 + 0x68C5, KANJI_RARELY_USED, // 棅 + 0x68C8, KANJI_RARELY_USED, // 棈 + 0x68CC, KANJI_RARELY_USED, // 棌 + 0x68CF, KANJI_RARELY_USED, // 棏 + 0x68D0, KANJI_RARELY_USED, // 棐 + 0x68D1, KANJI_RARELY_USED, // 棑 + 0x68D3, KANJI_RARELY_USED, // 棓 + 0x68D6, KANJI_RARELY_USED, // 棖 + 0x68D9, KANJI_RARELY_USED, // 棙 + 0x68DC, KANJI_RARELY_USED, // 棜 + 0x68DD, KANJI_RARELY_USED, // 棝 + 0x68E5, KANJI_RARELY_USED, // 棥 + 0x68E8, KANJI_RARELY_USED, // 棚 + 0x68EA, KANJI_RARELY_USED, // 棪 + 0x68EB, KANJI_RARELY_USED, // 棫 + 0x68EC, KANJI_RARELY_USED, // 棬 + 0x68ED, KANJI_RARELY_USED, // 棭 + 0x68F0, KANJI_RARELY_USED, // 棰 + 0x68F1, KANJI_RARELY_USED, // 棱 + 0x68F5, KANJI_RARELY_USED, // 棵 + 0x68F6, KANJI_RARELY_USED, // 棶 + 0x68FB, KANJI_RARELY_USED, // 棻 + 0x68FC, KANJI_RARELY_USED, // 棌 + 0x68FD, KANJI_RARELY_USED, // 棜 + 0x6906, KANJI_RARELY_USED, // 怆 + 0x6909, KANJI_RARELY_USED, // 怉 + 0x690A, KANJI_RARELY_USED, // 怊 + 0x6910, KANJI_RARELY_USED, // 怐 + 0x6911, KANJI_RARELY_USED, // 怑 + 0x6913, KANJI_RARELY_USED, // 怓 + 0x6916, KANJI_RARELY_USED, // 怖 + 0x6917, KANJI_RARELY_USED, // 怗 + 0x6931, KANJI_RARELY_USED, // 怱 + 0x6933, KANJI_RARELY_USED, // 怳 + 0x6935, KANJI_RARELY_USED, // 怵 + 0x6938, KANJI_RARELY_USED, // 怞 + 0x693B, KANJI_RARELY_USED, // 总 + 0x6942, KANJI_RARELY_USED, // 楂 + 0x6945, KANJI_RARELY_USED, // 楅 + 0x6949, KANJI_RARELY_USED, // 楉 + 0x694E, KANJI_RARELY_USED, // 楎 + 0x6957, KANJI_RARELY_USED, // 楗 + 0x695B, KANJI_RARELY_USED, // 楛 + 0x6963, KANJI_RARELY_USED, // 楣 + 0x6964, KANJI_RARELY_USED, // 楀 + 0x6965, KANJI_RARELY_USED, // 楥 + 0x6966, KANJI_RARELY_USED, // 楊 + 0x6968, KANJI_RARELY_USED, // 楚 + 0x6969, KANJI_RARELY_USED, // 楩 + 0x696C, KANJI_RARELY_USED, // 楬 + 0x6970, KANJI_RARELY_USED, // 楰 + 0x6971, KANJI_RARELY_USED, // 楱 + 0x6972, KANJI_RARELY_USED, // 楲 + 0x697A, KANJI_RARELY_USED, // 楺 + 0x697B, KANJI_RARELY_USED, // 楻 + 0x697F, KANJI_RARELY_USED, // 楿 + 0x6980, KANJI_RARELY_USED, // 技 + 0x698D, KANJI_RARELY_USED, // 抍 + 0x6992, KANJI_RARELY_USED, // 抒 + 0x6996, KANJI_RARELY_USED, // 抖 + 0x6998, KANJI_RARELY_USED, // 折 + 0x69A1, KANJI_RARELY_USED, // 抡 + 0x69A5, KANJI_RARELY_USED, // 报 + 0x69A6, KANJI_RARELY_USED, // 把 + 0x69A8, KANJI_RARELY_USED, // 抚 + 0x69AB, KANJI_RARELY_USED, // 披 + 0x69AD, KANJI_RARELY_USED, // 抭 + 0x69AF, KANJI_RARELY_USED, // 抯 + 0x69B7, KANJI_RARELY_USED, // 抷 + 0x69B8, KANJI_RARELY_USED, // 択 + 0x69BA, KANJI_RARELY_USED, // 抺 + 0x69BC, KANJI_RARELY_USED, // 抌 + 0x69C5, KANJI_RARELY_USED, // 槅 + 0x69C8, KANJI_RARELY_USED, // 槈 + 0x69D1, KANJI_RARELY_USED, // 槑 + 0x69D6, KANJI_RARELY_USED, // 槖 + 0x69D7, KANJI_RARELY_USED, // 槗 + 0x69E2, KANJI_RARELY_USED, // æ§¢ + 0x69E5, KANJI_RARELY_USED, // æ§¥ + 0x69EE, KANJI_RARELY_USED, // æ§® + 0x69EF, KANJI_RARELY_USED, // 槯 + 0x69F1, KANJI_RARELY_USED, // æ§± + 0x69F3, KANJI_RARELY_USED, // æ§³ + 0x69F5, KANJI_RARELY_USED, // æ§µ + 0x69FE, KANJI_RARELY_USED, // æ§Ÿ + 0x6A00, KANJI_RARELY_USED, // 暀 + 0x6A01, KANJI_RARELY_USED, // 暁 + 0x6A03, KANJI_RARELY_USED, // 暃 + 0x6A0F, KANJI_RARELY_USED, // 暏 + 0x6A11, KANJI_RARELY_USED, // æš‘ + 0x6A15, KANJI_RARELY_USED, // æš• + 0x6A1A, KANJI_RARELY_USED, // æšš + 0x6A1D, KANJI_RARELY_USED, // 暝 + 0x6A20, KANJI_RARELY_USED, // æš  + 0x6A24, KANJI_RARELY_USED, // 暀 + 0x6A28, KANJI_RARELY_USED, // æšš + 0x6A30, KANJI_RARELY_USED, // æš° + 0x6A32, KANJI_RARELY_USED, // æš² + 0x6A34, KANJI_RARELY_USED, // 暎 + 0x6A37, KANJI_RARELY_USED, // æš· + 0x6A3B, KANJI_RARELY_USED, // æš» + 0x6A3E, KANJI_RARELY_USED, // 暟 + 0x6A3F, KANJI_RARELY_USED, // æš¿ + 0x6A45, KANJI_RARELY_USED, // 橅 + 0x6A46, KANJI_RARELY_USED, // 橆 + 0x6A49, KANJI_RARELY_USED, // 橉 + 0x6A4A, KANJI_RARELY_USED, // 橊 + 0x6A4E, KANJI_RARELY_USED, // 橎 + 0x6A50, KANJI_RARELY_USED, // 橐 + 0x6A51, KANJI_RARELY_USED, // 橑 + 0x6A52, KANJI_RARELY_USED, // 橒 + 0x6A55, KANJI_RARELY_USED, // 橕 + 0x6A56, KANJI_RARELY_USED, // 橖 + 0x6A5B, KANJI_RARELY_USED, // 橛 + 0x6A64, KANJI_RARELY_USED, // æ©€ + 0x6A67, KANJI_RARELY_USED, // æ©§ + 0x6A6A, KANJI_RARELY_USED, // 橪 + 0x6A71, KANJI_RARELY_USED, // 橱 + 0x6A73, KANJI_RARELY_USED, // 橳 + 0x6A7E, KANJI_RARELY_USED, // 機 + 0x6A81, KANJI_RARELY_USED, // 檁 + 0x6A83, KANJI_RARELY_USED, // 檃 + 0x6A86, KANJI_RARELY_USED, // 檆 + 0x6A87, KANJI_RARELY_USED, // 檇 + 0x6A89, KANJI_RARELY_USED, // 檉 + 0x6A8B, KANJI_RARELY_USED, // 檋 + 0x6A91, KANJI_RARELY_USED, // 檑 + 0x6A9B, KANJI_RARELY_USED, // 檛 + 0x6A9D, KANJI_RARELY_USED, // 檝 + 0x6A9E, KANJI_RARELY_USED, // 檞 + 0x6A9F, KANJI_RARELY_USED, // 檟 + 0x6AA5, KANJI_RARELY_USED, // 檥 + 0x6AAB, KANJI_RARELY_USED, // 檫 + 0x6AAF, KANJI_RARELY_USED, // 檯 + 0x6AB0, KANJI_RARELY_USED, // 檰 + 0x6AB1, KANJI_RARELY_USED, // 檱 + 0x6AB4, KANJI_RARELY_USED, // 檎 + 0x6ABD, KANJI_RARELY_USED, // 檜 + 0x6ABE, KANJI_RARELY_USED, // 檟 + 0x6ABF, KANJI_RARELY_USED, // 檿 + 0x6AC6, KANJI_RARELY_USED, // 櫆 + 0x6AC9, KANJI_RARELY_USED, // 櫉 + 0x6AC8, KANJI_RARELY_USED, // 櫈 + 0x6ACC, KANJI_RARELY_USED, // 櫌 + 0x6AD0, KANJI_RARELY_USED, // 櫐 + 0x6AD4, KANJI_RARELY_USED, // 櫔 + 0x6AD5, KANJI_RARELY_USED, // 櫕 + 0x6AD6, KANJI_RARELY_USED, // 櫖 + 0x6ADC, KANJI_RARELY_USED, // 櫜 + 0x6ADD, KANJI_RARELY_USED, // 櫝 + 0x6AE4, KANJI_RARELY_USED, // æ«€ + 0x6AE7, KANJI_RARELY_USED, // æ«§ + 0x6AEC, KANJI_RARELY_USED, // 櫬 + 0x6AF0, KANJI_RARELY_USED, // æ«° + 0x6AF1, KANJI_RARELY_USED, // 櫱 + 0x6AF2, KANJI_RARELY_USED, // 櫲 + 0x6AFC, KANJI_RARELY_USED, // 櫌 + 0x6AFD, KANJI_RARELY_USED, // 櫜 + 0x6B02, KANJI_RARELY_USED, // 欂 + 0x6B03, KANJI_RARELY_USED, // 欃 + 0x6B06, KANJI_RARELY_USED, // 欆 + 0x6B07, KANJI_RARELY_USED, // 欇 + 0x6B09, KANJI_RARELY_USED, // 欉 + 0x6B0F, KANJI_RARELY_USED, // 欏 + 0x6B10, KANJI_RARELY_USED, // 欐 + 0x6B11, KANJI_RARELY_USED, // 欑 + 0x6B17, KANJI_RARELY_USED, // 欗 + 0x6B1B, KANJI_RARELY_USED, // 欛 + 0x6B1E, KANJI_RARELY_USED, // 欞 + 0x6B24, KANJI_RARELY_USED, // 欀 + 0x6B28, KANJI_RARELY_USED, // 欚 + 0x6B2B, KANJI_RARELY_USED, // 欫 + 0x6B2C, KANJI_RARELY_USED, // 欬 + 0x6B2F, KANJI_RARELY_USED, // 欯 + 0x6B35, KANJI_RARELY_USED, // 欵 + 0x6B36, KANJI_RARELY_USED, // 欶 + 0x6B3B, KANJI_RARELY_USED, // 欻 + 0x6B3F, KANJI_RARELY_USED, // 欿 + 0x6B46, KANJI_RARELY_USED, // 歆 + 0x6B4A, KANJI_RARELY_USED, // 歊 + 0x6B4D, KANJI_RARELY_USED, // 歍 + 0x6B52, KANJI_RARELY_USED, // 歒 + 0x6B56, KANJI_RARELY_USED, // 歖 + 0x6B58, KANJI_RARELY_USED, // 歘 + 0x6B5D, KANJI_RARELY_USED, // 歝 + 0x6B60, KANJI_RARELY_USED, // æ­  + 0x6B67, KANJI_RARELY_USED, // æ­§ + 0x6B6B, KANJI_RARELY_USED, // æ­« + 0x6B6E, KANJI_RARELY_USED, // æ­® + 0x6B70, KANJI_RARELY_USED, // æ­° + 0x6B75, KANJI_RARELY_USED, // æ­µ + 0x6B7D, KANJI_RARELY_USED, // æ­œ + 0x6B7E, KANJI_RARELY_USED, // æ­Ÿ + 0x6B82, KANJI_RARELY_USED, // 殂 + 0x6B85, KANJI_RARELY_USED, // 殅 + 0x6B97, KANJI_RARELY_USED, // 殗 + 0x6B9B, KANJI_RARELY_USED, // 殛 + 0x6B9F, KANJI_RARELY_USED, // 殟 + 0x6BA0, KANJI_RARELY_USED, // æ®  + 0x6BA2, KANJI_RARELY_USED, // 殢 + 0x6BA3, KANJI_RARELY_USED, // 殣 + 0x6BA8, KANJI_RARELY_USED, // 殚 + 0x6BA9, KANJI_RARELY_USED, // 殩 + 0x6BAC, KANJI_RARELY_USED, // 殬 + 0x6BAD, KANJI_RARELY_USED, // æ®­ + 0x6BAE, KANJI_RARELY_USED, // æ®® + 0x6BB0, KANJI_RARELY_USED, // æ®° + 0x6BB8, KANJI_RARELY_USED, // 殞 + 0x6BB9, KANJI_RARELY_USED, // 殹 + 0x6BBD, KANJI_RARELY_USED, // 殜 + 0x6BBE, KANJI_RARELY_USED, // 殟 + 0x6BC3, KANJI_RARELY_USED, // 毃 + 0x6BC4, KANJI_RARELY_USED, // 毄 + 0x6BC9, KANJI_RARELY_USED, // 毉 + 0x6BCC, KANJI_RARELY_USED, // 毌 + 0x6BD6, KANJI_RARELY_USED, // 毖 + 0x6BDA, KANJI_RARELY_USED, // 毚 + 0x6BE1, KANJI_RARELY_USED, // 毡 + 0x6BE3, KANJI_RARELY_USED, // 毣 + 0x6BE6, KANJI_RARELY_USED, // 毊 + 0x6BE7, KANJI_RARELY_USED, // 毧 + 0x6BEE, KANJI_RARELY_USED, // 毮 + 0x6BF1, KANJI_RARELY_USED, // 毱 + 0x6BF7, KANJI_RARELY_USED, // 毷 + 0x6BF9, KANJI_RARELY_USED, // 毹 + 0x6BFF, KANJI_RARELY_USED, // 毿 + 0x6C02, KANJI_RARELY_USED, // 氂 + 0x6C04, KANJI_RARELY_USED, // 氄 + 0x6C05, KANJI_RARELY_USED, // 氅 + 0x6C09, KANJI_RARELY_USED, // 氉 + 0x6C0D, KANJI_RARELY_USED, // 氍 + 0x6C0E, KANJI_RARELY_USED, // 氎 + 0x6C10, KANJI_RARELY_USED, // 氐 + 0x6C12, KANJI_RARELY_USED, // 氒 + 0x6C19, KANJI_RARELY_USED, // 氙 + 0x6C1F, KANJI_RARELY_USED, // 氟 + 0x6C26, KANJI_RARELY_USED, // æ°Š + 0x6C27, KANJI_RARELY_USED, // æ°§ + 0x6C28, KANJI_RARELY_USED, // æ°š + 0x6C2C, KANJI_RARELY_USED, // æ°¬ + 0x6C2E, KANJI_RARELY_USED, // æ°® + 0x6C33, KANJI_RARELY_USED, // æ°³ + 0x6C35, KANJI_RARELY_USED, // æ°µ + 0x6C36, KANJI_RARELY_USED, // æ°¶ + 0x6C3A, KANJI_RARELY_USED, // æ°º + 0x6C3B, KANJI_RARELY_USED, // æ°» + 0x6C3F, KANJI_RARELY_USED, // æ°¿ + 0x6C4A, KANJI_RARELY_USED, // 汊 + 0x6C4B, KANJI_RARELY_USED, // 汋 + 0x6C4D, KANJI_RARELY_USED, // 汍 + 0x6C4F, KANJI_RARELY_USED, // 汏 + 0x6C52, KANJI_RARELY_USED, // 汒 + 0x6C54, KANJI_RARELY_USED, // 汔 + 0x6C59, KANJI_RARELY_USED, // 汙 + 0x6C5B, KANJI_RARELY_USED, // 汛 + 0x6C5C, KANJI_RARELY_USED, // 汜 + 0x6C6B, KANJI_RARELY_USED, // 汫 + 0x6C6D, KANJI_RARELY_USED, // æ±­ + 0x6C6F, KANJI_RARELY_USED, // 汯 + 0x6C74, KANJI_RARELY_USED, // 汎 + 0x6C76, KANJI_RARELY_USED, // æ±¶ + 0x6C78, KANJI_RARELY_USED, // 汞 + 0x6C79, KANJI_RARELY_USED, // æ±¹ + 0x6C7B, KANJI_RARELY_USED, // æ±» + 0x6C85, KANJI_RARELY_USED, // 沅 + 0x6C86, KANJI_RARELY_USED, // 沆 + 0x6C87, KANJI_RARELY_USED, // 沇 + 0x6C89, KANJI_RARELY_USED, // 沉 + 0x6C94, KANJI_RARELY_USED, // 沔 + 0x6C95, KANJI_RARELY_USED, // 沕 + 0x6C97, KANJI_RARELY_USED, // 沗 + 0x6C98, KANJI_RARELY_USED, // 沘 + 0x6C9C, KANJI_RARELY_USED, // 沜 + 0x6C9F, KANJI_RARELY_USED, // 沟 + 0x6CB0, KANJI_RARELY_USED, // æ²° + 0x6CB2, KANJI_RARELY_USED, // æ²² + 0x6CB4, KANJI_RARELY_USED, // 沎 + 0x6CC2, KANJI_RARELY_USED, // 泂 + 0x6CC6, KANJI_RARELY_USED, // 泆 + 0x6CCD, KANJI_RARELY_USED, // 泍 + 0x6CCF, KANJI_RARELY_USED, // 泏 + 0x6CD0, KANJI_RARELY_USED, // 泐 + 0x6CD1, KANJI_RARELY_USED, // 泑 + 0x6CD2, KANJI_RARELY_USED, // 泒 + 0x6CD4, KANJI_RARELY_USED, // 泔 + 0x6CD6, KANJI_RARELY_USED, // 泖 + 0x6CDA, KANJI_RARELY_USED, // 泚 + 0x6CDC, KANJI_RARELY_USED, // 泜 + 0x6CE0, KANJI_RARELY_USED, // æ³  + 0x6CE7, KANJI_RARELY_USED, // æ³§ + 0x6CE9, KANJI_RARELY_USED, // 泩 + 0x6CEB, KANJI_RARELY_USED, // 泫 + 0x6CEC, KANJI_RARELY_USED, // 泬 + 0x6CEE, KANJI_RARELY_USED, // æ³® + 0x6CF2, KANJI_RARELY_USED, // æ³² + 0x6CF4, KANJI_RARELY_USED, // 泎 + 0x6D04, KANJI_RARELY_USED, // 掄 + 0x6D07, KANJI_RARELY_USED, // 掇 + 0x6D0A, KANJI_RARELY_USED, // 掊 + 0x6D0E, KANJI_RARELY_USED, // 掎 + 0x6D0F, KANJI_RARELY_USED, // 掏 + 0x6D11, KANJI_RARELY_USED, // 掑 + 0x6D13, KANJI_RARELY_USED, // 掓 + 0x6D1A, KANJI_RARELY_USED, // 掚 + 0x6D26, KANJI_RARELY_USED, // 掊 + 0x6D27, KANJI_RARELY_USED, // 控 + 0x6D28, KANJI_RARELY_USED, // 掚 + 0x6C67, KANJI_RARELY_USED, // æ±§ + 0x6D2E, KANJI_RARELY_USED, // 掮 + 0x6D2F, KANJI_RARELY_USED, // 掯 + 0x6D31, KANJI_RARELY_USED, // 掱 + 0x6D39, KANJI_RARELY_USED, // 掹 + 0x6D3C, KANJI_RARELY_USED, // 掌 + 0x6D3F, KANJI_RARELY_USED, // 掿 + 0x6D57, KANJI_RARELY_USED, // 浗 + 0x6D5E, KANJI_RARELY_USED, // 浞 + 0x6D5F, KANJI_RARELY_USED, // 浟 + 0x6D61, KANJI_RARELY_USED, // 浡 + 0x6D65, KANJI_RARELY_USED, // æµ¥ + 0x6D67, KANJI_RARELY_USED, // æµ§ + 0x6D6F, KANJI_RARELY_USED, // 浯 + 0x6D70, KANJI_RARELY_USED, // æµ° + 0x6D7C, KANJI_RARELY_USED, // 浌 + 0x6D82, KANJI_RARELY_USED, // 涂 + 0x6D87, KANJI_RARELY_USED, // 涇 + 0x6D91, KANJI_RARELY_USED, // 涑 + 0x6D92, KANJI_RARELY_USED, // 涒 + 0x6D94, KANJI_RARELY_USED, // 涔 + 0x6D96, KANJI_RARELY_USED, // 涖 + 0x6D97, KANJI_RARELY_USED, // 涗 + 0x6D98, KANJI_RARELY_USED, // 涘 + 0x6DAA, KANJI_RARELY_USED, // 涪 + 0x6DAC, KANJI_RARELY_USED, // 涬 + 0x6DB4, KANJI_RARELY_USED, // æ¶Ž + 0x6DB7, KANJI_RARELY_USED, // æ¶· + 0x6DB9, KANJI_RARELY_USED, // æ¶¹ + 0x6DBD, KANJI_RARELY_USED, // æ¶œ + 0x6DBF, KANJI_RARELY_USED, // æ¶¿ + 0x6DC4, KANJI_RARELY_USED, // 淄 + 0x6DC8, KANJI_RARELY_USED, // 淈 + 0x6DCA, KANJI_RARELY_USED, // 淊 + 0x6DCE, KANJI_RARELY_USED, // 淎 + 0x6DCF, KANJI_RARELY_USED, // 淏 + 0x6DD6, KANJI_RARELY_USED, // 淖 + 0x6DDB, KANJI_RARELY_USED, // 淛 + 0x6DDD, KANJI_RARELY_USED, // 淝 + 0x6DDF, KANJI_RARELY_USED, // 淟 + 0x6DE0, KANJI_RARELY_USED, // æ·  + 0x6DE2, KANJI_RARELY_USED, // æ·¢ + 0x6DE5, KANJI_RARELY_USED, // æ·¥ + 0x6DE9, KANJI_RARELY_USED, // æ·© + 0x6DEF, KANJI_RARELY_USED, // æ·¯ + 0x6DF0, KANJI_RARELY_USED, // æ·° + 0x6DF4, KANJI_RARELY_USED, // æ·Ž + 0x6DF6, KANJI_RARELY_USED, // æ·¶ + 0x6DFC, KANJI_RARELY_USED, // æ·Œ + 0x6E00, KANJI_RARELY_USED, // 枀 + 0x6E04, KANJI_RARELY_USED, // æž„ + 0x6E1E, KANJI_RARELY_USED, // æžž + 0x6E22, KANJI_RARELY_USED, // 枢 + 0x6E27, KANJI_RARELY_USED, // æž§ + 0x6E32, KANJI_RARELY_USED, // æž² + 0x6E36, KANJI_RARELY_USED, // æž¶ + 0x6E39, KANJI_RARELY_USED, // æž¹ + 0x6E3B, KANJI_RARELY_USED, // æž» + 0x6E3C, KANJI_RARELY_USED, // 枌 + 0x6E44, KANJI_RARELY_USED, // 湄 + 0x6E45, KANJI_RARELY_USED, // 湅 + 0x6E48, KANJI_RARELY_USED, // 湈 + 0x6E49, KANJI_RARELY_USED, // 湉 + 0x6E4B, KANJI_RARELY_USED, // 湋 + 0x6E4F, KANJI_RARELY_USED, // 湏 + 0x6E51, KANJI_RARELY_USED, // 湑 + 0x6E52, KANJI_RARELY_USED, // 湒 + 0x6E53, KANJI_RARELY_USED, // 湓 + 0x6E54, KANJI_RARELY_USED, // 湔 + 0x6E57, KANJI_RARELY_USED, // 湗 + 0x6E5C, KANJI_RARELY_USED, // 湜 + 0x6E5D, KANJI_RARELY_USED, // 湝 + 0x6E5E, KANJI_RARELY_USED, // 湞 + 0x6E62, KANJI_RARELY_USED, // æ¹¢ + 0x6E63, KANJI_RARELY_USED, // æ¹£ + 0x6E68, KANJI_RARELY_USED, // 湚 + 0x6E73, KANJI_RARELY_USED, // æ¹³ + 0x6E7B, KANJI_RARELY_USED, // æ¹» + 0x6E7D, KANJI_RARELY_USED, // 湜 + 0x6E8D, KANJI_RARELY_USED, // 溍 + 0x6E93, KANJI_RARELY_USED, // 溓 + 0x6E99, KANJI_RARELY_USED, // 溙 + 0x6EA0, KANJI_RARELY_USED, // 溠 + 0x6EA7, KANJI_RARELY_USED, // 溧 + 0x6EAD, KANJI_RARELY_USED, // 溭 + 0x6EAE, KANJI_RARELY_USED, // 溮 + 0x6EB1, KANJI_RARELY_USED, // 溱 + 0x6EB3, KANJI_RARELY_USED, // 溳 + 0x6EBB, KANJI_RARELY_USED, // 溻 + 0x6EBF, KANJI_RARELY_USED, // 溿 + 0x6EC0, KANJI_RARELY_USED, // 滀 + 0x6EC1, KANJI_RARELY_USED, // 滁 + 0x6EC3, KANJI_RARELY_USED, // 滃 + 0x6EC7, KANJI_RARELY_USED, // 滇 + 0x6EC8, KANJI_RARELY_USED, // 滈 + 0x6ECA, KANJI_RARELY_USED, // 滊 + 0x6ECD, KANJI_RARELY_USED, // 滍 + 0x6ECE, KANJI_RARELY_USED, // 滎 + 0x6ECF, KANJI_RARELY_USED, // 滏 + 0x6EEB, KANJI_RARELY_USED, // 滫 + 0x6EED, KANJI_RARELY_USED, // æ»­ + 0x6EEE, KANJI_RARELY_USED, // æ»® + 0x6EF9, KANJI_RARELY_USED, // 滹 + 0x6EFB, KANJI_RARELY_USED, // æ»» + 0x6EFD, KANJI_RARELY_USED, // 滜 + 0x6F04, KANJI_RARELY_USED, // 挄 + 0x6F08, KANJI_RARELY_USED, // 挈 + 0x6F0A, KANJI_RARELY_USED, // 挊 + 0x6F0C, KANJI_RARELY_USED, // 挌 + 0x6F0D, KANJI_RARELY_USED, // 挍 + 0x6F16, KANJI_RARELY_USED, // 挖 + 0x6F18, KANJI_RARELY_USED, // 挘 + 0x6F1A, KANJI_RARELY_USED, // 挚 + 0x6F1B, KANJI_RARELY_USED, // 挛 + 0x6F26, KANJI_RARELY_USED, // 挊 + 0x6F29, KANJI_RARELY_USED, // 挩 + 0x6F2A, KANJI_RARELY_USED, // 挪 + 0x6F2F, KANJI_RARELY_USED, // 振 + 0x6F30, KANJI_RARELY_USED, // 挰 + 0x6F33, KANJI_RARELY_USED, // 挳 + 0x6F36, KANJI_RARELY_USED, // 挶 + 0x6F3B, KANJI_RARELY_USED, // 挻 + 0x6F3C, KANJI_RARELY_USED, // 挌 + 0x6F2D, KANJI_RARELY_USED, // 挭 + 0x6F4F, KANJI_RARELY_USED, // 朏 + 0x6F51, KANJI_RARELY_USED, // 朑 + 0x6F52, KANJI_RARELY_USED, // 朒 + 0x6F53, KANJI_RARELY_USED, // 朓 + 0x6F57, KANJI_RARELY_USED, // 朗 + 0x6F59, KANJI_RARELY_USED, // 朙 + 0x6F5A, KANJI_RARELY_USED, // 朚 + 0x6F5D, KANJI_RARELY_USED, // 朝 + 0x6F5E, KANJI_RARELY_USED, // 朞 + 0x6F61, KANJI_RARELY_USED, // 朡 + 0x6F62, KANJI_RARELY_USED, // 朢 + 0x6F68, KANJI_RARELY_USED, // 朚 + 0x6F6C, KANJI_RARELY_USED, // 本 + 0x6F7D, KANJI_RARELY_USED, // 朜 + 0x6F7E, KANJI_RARELY_USED, // 期 + 0x6F83, KANJI_RARELY_USED, // 柃 + 0x6F87, KANJI_RARELY_USED, // 柇 + 0x6F88, KANJI_RARELY_USED, // 柈 + 0x6F8B, KANJI_RARELY_USED, // 柋 + 0x6F8C, KANJI_RARELY_USED, // 柌 + 0x6F8D, KANJI_RARELY_USED, // 柍 + 0x6F90, KANJI_RARELY_USED, // 某 + 0x6F92, KANJI_RARELY_USED, // 柒 + 0x6F93, KANJI_RARELY_USED, // 染 + 0x6F94, KANJI_RARELY_USED, // 柔 + 0x6F96, KANJI_RARELY_USED, // 柖 + 0x6F9A, KANJI_RARELY_USED, // 柚 + 0x6F9F, KANJI_RARELY_USED, // 柟 + 0x6FA0, KANJI_RARELY_USED, // 柠 + 0x6FA5, KANJI_RARELY_USED, // 查 + 0x6FA6, KANJI_RARELY_USED, // 柊 + 0x6FA7, KANJI_RARELY_USED, // 柧 + 0x6FA8, KANJI_RARELY_USED, // 柚 + 0x6FAE, KANJI_RARELY_USED, // 柮 + 0x6FAF, KANJI_RARELY_USED, // 柯 + 0x6FB0, KANJI_RARELY_USED, // 柰 + 0x6FB5, KANJI_RARELY_USED, // 柵 + 0x6FB6, KANJI_RARELY_USED, // 柶 + 0x6FBC, KANJI_RARELY_USED, // 柌 + 0x6FC5, KANJI_RARELY_USED, // 濅 + 0x6FC7, KANJI_RARELY_USED, // 濇 + 0x6FC8, KANJI_RARELY_USED, // 濈 + 0x6FCA, KANJI_RARELY_USED, // 濊 + 0x6FDA, KANJI_RARELY_USED, // 濚 + 0x6FDE, KANJI_RARELY_USED, // 濞 + 0x6FE8, KANJI_RARELY_USED, // 濚 + 0x6FE9, KANJI_RARELY_USED, // æ¿© + 0x6FF0, KANJI_RARELY_USED, // æ¿° + 0x6FF5, KANJI_RARELY_USED, // 濵 + 0x6FF9, KANJI_RARELY_USED, // 濹 + 0x6FFC, KANJI_RARELY_USED, // 濌 + 0x6FFD, KANJI_RARELY_USED, // 濜 + 0x7000, KANJI_RARELY_USED, // 瀀 + 0x7005, KANJI_RARELY_USED, // 瀅 + 0x7006, KANJI_RARELY_USED, // 瀆 + 0x7007, KANJI_RARELY_USED, // 瀇 + 0x700D, KANJI_RARELY_USED, // 瀍 + 0x7017, KANJI_RARELY_USED, // 瀗 + 0x7020, KANJI_RARELY_USED, // 瀠 + 0x7023, KANJI_RARELY_USED, // 瀣 + 0x702F, KANJI_RARELY_USED, // 瀯 + 0x7034, KANJI_RARELY_USED, // 瀮 + 0x7037, KANJI_RARELY_USED, // 瀷 + 0x7039, KANJI_RARELY_USED, // 瀹 + 0x703C, KANJI_RARELY_USED, // 瀌 + 0x7043, KANJI_RARELY_USED, // 灃 + 0x7044, KANJI_RARELY_USED, // 灄 + 0x7048, KANJI_RARELY_USED, // 灈 + 0x7049, KANJI_RARELY_USED, // 灉 + 0x704A, KANJI_RARELY_USED, // 灊 + 0x704B, KANJI_RARELY_USED, // 灋 + 0x7054, KANJI_RARELY_USED, // 灔 + 0x7055, KANJI_RARELY_USED, // 灕 + 0x705D, KANJI_RARELY_USED, // 灝 + 0x705E, KANJI_RARELY_USED, // 灞 + 0x704E, KANJI_RARELY_USED, // 灎 + 0x7064, KANJI_RARELY_USED, // 灀 + 0x7065, KANJI_RARELY_USED, // 灥 + 0x706C, KANJI_RARELY_USED, // 灬 + 0x706E, KANJI_RARELY_USED, // 灮 + 0x7075, KANJI_RARELY_USED, // 灵 + 0x7076, KANJI_RARELY_USED, // 灶 + 0x707E, KANJI_RARELY_USED, // 灟 + 0x7081, KANJI_RARELY_USED, // 炁 + 0x7085, KANJI_RARELY_USED, // 炅 + 0x7086, KANJI_RARELY_USED, // 炆 + 0x7094, KANJI_RARELY_USED, // 炔 + 0x7095, KANJI_RARELY_USED, // 炕 + 0x7096, KANJI_RARELY_USED, // 炖 + 0x7097, KANJI_RARELY_USED, // 炗 + 0x7098, KANJI_RARELY_USED, // 炘 + 0x709B, KANJI_RARELY_USED, // 炛 + 0x70A4, KANJI_RARELY_USED, // ç‚€ + 0x70AB, KANJI_RARELY_USED, // 炫 + 0x70B0, KANJI_RARELY_USED, // 炰 + 0x70B1, KANJI_RARELY_USED, // 炱 + 0x70B4, KANJI_RARELY_USED, // 炮 + 0x70B7, KANJI_RARELY_USED, // 炷 + 0x70CA, KANJI_RARELY_USED, // 烊 + 0x70D1, KANJI_RARELY_USED, // 烑 + 0x70D3, KANJI_RARELY_USED, // 烓 + 0x70D4, KANJI_RARELY_USED, // 烔 + 0x70D5, KANJI_RARELY_USED, // 烕 + 0x70D6, KANJI_RARELY_USED, // 烖 + 0x70D8, KANJI_RARELY_USED, // 烘 + 0x70DC, KANJI_RARELY_USED, // 烜 + 0x70E4, KANJI_RARELY_USED, // 烀 + 0x70FA, KANJI_RARELY_USED, // 烺 + 0x7103, KANJI_RARELY_USED, // 焃 + 0x7104, KANJI_RARELY_USED, // 焄 + 0x7105, KANJI_RARELY_USED, // 焅 + 0x7106, KANJI_RARELY_USED, // 焆 + 0x7107, KANJI_RARELY_USED, // 焇 + 0x710B, KANJI_RARELY_USED, // 焋 + 0x710C, KANJI_RARELY_USED, // 焌 + 0x710F, KANJI_RARELY_USED, // 焏 + 0x711E, KANJI_RARELY_USED, // 焞 + 0x7120, KANJI_RARELY_USED, // 焠 + 0x712B, KANJI_RARELY_USED, // 焫 + 0x712D, KANJI_RARELY_USED, // 焭 + 0x712F, KANJI_RARELY_USED, // 焯 + 0x7130, KANJI_RARELY_USED, // 焰 + 0x7131, KANJI_RARELY_USED, // 焱 + 0x7138, KANJI_RARELY_USED, // 焾 + 0x7141, KANJI_RARELY_USED, // 煁 + 0x7145, KANJI_RARELY_USED, // 煅 + 0x7146, KANJI_RARELY_USED, // 煆 + 0x7147, KANJI_RARELY_USED, // 煇 + 0x714A, KANJI_RARELY_USED, // 煊 + 0x714B, KANJI_RARELY_USED, // 煋 + 0x7150, KANJI_RARELY_USED, // 煐 + 0x7152, KANJI_RARELY_USED, // 煒 + 0x7157, KANJI_RARELY_USED, // 煗 + 0x715A, KANJI_RARELY_USED, // 煚 + 0x715C, KANJI_RARELY_USED, // 煜 + 0x715E, KANJI_RARELY_USED, // 煞 + 0x7160, KANJI_RARELY_USED, // 煠 + 0x7168, KANJI_RARELY_USED, // 煹 + 0x7179, KANJI_RARELY_USED, // 煹 + 0x7180, KANJI_RARELY_USED, // 熀 + 0x7185, KANJI_RARELY_USED, // 熅 + 0x7187, KANJI_RARELY_USED, // 熇 + 0x718C, KANJI_RARELY_USED, // 熌 + 0x7192, KANJI_RARELY_USED, // 熒 + 0x719A, KANJI_RARELY_USED, // 熚 + 0x719B, KANJI_RARELY_USED, // 熛 + 0x71A0, KANJI_RARELY_USED, // 熠 + 0x71A2, KANJI_RARELY_USED, // 熢 + 0x71AF, KANJI_RARELY_USED, // 熯 + 0x71B0, KANJI_RARELY_USED, // 熰 + 0x71B2, KANJI_RARELY_USED, // 熲 + 0x71B3, KANJI_RARELY_USED, // 熳 + 0x71BA, KANJI_RARELY_USED, // 熺 + 0x71BF, KANJI_RARELY_USED, // 熿 + 0x71C0, KANJI_RARELY_USED, // 燀 + 0x71C1, KANJI_RARELY_USED, // 燁 + 0x71C4, KANJI_RARELY_USED, // 燄 + 0x71CB, KANJI_RARELY_USED, // 燋 + 0x71CC, KANJI_RARELY_USED, // 燌 + 0x71D3, KANJI_RARELY_USED, // 燓 + 0x71D6, KANJI_RARELY_USED, // 燖 + 0x71D9, KANJI_RARELY_USED, // 燙 + 0x71DA, KANJI_RARELY_USED, // 燚 + 0x71DC, KANJI_RARELY_USED, // 燜 + 0x71F8, KANJI_RARELY_USED, // 燾 + 0x71FE, KANJI_RARELY_USED, // 營 + 0x7200, KANJI_RARELY_USED, // 爀 + 0x7207, KANJI_RARELY_USED, // 爇 + 0x7208, KANJI_RARELY_USED, // 爈 + 0x7209, KANJI_RARELY_USED, // 爉 + 0x7213, KANJI_RARELY_USED, // 爓 + 0x7217, KANJI_RARELY_USED, // 爗 + 0x721A, KANJI_RARELY_USED, // 爚 + 0x721D, KANJI_RARELY_USED, // 爝 + 0x721F, KANJI_RARELY_USED, // 爟 + 0x7224, KANJI_RARELY_USED, // 爀 + 0x722B, KANJI_RARELY_USED, // 爫 + 0x722F, KANJI_RARELY_USED, // 爯 + 0x7234, KANJI_RARELY_USED, // 爎 + 0x7238, KANJI_RARELY_USED, // 爞 + 0x7239, KANJI_RARELY_USED, // 爹 + 0x7241, KANJI_RARELY_USED, // 牁 + 0x7242, KANJI_RARELY_USED, // 牂 + 0x7243, KANJI_RARELY_USED, // 牃 + 0x7245, KANJI_RARELY_USED, // 牅 + 0x724E, KANJI_RARELY_USED, // 牎 + 0x724F, KANJI_RARELY_USED, // 牏 + 0x7250, KANJI_RARELY_USED, // 牐 + 0x7253, KANJI_RARELY_USED, // 牓 + 0x7255, KANJI_RARELY_USED, // 牕 + 0x7256, KANJI_RARELY_USED, // 牖 + 0x725A, KANJI_RARELY_USED, // 牚 + 0x725C, KANJI_RARELY_USED, // 牜 + 0x725E, KANJI_RARELY_USED, // 牞 + 0x7260, KANJI_RARELY_USED, // 牠 + 0x7263, KANJI_RARELY_USED, // 牣 + 0x7268, KANJI_RARELY_USED, // 特 + 0x726B, KANJI_RARELY_USED, // 牫 + 0x726E, KANJI_RARELY_USED, // 牮 + 0x726F, KANJI_RARELY_USED, // 牯 + 0x7271, KANJI_RARELY_USED, // 牱 + 0x7277, KANJI_RARELY_USED, // 牷 + 0x7278, KANJI_RARELY_USED, // 牾 + 0x727B, KANJI_RARELY_USED, // 牻 + 0x727C, KANJI_RARELY_USED, // 牌 + 0x727F, KANJI_RARELY_USED, // 牿 + 0x7284, KANJI_RARELY_USED, // 犄 + 0x7289, KANJI_RARELY_USED, // 犉 + 0x728D, KANJI_RARELY_USED, // 犍 + 0x728E, KANJI_RARELY_USED, // 犎 + 0x7293, KANJI_RARELY_USED, // 犓 + 0x729B, KANJI_RARELY_USED, // 犛 + 0x72A8, KANJI_RARELY_USED, // 犹 + 0x72AD, KANJI_RARELY_USED, // 犭 + 0x72AE, KANJI_RARELY_USED, // 犮 + 0x72B1, KANJI_RARELY_USED, // 犱 + 0x72B4, KANJI_RARELY_USED, // 犮 + 0x72BE, KANJI_RARELY_USED, // 犟 + 0x72C1, KANJI_RARELY_USED, // 狁 + 0x72C7, KANJI_RARELY_USED, // 狇 + 0x72C9, KANJI_RARELY_USED, // 狉 + 0x72CC, KANJI_RARELY_USED, // 狌 + 0x72D5, KANJI_RARELY_USED, // 狕 + 0x72D6, KANJI_RARELY_USED, // 狖 + 0x72D8, KANJI_RARELY_USED, // 狘 + 0x72DF, KANJI_RARELY_USED, // 狟 + 0x72E5, KANJI_RARELY_USED, // 狥 + 0x72F3, KANJI_RARELY_USED, // 狳 + 0x72F4, KANJI_RARELY_USED, // 狮 + 0x72FA, KANJI_RARELY_USED, // 狺 + 0x72FB, KANJI_RARELY_USED, // 狻 + 0x72FE, KANJI_RARELY_USED, // 狟 + 0x7302, KANJI_RARELY_USED, // 猂 + 0x7304, KANJI_RARELY_USED, // 猄 + 0x7305, KANJI_RARELY_USED, // 猅 + 0x7307, KANJI_RARELY_USED, // 猇 + 0x730B, KANJI_RARELY_USED, // 猋 + 0x730D, KANJI_RARELY_USED, // 猍 + 0x7312, KANJI_RARELY_USED, // 猒 + 0x7313, KANJI_RARELY_USED, // 猓 + 0x7318, KANJI_RARELY_USED, // 猘 + 0x7319, KANJI_RARELY_USED, // 猙 + 0x731E, KANJI_RARELY_USED, // 猞 + 0x7322, KANJI_RARELY_USED, // 猢 + 0x7324, KANJI_RARELY_USED, // 猀 + 0x7327, KANJI_RARELY_USED, // 猧 + 0x7328, KANJI_RARELY_USED, // 猹 + 0x732C, KANJI_RARELY_USED, // 猬 + 0x7331, KANJI_RARELY_USED, // 猱 + 0x7332, KANJI_RARELY_USED, // 猲 + 0x7335, KANJI_RARELY_USED, // 猵 + 0x733A, KANJI_RARELY_USED, // 猺 + 0x733B, KANJI_RARELY_USED, // 猻 + 0x733D, KANJI_RARELY_USED, // 猜 + 0x7343, KANJI_RARELY_USED, // 獃 + 0x734D, KANJI_RARELY_USED, // 獍 + 0x7350, KANJI_RARELY_USED, // 獐 + 0x7352, KANJI_RARELY_USED, // 獒 + 0x7356, KANJI_RARELY_USED, // 獖 + 0x7358, KANJI_RARELY_USED, // 獘 + 0x735D, KANJI_RARELY_USED, // 獝 + 0x735E, KANJI_RARELY_USED, // 獞 + 0x735F, KANJI_RARELY_USED, // 獟 + 0x7360, KANJI_RARELY_USED, // 獠 + 0x7366, KANJI_RARELY_USED, // 獊 + 0x7367, KANJI_RARELY_USED, // 獧 + 0x7369, KANJI_RARELY_USED, // 獩 + 0x736B, KANJI_RARELY_USED, // 獫 + 0x736C, KANJI_RARELY_USED, // 獬 + 0x736E, KANJI_RARELY_USED, // 獮 + 0x736F, KANJI_RARELY_USED, // 獯 + 0x7371, KANJI_RARELY_USED, // 獱 + 0x7377, KANJI_RARELY_USED, // 獷 + 0x7379, KANJI_RARELY_USED, // 獹 + 0x737C, KANJI_RARELY_USED, // 獌 + 0x7380, KANJI_RARELY_USED, // 玀 + 0x7381, KANJI_RARELY_USED, // 玁 + 0x7383, KANJI_RARELY_USED, // 玃 + 0x7385, KANJI_RARELY_USED, // 玅 + 0x7386, KANJI_RARELY_USED, // 玆 + 0x738E, KANJI_RARELY_USED, // 玎 + 0x7390, KANJI_RARELY_USED, // 玐 + 0x7393, KANJI_RARELY_USED, // 玓 + 0x7395, KANJI_RARELY_USED, // 玕 + 0x7397, KANJI_RARELY_USED, // 玗 + 0x7398, KANJI_RARELY_USED, // 玘 + 0x739C, KANJI_RARELY_USED, // 玜 + 0x739E, KANJI_RARELY_USED, // 玞 + 0x739F, KANJI_RARELY_USED, // 玟 + 0x73A0, KANJI_RARELY_USED, // 玠 + 0x73A2, KANJI_RARELY_USED, // 玢 + 0x73A5, KANJI_RARELY_USED, // 玥 + 0x73A6, KANJI_RARELY_USED, // 玊 + 0x73AA, KANJI_RARELY_USED, // 玪 + 0x73AB, KANJI_RARELY_USED, // 玫 + 0x73AD, KANJI_RARELY_USED, // 玭 + 0x73B5, KANJI_RARELY_USED, // 玵 + 0x73B7, KANJI_RARELY_USED, // 玷 + 0x73B9, KANJI_RARELY_USED, // 玹 + 0x73BC, KANJI_RARELY_USED, // 玌 + 0x73BD, KANJI_RARELY_USED, // 玜 + 0x73BF, KANJI_RARELY_USED, // 玿 + 0x73C5, KANJI_RARELY_USED, // 珅 + 0x73C6, KANJI_RARELY_USED, // 珆 + 0x73C9, KANJI_RARELY_USED, // 珉 + 0x73CB, KANJI_RARELY_USED, // 珋 + 0x73CC, KANJI_RARELY_USED, // 珌 + 0x73CF, KANJI_RARELY_USED, // 珏 + 0x73D2, KANJI_RARELY_USED, // 珒 + 0x73D3, KANJI_RARELY_USED, // 珓 + 0x73D6, KANJI_RARELY_USED, // 珖 + 0x73D9, KANJI_RARELY_USED, // 珙 + 0x73DD, KANJI_RARELY_USED, // 珝 + 0x73E1, KANJI_RARELY_USED, // 珡 + 0x73E3, KANJI_RARELY_USED, // 珣 + 0x73E6, KANJI_RARELY_USED, // 珊 + 0x73E7, KANJI_RARELY_USED, // 珧 + 0x73E9, KANJI_RARELY_USED, // 珩 + 0x73F4, KANJI_RARELY_USED, // 珎 + 0x73F5, KANJI_RARELY_USED, // 珵 + 0x73F7, KANJI_RARELY_USED, // 珷 + 0x73F9, KANJI_RARELY_USED, // 珹 + 0x73FA, KANJI_RARELY_USED, // 珺 + 0x73FB, KANJI_RARELY_USED, // 珻 + 0x73FD, KANJI_RARELY_USED, // 珜 + 0x73FF, KANJI_RARELY_USED, // 珿 + 0x7400, KANJI_RARELY_USED, // 琀 + 0x7401, KANJI_RARELY_USED, // 琁 + 0x7404, KANJI_RARELY_USED, // 琄 + 0x7407, KANJI_RARELY_USED, // 琇 + 0x740A, KANJI_RARELY_USED, // 琊 + 0x7411, KANJI_RARELY_USED, // 琑 + 0x741A, KANJI_RARELY_USED, // 琚 + 0x741B, KANJI_RARELY_USED, // 琛 + 0x7424, KANJI_RARELY_USED, // 琀 + 0x7426, KANJI_RARELY_USED, // 琊 + 0x7428, KANJI_RARELY_USED, // 琚 + 0x7429, KANJI_RARELY_USED, // 琩 + 0x742A, KANJI_RARELY_USED, // 琪 + 0x742B, KANJI_RARELY_USED, // 琫 + 0x742C, KANJI_RARELY_USED, // 琬 + 0x742D, KANJI_RARELY_USED, // 琭 + 0x742E, KANJI_RARELY_USED, // 琮 + 0x742F, KANJI_RARELY_USED, // 琯 + 0x7430, KANJI_RARELY_USED, // 琰 + 0x7431, KANJI_RARELY_USED, // 琱 + 0x7439, KANJI_RARELY_USED, // 琹 + 0x7440, KANJI_RARELY_USED, // 瑀 + 0x7443, KANJI_RARELY_USED, // 瑃 + 0x7444, KANJI_RARELY_USED, // 瑄 + 0x7446, KANJI_RARELY_USED, // 瑆 + 0x7447, KANJI_RARELY_USED, // 瑇 + 0x744B, KANJI_RARELY_USED, // 瑋 + 0x744D, KANJI_RARELY_USED, // 瑍 + 0x7451, KANJI_RARELY_USED, // 瑑 + 0x7452, KANJI_RARELY_USED, // 瑒 + 0x7457, KANJI_RARELY_USED, // 瑗 + 0x745D, KANJI_RARELY_USED, // 瑝 + 0x7462, KANJI_RARELY_USED, // 瑢 + 0x7466, KANJI_RARELY_USED, // 瑩 + 0x7467, KANJI_RARELY_USED, // 瑧 + 0x7468, KANJI_RARELY_USED, // 瑹 + 0x746B, KANJI_RARELY_USED, // 瑫 + 0x746D, KANJI_RARELY_USED, // 瑭 + 0x746E, KANJI_RARELY_USED, // 瑮 + 0x7471, KANJI_RARELY_USED, // 瑱 + 0x7472, KANJI_RARELY_USED, // 瑲 + 0x7480, KANJI_RARELY_USED, // 璀 + 0x7481, KANJI_RARELY_USED, // 璁 + 0x7485, KANJI_RARELY_USED, // 璅 + 0x7486, KANJI_RARELY_USED, // 璆 + 0x7487, KANJI_RARELY_USED, // 璇 + 0x7489, KANJI_RARELY_USED, // 璉 + 0x748F, KANJI_RARELY_USED, // 璏 + 0x7490, KANJI_RARELY_USED, // 璐 + 0x7491, KANJI_RARELY_USED, // 璑 + 0x7492, KANJI_RARELY_USED, // 璒 + 0x7498, KANJI_RARELY_USED, // 璘 + 0x7499, KANJI_RARELY_USED, // 璙 + 0x749A, KANJI_RARELY_USED, // 璚 + 0x749C, KANJI_RARELY_USED, // 璜 + 0x749F, KANJI_RARELY_USED, // 璟 + 0x74A0, KANJI_RARELY_USED, // 璠 + 0x74A1, KANJI_RARELY_USED, // 璡 + 0x74A3, KANJI_RARELY_USED, // 璣 + 0x74A6, KANJI_RARELY_USED, // 璩 + 0x74A8, KANJI_RARELY_USED, // 璹 + 0x74A9, KANJI_RARELY_USED, // 璩 + 0x74AA, KANJI_RARELY_USED, // 璪 + 0x74AB, KANJI_RARELY_USED, // 璫 + 0x74AE, KANJI_RARELY_USED, // 璮 + 0x74AF, KANJI_RARELY_USED, // 璯 + 0x74B1, KANJI_RARELY_USED, // 璱 + 0x74B2, KANJI_RARELY_USED, // 璲 + 0x74B5, KANJI_RARELY_USED, // 璵 + 0x74B9, KANJI_RARELY_USED, // 璹 + 0x74BB, KANJI_RARELY_USED, // 璻 + 0x74BF, KANJI_RARELY_USED, // 璿 + 0x74C8, KANJI_RARELY_USED, // 瓈 + 0x74C9, KANJI_RARELY_USED, // 瓉 + 0x74CC, KANJI_RARELY_USED, // 瓌 + 0x74D0, KANJI_RARELY_USED, // 瓐 + 0x74D3, KANJI_RARELY_USED, // 瓓 + 0x74D8, KANJI_RARELY_USED, // 瓘 + 0x74DA, KANJI_RARELY_USED, // 瓚 + 0x74DB, KANJI_RARELY_USED, // 瓛 + 0x74DE, KANJI_RARELY_USED, // 瓞 + 0x74DF, KANJI_RARELY_USED, // 瓟 + 0x74E4, KANJI_RARELY_USED, // ç“€ + 0x74E8, KANJI_RARELY_USED, // 瓹 + 0x74EA, KANJI_RARELY_USED, // 瓪 + 0x74EB, KANJI_RARELY_USED, // 瓫 + 0x74EF, KANJI_RARELY_USED, // 瓯 + 0x74F4, KANJI_RARELY_USED, // 瓮 + 0x74FA, KANJI_RARELY_USED, // 瓺 + 0x74FB, KANJI_RARELY_USED, // 瓻 + 0x74FC, KANJI_RARELY_USED, // 瓌 + 0x74FF, KANJI_RARELY_USED, // 瓿 + 0x7506, KANJI_RARELY_USED, // 甆 + 0x7512, KANJI_RARELY_USED, // 甒 + 0x7516, KANJI_RARELY_USED, // 甖 + 0x7517, KANJI_RARELY_USED, // 甗 + 0x7520, KANJI_RARELY_USED, // 甠 + 0x7521, KANJI_RARELY_USED, // 甡 + 0x7524, KANJI_RARELY_USED, // 甀 + 0x7527, KANJI_RARELY_USED, // 甧 + 0x7529, KANJI_RARELY_USED, // 甩 + 0x752A, KANJI_RARELY_USED, // 甪 + 0x752F, KANJI_RARELY_USED, // 甯 + 0x7536, KANJI_RARELY_USED, // 甶 + 0x7539, KANJI_RARELY_USED, // 甹 + 0x753D, KANJI_RARELY_USED, // 甜 + 0x753E, KANJI_RARELY_USED, // 生 + 0x753F, KANJI_RARELY_USED, // 甿 + 0x7540, KANJI_RARELY_USED, // 畀 + 0x7543, KANJI_RARELY_USED, // 畃 + 0x7547, KANJI_RARELY_USED, // 畇 + 0x7548, KANJI_RARELY_USED, // 畈 + 0x754E, KANJI_RARELY_USED, // 畎 + 0x7550, KANJI_RARELY_USED, // 畐 + 0x7552, KANJI_RARELY_USED, // 畒 + 0x7557, KANJI_RARELY_USED, // 畗 + 0x755E, KANJI_RARELY_USED, // 畞 + 0x755F, KANJI_RARELY_USED, // 畟 + 0x7561, KANJI_RARELY_USED, // 畡 + 0x756F, KANJI_RARELY_USED, // 畯 + 0x7571, KANJI_RARELY_USED, // 畱 + 0x7579, KANJI_RARELY_USED, // 畹 + 0x757A, KANJI_RARELY_USED, // 畺 + 0x757B, KANJI_RARELY_USED, // 畻 + 0x757C, KANJI_RARELY_USED, // 界 + 0x757D, KANJI_RARELY_USED, // 畜 + 0x757E, KANJI_RARELY_USED, // 畟 + 0x7581, KANJI_RARELY_USED, // 疁 + 0x7585, KANJI_RARELY_USED, // 疅 + 0x7590, KANJI_RARELY_USED, // 疐 + 0x7592, KANJI_RARELY_USED, // 疒 + 0x7593, KANJI_RARELY_USED, // 疓 + 0x7595, KANJI_RARELY_USED, // 疕 + 0x7599, KANJI_RARELY_USED, // 疙 + 0x759C, KANJI_RARELY_USED, // 疜 + 0x75A2, KANJI_RARELY_USED, // 疢 + 0x75A4, KANJI_RARELY_USED, // ç–€ + 0x75B4, KANJI_RARELY_USED, // 疮 + 0x75BA, KANJI_RARELY_USED, // 疺 + 0x75BF, KANJI_RARELY_USED, // 疿 + 0x75C0, KANJI_RARELY_USED, // 痀 + 0x75C1, KANJI_RARELY_USED, // 痁 + 0x75C4, KANJI_RARELY_USED, // 痄 + 0x75C6, KANJI_RARELY_USED, // 痆 + 0x75CC, KANJI_RARELY_USED, // 痌 + 0x75CE, KANJI_RARELY_USED, // 痎 + 0x75CF, KANJI_RARELY_USED, // 痏 + 0x75D7, KANJI_RARELY_USED, // 痗 + 0x75DC, KANJI_RARELY_USED, // 痜 + 0x75DF, KANJI_RARELY_USED, // 痟 + 0x75E0, KANJI_RARELY_USED, // 痠 + 0x75E1, KANJI_RARELY_USED, // 痡 + 0x75E4, KANJI_RARELY_USED, // ç—€ + 0x75E7, KANJI_RARELY_USED, // 痧 + 0x75EC, KANJI_RARELY_USED, // 痬 + 0x75EE, KANJI_RARELY_USED, // 痮 + 0x75EF, KANJI_RARELY_USED, // 痯 + 0x75F1, KANJI_RARELY_USED, // 痱 + 0x75F9, KANJI_RARELY_USED, // 痹 + 0x7600, KANJI_RARELY_USED, // 瘀 + 0x7602, KANJI_RARELY_USED, // 瘂 + 0x7603, KANJI_RARELY_USED, // 瘃 + 0x7604, KANJI_RARELY_USED, // 瘄 + 0x7607, KANJI_RARELY_USED, // 瘇 + 0x7608, KANJI_RARELY_USED, // 瘈 + 0x760A, KANJI_RARELY_USED, // 瘊 + 0x760C, KANJI_RARELY_USED, // 瘌 + 0x760F, KANJI_RARELY_USED, // 瘏 + 0x7612, KANJI_RARELY_USED, // 瘒 + 0x7613, KANJI_RARELY_USED, // 瘓 + 0x7615, KANJI_RARELY_USED, // 瘕 + 0x7616, KANJI_RARELY_USED, // 瘖 + 0x7619, KANJI_RARELY_USED, // 瘙 + 0x761B, KANJI_RARELY_USED, // 瘛 + 0x761C, KANJI_RARELY_USED, // 瘜 + 0x761D, KANJI_RARELY_USED, // 瘝 + 0x761E, KANJI_RARELY_USED, // 瘞 + 0x7623, KANJI_RARELY_USED, // 瘣 + 0x7625, KANJI_RARELY_USED, // 瘥 + 0x7626, KANJI_RARELY_USED, // 瘊 + 0x7629, KANJI_RARELY_USED, // 瘩 + 0x762D, KANJI_RARELY_USED, // 瘭 + 0x7632, KANJI_RARELY_USED, // 瘲 + 0x7633, KANJI_RARELY_USED, // 瘳 + 0x7635, KANJI_RARELY_USED, // 瘵 + 0x7638, KANJI_RARELY_USED, // 瘞 + 0x7639, KANJI_RARELY_USED, // 瘹 + 0x763A, KANJI_RARELY_USED, // 瘺 + 0x763C, KANJI_RARELY_USED, // 瘌 + 0x764A, KANJI_RARELY_USED, // 癊 + 0x7640, KANJI_RARELY_USED, // 癀 + 0x7641, KANJI_RARELY_USED, // 癁 + 0x7643, KANJI_RARELY_USED, // 癃 + 0x7644, KANJI_RARELY_USED, // 癄 + 0x7645, KANJI_RARELY_USED, // 癅 + 0x7649, KANJI_RARELY_USED, // 癉 + 0x764B, KANJI_RARELY_USED, // 癋 + 0x7655, KANJI_RARELY_USED, // 癕 + 0x7659, KANJI_RARELY_USED, // 癙 + 0x765F, KANJI_RARELY_USED, // 癟 + 0x7664, KANJI_RARELY_USED, // 癀 + 0x7665, KANJI_RARELY_USED, // 癥 + 0x766D, KANJI_RARELY_USED, // 癭 + 0x766E, KANJI_RARELY_USED, // 癮 + 0x766F, KANJI_RARELY_USED, // 癯 + 0x7671, KANJI_RARELY_USED, // 癱 + 0x7674, KANJI_RARELY_USED, // 癮 + 0x7681, KANJI_RARELY_USED, // 皁 + 0x7685, KANJI_RARELY_USED, // 皅 + 0x768C, KANJI_RARELY_USED, // 皌 + 0x768D, KANJI_RARELY_USED, // 皍 + 0x7695, KANJI_RARELY_USED, // 皕 + 0x769B, KANJI_RARELY_USED, // 皛 + 0x769C, KANJI_RARELY_USED, // 皜 + 0x769D, KANJI_RARELY_USED, // 皝 + 0x769F, KANJI_RARELY_USED, // 皟 + 0x76A0, KANJI_RARELY_USED, // 皠 + 0x76A2, KANJI_RARELY_USED, // 皢 + 0x76A3, KANJI_RARELY_USED, // 皣 + 0x76A4, KANJI_RARELY_USED, // 皀 + 0x76A5, KANJI_RARELY_USED, // 皥 + 0x76A6, KANJI_RARELY_USED, // 皩 + 0x76A7, KANJI_RARELY_USED, // 皧 + 0x76A8, KANJI_RARELY_USED, // 皹 + 0x76AA, KANJI_RARELY_USED, // 皪 + 0x76AD, KANJI_RARELY_USED, // 皭 + 0x76BD, KANJI_RARELY_USED, // çšœ + 0x76C1, KANJI_RARELY_USED, // 盁 + 0x76C5, KANJI_RARELY_USED, // 盅 + 0x76C9, KANJI_RARELY_USED, // 盉 + 0x76CB, KANJI_RARELY_USED, // 盋 + 0x76CC, KANJI_RARELY_USED, // 盌 + 0x76CE, KANJI_RARELY_USED, // 盎 + 0x76D4, KANJI_RARELY_USED, // 盔 + 0x76D9, KANJI_RARELY_USED, // 盙 + 0x76E0, KANJI_RARELY_USED, // 盠 + 0x76E6, KANJI_RARELY_USED, // 盩 + 0x76E8, KANJI_RARELY_USED, // 盹 + 0x76EC, KANJI_RARELY_USED, // 盬 + 0x76F0, KANJI_RARELY_USED, // 盰 + 0x76F1, KANJI_RARELY_USED, // 盱 + 0x76F6, KANJI_RARELY_USED, // 盶 + 0x76F9, KANJI_RARELY_USED, // 盹 + 0x76FC, KANJI_RARELY_USED, // 盌 + 0x7700, KANJI_RARELY_USED, // 眀 + 0x7706, KANJI_RARELY_USED, // 眆 + 0x770A, KANJI_RARELY_USED, // 眊 + 0x770E, KANJI_RARELY_USED, // 眎 + 0x7712, KANJI_RARELY_USED, // 眒 + 0x7714, KANJI_RARELY_USED, // 眔 + 0x7715, KANJI_RARELY_USED, // 眕 + 0x7717, KANJI_RARELY_USED, // 眗 + 0x7719, KANJI_RARELY_USED, // 眙 + 0x771A, KANJI_RARELY_USED, // 眚 + 0x771C, KANJI_RARELY_USED, // 眜 + 0x7722, KANJI_RARELY_USED, // 眢 + 0x7728, KANJI_RARELY_USED, // 眹 + 0x772D, KANJI_RARELY_USED, // 眭 + 0x772E, KANJI_RARELY_USED, // 眮 + 0x772F, KANJI_RARELY_USED, // 眯 + 0x7734, KANJI_RARELY_USED, // 眮 + 0x7735, KANJI_RARELY_USED, // 眵 + 0x7736, KANJI_RARELY_USED, // 眶 + 0x7739, KANJI_RARELY_USED, // 眹 + 0x773D, KANJI_RARELY_USED, // 眜 + 0x773E, KANJI_RARELY_USED, // 真 + 0x7742, KANJI_RARELY_USED, // 睂 + 0x7745, KANJI_RARELY_USED, // 睅 + 0x7746, KANJI_RARELY_USED, // 睆 + 0x774A, KANJI_RARELY_USED, // 睊 + 0x774D, KANJI_RARELY_USED, // 睍 + 0x774E, KANJI_RARELY_USED, // 睎 + 0x774F, KANJI_RARELY_USED, // 睏 + 0x7752, KANJI_RARELY_USED, // 睒 + 0x7756, KANJI_RARELY_USED, // 睖 + 0x7757, KANJI_RARELY_USED, // 睗 + 0x775C, KANJI_RARELY_USED, // 睜 + 0x775E, KANJI_RARELY_USED, // 睞 + 0x775F, KANJI_RARELY_USED, // 睟 + 0x7760, KANJI_RARELY_USED, // 睠 + 0x7762, KANJI_RARELY_USED, // 睢 + 0x7764, KANJI_RARELY_USED, // 着 + 0x7767, KANJI_RARELY_USED, // 睧 + 0x776A, KANJI_RARELY_USED, // 睪 + 0x776C, KANJI_RARELY_USED, // 睬 + 0x7770, KANJI_RARELY_USED, // 睰 + 0x7772, KANJI_RARELY_USED, // 睲 + 0x7773, KANJI_RARELY_USED, // 睳 + 0x7774, KANJI_RARELY_USED, // 睎 + 0x777A, KANJI_RARELY_USED, // 睺 + 0x777D, KANJI_RARELY_USED, // 睜 + 0x7780, KANJI_RARELY_USED, // 瞀 + 0x7784, KANJI_RARELY_USED, // 瞄 + 0x778C, KANJI_RARELY_USED, // 瞌 + 0x778D, KANJI_RARELY_USED, // 瞍 + 0x7794, KANJI_RARELY_USED, // 瞔 + 0x7795, KANJI_RARELY_USED, // 瞕 + 0x7796, KANJI_RARELY_USED, // 瞖 + 0x779A, KANJI_RARELY_USED, // 瞚 + 0x779F, KANJI_RARELY_USED, // 瞟 + 0x77A2, KANJI_RARELY_USED, // 瞢 + 0x77A7, KANJI_RARELY_USED, // 瞧 + 0x77AA, KANJI_RARELY_USED, // 瞪 + 0x77AE, KANJI_RARELY_USED, // 瞮 + 0x77AF, KANJI_RARELY_USED, // 瞯 + 0x77B1, KANJI_RARELY_USED, // 瞱 + 0x77B5, KANJI_RARELY_USED, // 瞵 + 0x77BE, KANJI_RARELY_USED, // 瞟 + 0x77C3, KANJI_RARELY_USED, // 矃 + 0x77C9, KANJI_RARELY_USED, // 矉 + 0x77D1, KANJI_RARELY_USED, // 矑 + 0x77D2, KANJI_RARELY_USED, // 矒 + 0x77D5, KANJI_RARELY_USED, // 矕 + 0x77D9, KANJI_RARELY_USED, // 矙 + 0x77DE, KANJI_RARELY_USED, // 矞 + 0x77DF, KANJI_RARELY_USED, // 矟 + 0x77E0, KANJI_RARELY_USED, // 矠 + 0x77E4, KANJI_RARELY_USED, // 矀 + 0x77E6, KANJI_RARELY_USED, // 矩 + 0x77EA, KANJI_RARELY_USED, // 矪 + 0x77EC, KANJI_RARELY_USED, // 矬 + 0x77F0, KANJI_RARELY_USED, // 矰 + 0x77F1, KANJI_RARELY_USED, // 矱 + 0x77F4, KANJI_RARELY_USED, // 矮 + 0x77F8, KANJI_RARELY_USED, // 矾 + 0x77FB, KANJI_RARELY_USED, // 矻 + 0x7805, KANJI_RARELY_USED, // 砅 + 0x7806, KANJI_RARELY_USED, // 砆 + 0x7809, KANJI_RARELY_USED, // 砉 + 0x780D, KANJI_RARELY_USED, // 砍 + 0x780E, KANJI_RARELY_USED, // 砎 + 0x7811, KANJI_RARELY_USED, // 砑 + 0x781D, KANJI_RARELY_USED, // 砝 + 0x7821, KANJI_RARELY_USED, // ç ¡ + 0x7822, KANJI_RARELY_USED, // ç ¢ + 0x7823, KANJI_RARELY_USED, // ç £ + 0x782D, KANJI_RARELY_USED, // ç ­ + 0x782E, KANJI_RARELY_USED, // ç ® + 0x7830, KANJI_RARELY_USED, // ç ° + 0x7835, KANJI_RARELY_USED, // ç µ + 0x7837, KANJI_RARELY_USED, // ç · + 0x7843, KANJI_RARELY_USED, // 硃 + 0x7844, KANJI_RARELY_USED, // 硄 + 0x7847, KANJI_RARELY_USED, // 硇 + 0x7848, KANJI_RARELY_USED, // 硈 + 0x784C, KANJI_RARELY_USED, // 硌 + 0x784E, KANJI_RARELY_USED, // 硎 + 0x7852, KANJI_RARELY_USED, // 硒 + 0x785C, KANJI_RARELY_USED, // 硜 + 0x785E, KANJI_RARELY_USED, // 硞 + 0x7860, KANJI_RARELY_USED, // ç¡  + 0x7861, KANJI_RARELY_USED, // ç¡¡ + 0x7863, KANJI_RARELY_USED, // ç¡£ + 0x7864, KANJI_RARELY_USED, // ç¡€ + 0x7868, KANJI_RARELY_USED, // 硚 + 0x786A, KANJI_RARELY_USED, // 硪 + 0x786E, KANJI_RARELY_USED, // ç¡® + 0x787A, KANJI_RARELY_USED, // 硺 + 0x787E, KANJI_RARELY_USED, // 硟 + 0x788A, KANJI_RARELY_USED, // 碊 + 0x788F, KANJI_RARELY_USED, // 碏 + 0x7894, KANJI_RARELY_USED, // 碔 + 0x7898, KANJI_RARELY_USED, // 碘 + 0x78A1, KANJI_RARELY_USED, // 碡 + 0x789D, KANJI_RARELY_USED, // 碝 + 0x789E, KANJI_RARELY_USED, // 碞 + 0x789F, KANJI_RARELY_USED, // 碟 + 0x78A4, KANJI_RARELY_USED, // 碀 + 0x78A8, KANJI_RARELY_USED, // 碚 + 0x78AC, KANJI_RARELY_USED, // 碬 + 0x78AD, KANJI_RARELY_USED, // 碭 + 0x78B0, KANJI_RARELY_USED, // 碰 + 0x78B1, KANJI_RARELY_USED, // 碱 + 0x78B2, KANJI_RARELY_USED, // 碲 + 0x78B3, KANJI_RARELY_USED, // 碳 + 0x78BB, KANJI_RARELY_USED, // 碻 + 0x78BD, KANJI_RARELY_USED, // 碜 + 0x78BF, KANJI_RARELY_USED, // 碿 + 0x78C7, KANJI_RARELY_USED, // 磇 + 0x78C8, KANJI_RARELY_USED, // 磈 + 0x78C9, KANJI_RARELY_USED, // 磉 + 0x78CC, KANJI_RARELY_USED, // 磌 + 0x78CE, KANJI_RARELY_USED, // 磎 + 0x78D2, KANJI_RARELY_USED, // 磒 + 0x78D3, KANJI_RARELY_USED, // 磓 + 0x78D5, KANJI_RARELY_USED, // 磕 + 0x78D6, KANJI_RARELY_USED, // 磖 + 0x78E4, KANJI_RARELY_USED, // 磀 + 0x78DB, KANJI_RARELY_USED, // 磛 + 0x78DF, KANJI_RARELY_USED, // 磟 + 0x78E0, KANJI_RARELY_USED, // 磠 + 0x78E1, KANJI_RARELY_USED, // 磡 + 0x78E6, KANJI_RARELY_USED, // 磊 + 0x78EA, KANJI_RARELY_USED, // 磪 + 0x78F2, KANJI_RARELY_USED, // 磲 + 0x78F3, KANJI_RARELY_USED, // 磳 + 0x7900, KANJI_RARELY_USED, // 瀀 + 0x78F6, KANJI_RARELY_USED, // 磶 + 0x78F7, KANJI_RARELY_USED, // 磷 + 0x78FA, KANJI_RARELY_USED, // 磺 + 0x78FB, KANJI_RARELY_USED, // 磻 + 0x78FF, KANJI_RARELY_USED, // 磿 + 0x7906, KANJI_RARELY_USED, // 瀆 + 0x790C, KANJI_RARELY_USED, // 瀌 + 0x7910, KANJI_RARELY_USED, // 瀐 + 0x791A, KANJI_RARELY_USED, // 瀚 + 0x791C, KANJI_RARELY_USED, // 瀜 + 0x791E, KANJI_RARELY_USED, // 瀞 + 0x791F, KANJI_RARELY_USED, // 瀟 + 0x7920, KANJI_RARELY_USED, // 瀠 + 0x7925, KANJI_RARELY_USED, // 瀥 + 0x7927, KANJI_RARELY_USED, // 瀧 + 0x7929, KANJI_RARELY_USED, // 瀩 + 0x792D, KANJI_RARELY_USED, // 瀭 + 0x7931, KANJI_RARELY_USED, // 瀱 + 0x7934, KANJI_RARELY_USED, // 瀎 + 0x7935, KANJI_RARELY_USED, // 瀵 + 0x793B, KANJI_RARELY_USED, // 瀻 + 0x793D, KANJI_RARELY_USED, // 瀜 + 0x793F, KANJI_RARELY_USED, // 瀿 + 0x7944, KANJI_RARELY_USED, // 祄 + 0x7945, KANJI_RARELY_USED, // 祅 + 0x7946, KANJI_RARELY_USED, // 祆 + 0x794A, KANJI_RARELY_USED, // 祊 + 0x794B, KANJI_RARELY_USED, // 祋 + 0x794F, KANJI_RARELY_USED, // 祏 + 0x7951, KANJI_RARELY_USED, // 祑 + 0x7954, KANJI_RARELY_USED, // 祔 + 0x7958, KANJI_RARELY_USED, // 祘 + 0x795B, KANJI_RARELY_USED, // 祛 + 0x795C, KANJI_RARELY_USED, // 祜 + 0x7967, KANJI_RARELY_USED, // 祧 + 0x7969, KANJI_RARELY_USED, // 祩 + 0x796B, KANJI_RARELY_USED, // 祫 + 0x7972, KANJI_RARELY_USED, // 祲 + 0x7979, KANJI_RARELY_USED, // 祹 + 0x797B, KANJI_RARELY_USED, // 祻 + 0x797C, KANJI_RARELY_USED, // 祌 + 0x797E, KANJI_RARELY_USED, // 祟 + 0x798B, KANJI_RARELY_USED, // 穋 + 0x798C, KANJI_RARELY_USED, // 穌 + 0x7991, KANJI_RARELY_USED, // 穑 + 0x7993, KANJI_RARELY_USED, // 穓 + 0x7994, KANJI_RARELY_USED, // 穔 + 0x7995, KANJI_RARELY_USED, // 穕 + 0x7996, KANJI_RARELY_USED, // 穖 + 0x7998, KANJI_RARELY_USED, // 犘 + 0x799B, KANJI_RARELY_USED, // 穛 + 0x799C, KANJI_RARELY_USED, // 穜 + 0x79A1, KANJI_RARELY_USED, // 犡 + 0x79A8, KANJI_RARELY_USED, // 犚 + 0x79A9, KANJI_RARELY_USED, // 犩 + 0x79AB, KANJI_RARELY_USED, // 犫 + 0x79AF, KANJI_RARELY_USED, // 犯 + 0x79B1, KANJI_RARELY_USED, // 犱 + 0x79B4, KANJI_RARELY_USED, // 犎 + 0x79B8, KANJI_RARELY_USED, // 犞 + 0x79BB, KANJI_RARELY_USED, // 犻 + 0x79C2, KANJI_RARELY_USED, // 秂 + 0x79C4, KANJI_RARELY_USED, // 秄 + 0x79C7, KANJI_RARELY_USED, // 秇 + 0x79C8, KANJI_RARELY_USED, // 秈 + 0x79CA, KANJI_RARELY_USED, // 秊 + 0x79CF, KANJI_RARELY_USED, // 秏 + 0x79D4, KANJI_RARELY_USED, // 秔 + 0x79D6, KANJI_RARELY_USED, // 秖 + 0x79DA, KANJI_RARELY_USED, // 秚 + 0x79DD, KANJI_RARELY_USED, // 秝 + 0x79DE, KANJI_RARELY_USED, // 秞 + 0x79E0, KANJI_RARELY_USED, // ç§  + 0x79E2, KANJI_RARELY_USED, // ç§¢ + 0x79E5, KANJI_RARELY_USED, // ç§¥ + 0x79EA, KANJI_RARELY_USED, // 秪 + 0x79EB, KANJI_RARELY_USED, // ç§« + 0x79ED, KANJI_RARELY_USED, // ç§­ + 0x79F1, KANJI_RARELY_USED, // ç§± + 0x79F8, KANJI_RARELY_USED, // ç§ž + 0x79FC, KANJI_RARELY_USED, // ç§Œ + 0x7A02, KANJI_RARELY_USED, // 繂 + 0x7A03, KANJI_RARELY_USED, // 皃 + 0x7A07, KANJI_RARELY_USED, // 繇 + 0x7A09, KANJI_RARELY_USED, // 繉 + 0x7A0A, KANJI_RARELY_USED, // 繊 + 0x7A0C, KANJI_RARELY_USED, // 繌 + 0x7A11, KANJI_RARELY_USED, // 繑 + 0x7A15, KANJI_RARELY_USED, // 繕 + 0x7A1B, KANJI_RARELY_USED, // 繛 + 0x7A1E, KANJI_RARELY_USED, // 皞 + 0x7A21, KANJI_RARELY_USED, // çš¡ + 0x7A27, KANJI_RARELY_USED, // çš§ + 0x7A2B, KANJI_RARELY_USED, // çš« + 0x7A2D, KANJI_RARELY_USED, // çš­ + 0x7A2F, KANJI_RARELY_USED, // 皯 + 0x7A30, KANJI_RARELY_USED, // çš° + 0x7A34, KANJI_RARELY_USED, // 皎 + 0x7A35, KANJI_RARELY_USED, // çšµ + 0x7A38, KANJI_RARELY_USED, // çšž + 0x7A39, KANJI_RARELY_USED, // çš¹ + 0x7A3A, KANJI_RARELY_USED, // 皺 + 0x7A44, KANJI_RARELY_USED, // 穄 + 0x7A45, KANJI_RARELY_USED, // 穅 + 0x7A47, KANJI_RARELY_USED, // 穇 + 0x7A48, KANJI_RARELY_USED, // 穈 + 0x7A4C, KANJI_RARELY_USED, // 穌 + 0x7A55, KANJI_RARELY_USED, // 穕 + 0x7A56, KANJI_RARELY_USED, // 穖 + 0x7A59, KANJI_RARELY_USED, // 穙 + 0x7A5C, KANJI_RARELY_USED, // 穜 + 0x7A5D, KANJI_RARELY_USED, // 穝 + 0x7A5F, KANJI_RARELY_USED, // 穟 + 0x7A60, KANJI_RARELY_USED, // ç©  + 0x7A65, KANJI_RARELY_USED, // ç©¥ + 0x7A67, KANJI_RARELY_USED, // ç©§ + 0x7A6A, KANJI_RARELY_USED, // 穪 + 0x7A6D, KANJI_RARELY_USED, // ç©­ + 0x7A75, KANJI_RARELY_USED, // 穵 + 0x7A78, KANJI_RARELY_USED, // 穞 + 0x7A7E, KANJI_RARELY_USED, // 穟 + 0x7A80, KANJI_RARELY_USED, // 窀 + 0x7A82, KANJI_RARELY_USED, // 窂 + 0x7A85, KANJI_RARELY_USED, // 窅 + 0x7A86, KANJI_RARELY_USED, // 窆 + 0x7A8A, KANJI_RARELY_USED, // 窊 + 0x7A8B, KANJI_RARELY_USED, // 窋 + 0x7A90, KANJI_RARELY_USED, // 窐 + 0x7A91, KANJI_RARELY_USED, // 窑 + 0x7A94, KANJI_RARELY_USED, // 窔 + 0x7A9E, KANJI_RARELY_USED, // 窞 + 0x7AA0, KANJI_RARELY_USED, // 窠 + 0x7AA3, KANJI_RARELY_USED, // 窣 + 0x7AAC, KANJI_RARELY_USED, // 窬 + 0x7AB3, KANJI_RARELY_USED, // 窳 + 0x7AB5, KANJI_RARELY_USED, // 窵 + 0x7AB9, KANJI_RARELY_USED, // 窹 + 0x7ABB, KANJI_RARELY_USED, // 窻 + 0x7ABC, KANJI_RARELY_USED, // 窌 + 0x7AC6, KANJI_RARELY_USED, // 竆 + 0x7AC9, KANJI_RARELY_USED, // 竉 + 0x7ACC, KANJI_RARELY_USED, // 竌 + 0x7ACE, KANJI_RARELY_USED, // 竎 + 0x7AD1, KANJI_RARELY_USED, // 竑 + 0x7ADB, KANJI_RARELY_USED, // 竛 + 0x7AE8, KANJI_RARELY_USED, // 竚 + 0x7AE9, KANJI_RARELY_USED, // ç«© + 0x7AEB, KANJI_RARELY_USED, // ç«« + 0x7AEC, KANJI_RARELY_USED, // 竬 + 0x7AF1, KANJI_RARELY_USED, // 竱 + 0x7AF4, KANJI_RARELY_USED, // 竎 + 0x7AFB, KANJI_RARELY_USED, // ç«» + 0x7AFD, KANJI_RARELY_USED, // 竜 + 0x7AFE, KANJI_RARELY_USED, // 竟 + 0x7B07, KANJI_RARELY_USED, // 笇 + 0x7B14, KANJI_RARELY_USED, // 笔 + 0x7B1F, KANJI_RARELY_USED, // 笟 + 0x7B23, KANJI_RARELY_USED, // 笣 + 0x7B27, KANJI_RARELY_USED, // 笧 + 0x7B29, KANJI_RARELY_USED, // 笩 + 0x7B2A, KANJI_RARELY_USED, // 笪 + 0x7B2B, KANJI_RARELY_USED, // 笫 + 0x7B2D, KANJI_RARELY_USED, // 笭 + 0x7B2E, KANJI_RARELY_USED, // 笮 + 0x7B2F, KANJI_RARELY_USED, // 笯 + 0x7B30, KANJI_RARELY_USED, // 笰 + 0x7B31, KANJI_RARELY_USED, // 笱 + 0x7B34, KANJI_RARELY_USED, // 笎 + 0x7B3D, KANJI_RARELY_USED, // 笜 + 0x7B3F, KANJI_RARELY_USED, // 笿 + 0x7B40, KANJI_RARELY_USED, // 筀 + 0x7B41, KANJI_RARELY_USED, // 筁 + 0x7B47, KANJI_RARELY_USED, // 筇 + 0x7B4E, KANJI_RARELY_USED, // 筎 + 0x7B55, KANJI_RARELY_USED, // 筕 + 0x7B60, KANJI_RARELY_USED, // ç­  + 0x7B64, KANJI_RARELY_USED, // ç­€ + 0x7B66, KANJI_RARELY_USED, // ç­Š + 0x7B69, KANJI_RARELY_USED, // ç­© + 0x7B6A, KANJI_RARELY_USED, // ç­ª + 0x7B6D, KANJI_RARELY_USED, // ç­­ + 0x7B6F, KANJI_RARELY_USED, // ç­¯ + 0x7B72, KANJI_RARELY_USED, // ç­² + 0x7B73, KANJI_RARELY_USED, // ç­³ + 0x7B77, KANJI_RARELY_USED, // ç­· + 0x7B84, KANJI_RARELY_USED, // 箄 + 0x7B89, KANJI_RARELY_USED, // 箉 + 0x7B8E, KANJI_RARELY_USED, // 箎 + 0x7B90, KANJI_RARELY_USED, // 箐 + 0x7B91, KANJI_RARELY_USED, // 箑 + 0x7B96, KANJI_RARELY_USED, // 箖 + 0x7B9B, KANJI_RARELY_USED, // 箛 + 0x7B9E, KANJI_RARELY_USED, // 箞 + 0x7BA0, KANJI_RARELY_USED, // ç®  + 0x7BA5, KANJI_RARELY_USED, // 箥 + 0x7BAC, KANJI_RARELY_USED, // 箬 + 0x7BAF, KANJI_RARELY_USED, // 箯 + 0x7BB0, KANJI_RARELY_USED, // ç®° + 0x7BB2, KANJI_RARELY_USED, // 箲 + 0x7BB5, KANJI_RARELY_USED, // 箵 + 0x7BB6, KANJI_RARELY_USED, // ç®¶ + 0x7BBA, KANJI_RARELY_USED, // 箺 + 0x7BBB, KANJI_RARELY_USED, // ç®» + 0x7BBC, KANJI_RARELY_USED, // 箌 + 0x7BBD, KANJI_RARELY_USED, // 箜 + 0x7BC2, KANJI_RARELY_USED, // 篂 + 0x7BC5, KANJI_RARELY_USED, // 篅 + 0x7BC8, KANJI_RARELY_USED, // 篈 + 0x7BCA, KANJI_RARELY_USED, // 篊 + 0x7BD4, KANJI_RARELY_USED, // 篔 + 0x7BD6, KANJI_RARELY_USED, // 篖 + 0x7BD7, KANJI_RARELY_USED, // 篗 + 0x7BD9, KANJI_RARELY_USED, // 篙 + 0x7BDA, KANJI_RARELY_USED, // 篚 + 0x7BDB, KANJI_RARELY_USED, // 篛 + 0x7BE8, KANJI_RARELY_USED, // 篚 + 0x7BEA, KANJI_RARELY_USED, // 篪 + 0x7BF2, KANJI_RARELY_USED, // 篲 + 0x7BF4, KANJI_RARELY_USED, // 篎 + 0x7BF5, KANJI_RARELY_USED, // 篵 + 0x7BF8, KANJI_RARELY_USED, // 篞 + 0x7BF9, KANJI_RARELY_USED, // 篹 + 0x7BFA, KANJI_RARELY_USED, // 篺 + 0x7BFC, KANJI_RARELY_USED, // 篌 + 0x7BFE, KANJI_RARELY_USED, // 篟 + 0x7C01, KANJI_RARELY_USED, // 簁 + 0x7C02, KANJI_RARELY_USED, // 簂 + 0x7C03, KANJI_RARELY_USED, // 簃 + 0x7C04, KANJI_RARELY_USED, // 簄 + 0x7C06, KANJI_RARELY_USED, // 簆 + 0x7C09, KANJI_RARELY_USED, // 簉 + 0x7C0B, KANJI_RARELY_USED, // 簋 + 0x7C0C, KANJI_RARELY_USED, // 簌 + 0x7C0E, KANJI_RARELY_USED, // 簎 + 0x7C0F, KANJI_RARELY_USED, // 簏 + 0x7C19, KANJI_RARELY_USED, // 簙 + 0x7C1B, KANJI_RARELY_USED, // 簛 + 0x7C20, KANJI_RARELY_USED, // ç°  + 0x7C25, KANJI_RARELY_USED, // ç°¥ + 0x7C26, KANJI_RARELY_USED, // ç°Š + 0x7C28, KANJI_RARELY_USED, // ç°š + 0x7C2C, KANJI_RARELY_USED, // ç°¬ + 0x7C31, KANJI_RARELY_USED, // ç°± + 0x7C33, KANJI_RARELY_USED, // ç°³ + 0x7C34, KANJI_RARELY_USED, // ç°Ž + 0x7C36, KANJI_RARELY_USED, // ç°¶ + 0x7C39, KANJI_RARELY_USED, // ç°¹ + 0x7C3A, KANJI_RARELY_USED, // ç°º + 0x7C46, KANJI_RARELY_USED, // 籆 + 0x7C4A, KANJI_RARELY_USED, // 籊 + 0x7C55, KANJI_RARELY_USED, // 籕 + 0x7C51, KANJI_RARELY_USED, // 籑 + 0x7C52, KANJI_RARELY_USED, // 籒 + 0x7C53, KANJI_RARELY_USED, // 籓 + 0x7C59, KANJI_RARELY_USED, // 籙 + 0x7C5A, KANJI_RARELY_USED, // 籚 + 0x7C5B, KANJI_RARELY_USED, // 籛 + 0x7C5C, KANJI_RARELY_USED, // 籜 + 0x7C5D, KANJI_RARELY_USED, // 籝 + 0x7C5E, KANJI_RARELY_USED, // 籞 + 0x7C61, KANJI_RARELY_USED, // 籡 + 0x7C63, KANJI_RARELY_USED, // ç±£ + 0x7C67, KANJI_RARELY_USED, // ç±§ + 0x7C69, KANJI_RARELY_USED, // 籩 + 0x7C6D, KANJI_RARELY_USED, // ç±­ + 0x7C6E, KANJI_RARELY_USED, // ç±® + 0x7C70, KANJI_RARELY_USED, // ç±° + 0x7C72, KANJI_RARELY_USED, // ç±² + 0x7C79, KANJI_RARELY_USED, // ç±¹ + 0x7C7C, KANJI_RARELY_USED, // 籌 + 0x7C7D, KANJI_RARELY_USED, // 籜 + 0x7C86, KANJI_RARELY_USED, // 粆 + 0x7C87, KANJI_RARELY_USED, // 粇 + 0x7C8F, KANJI_RARELY_USED, // 粏 + 0x7C94, KANJI_RARELY_USED, // 粔 + 0x7C9E, KANJI_RARELY_USED, // 粞 + 0x7CA0, KANJI_RARELY_USED, // ç²  + 0x7CA6, KANJI_RARELY_USED, // 粊 + 0x7CB0, KANJI_RARELY_USED, // ç²° + 0x7CB6, KANJI_RARELY_USED, // ç²¶ + 0x7CB7, KANJI_RARELY_USED, // ç²· + 0x7CBA, KANJI_RARELY_USED, // 粺 + 0x7CBB, KANJI_RARELY_USED, // ç²» + 0x7CBC, KANJI_RARELY_USED, // 粌 + 0x7CBF, KANJI_RARELY_USED, // 粿 + 0x7CC4, KANJI_RARELY_USED, // 糄 + 0x7CC7, KANJI_RARELY_USED, // 糇 + 0x7CC8, KANJI_RARELY_USED, // 糈 + 0x7CC9, KANJI_RARELY_USED, // 糉 + 0x7CCD, KANJI_RARELY_USED, // 糍 + 0x7CCF, KANJI_RARELY_USED, // 糏 + 0x7CD3, KANJI_RARELY_USED, // 糓 + 0x7CD4, KANJI_RARELY_USED, // 糔 + 0x7CD5, KANJI_RARELY_USED, // 糕 + 0x7CD7, KANJI_RARELY_USED, // 糗 + 0x7CD9, KANJI_RARELY_USED, // 糙 + 0x7CDA, KANJI_RARELY_USED, // 糚 + 0x7CDD, KANJI_RARELY_USED, // 糝 + 0x7CE6, KANJI_RARELY_USED, // 糊 + 0x7CE9, KANJI_RARELY_USED, // 糩 + 0x7CEB, KANJI_RARELY_USED, // 糫 + 0x7CF5, KANJI_RARELY_USED, // ç³µ + 0x7D03, KANJI_RARELY_USED, // 玃 + 0x7D07, KANJI_RARELY_USED, // 箇 + 0x7D08, KANJI_RARELY_USED, // 玈 + 0x7D09, KANJI_RARELY_USED, // 箉 + 0x7D0F, KANJI_RARELY_USED, // 玏 + 0x7D11, KANJI_RARELY_USED, // 箑 + 0x7D12, KANJI_RARELY_USED, // 箒 + 0x7D13, KANJI_RARELY_USED, // 箓 + 0x7D16, KANJI_RARELY_USED, // 箖 + 0x7D1D, KANJI_RARELY_USED, // 玝 + 0x7D1E, KANJI_RARELY_USED, // 箞 + 0x7D23, KANJI_RARELY_USED, // 玣 + 0x7D26, KANJI_RARELY_USED, // 玊 + 0x7D2A, KANJI_RARELY_USED, // 玪 + 0x7D2D, KANJI_RARELY_USED, // 玭 + 0x7D31, KANJI_RARELY_USED, // 玱 + 0x7D3C, KANJI_RARELY_USED, // 玌 + 0x7D3D, KANJI_RARELY_USED, // 玜 + 0x7D3E, KANJI_RARELY_USED, // 玟 + 0x7D40, KANJI_RARELY_USED, // 絀 + 0x7D41, KANJI_RARELY_USED, // 絁 + 0x7D47, KANJI_RARELY_USED, // 絇 + 0x7D48, KANJI_RARELY_USED, // 絈 + 0x7D4D, KANJI_RARELY_USED, // 絍 + 0x7D51, KANJI_RARELY_USED, // 絑 + 0x7D53, KANJI_RARELY_USED, // 絓 + 0x7D57, KANJI_RARELY_USED, // 絗 + 0x7D59, KANJI_RARELY_USED, // 絙 + 0x7D5A, KANJI_RARELY_USED, // 絚 + 0x7D5C, KANJI_RARELY_USED, // 絜 + 0x7D5D, KANJI_RARELY_USED, // 絝 + 0x7D65, KANJI_RARELY_USED, // çµ¥ + 0x7D67, KANJI_RARELY_USED, // çµ§ + 0x7D6A, KANJI_RARELY_USED, // 絪 + 0x7D70, KANJI_RARELY_USED, // çµ° + 0x7D78, KANJI_RARELY_USED, // 絞 + 0x7D7A, KANJI_RARELY_USED, // 絺 + 0x7D7B, KANJI_RARELY_USED, // çµ» + 0x7D7F, KANJI_RARELY_USED, // 絿 + 0x7D81, KANJI_RARELY_USED, // 綁 + 0x7D82, KANJI_RARELY_USED, // 綂 + 0x7D83, KANJI_RARELY_USED, // 綃 + 0x7D85, KANJI_RARELY_USED, // 綅 + 0x7D86, KANJI_RARELY_USED, // 綆 + 0x7D88, KANJI_RARELY_USED, // 綈 + 0x7D8B, KANJI_RARELY_USED, // 綋 + 0x7D8C, KANJI_RARELY_USED, // 綌 + 0x7D8D, KANJI_RARELY_USED, // 綍 + 0x7D91, KANJI_RARELY_USED, // 綑 + 0x7D96, KANJI_RARELY_USED, // 綖 + 0x7D97, KANJI_RARELY_USED, // 綗 + 0x7D9D, KANJI_RARELY_USED, // 綝 + 0x7D9E, KANJI_RARELY_USED, // 綞 + 0x7DA6, KANJI_RARELY_USED, // ç¶Š + 0x7DA7, KANJI_RARELY_USED, // ç¶§ + 0x7DAA, KANJI_RARELY_USED, // 綪 + 0x7DB3, KANJI_RARELY_USED, // ç¶³ + 0x7DB6, KANJI_RARELY_USED, // ç¶¶ + 0x7DB7, KANJI_RARELY_USED, // ç¶· + 0x7DB9, KANJI_RARELY_USED, // ç¶¹ + 0x7DC2, KANJI_RARELY_USED, // 緂 + 0x7DC3, KANJI_RARELY_USED, // 緃 + 0x7DC4, KANJI_RARELY_USED, // 緄 + 0x7DC5, KANJI_RARELY_USED, // 緅 + 0x7DC6, KANJI_RARELY_USED, // 緆 + 0x7DCC, KANJI_RARELY_USED, // 緌 + 0x7DCD, KANJI_RARELY_USED, // 緍 + 0x7DCE, KANJI_RARELY_USED, // 緎 + 0x7DD7, KANJI_RARELY_USED, // 緗 + 0x7DD9, KANJI_RARELY_USED, // 緙 + 0x7E00, KANJI_RARELY_USED, // 羀 + 0x7DE2, KANJI_RARELY_USED, // ç·¢ + 0x7DE5, KANJI_RARELY_USED, // ç·¥ + 0x7DE6, KANJI_RARELY_USED, // ç·Š + 0x7DEA, KANJI_RARELY_USED, // ç·ª + 0x7DEB, KANJI_RARELY_USED, // ç·« + 0x7DED, KANJI_RARELY_USED, // ç·­ + 0x7DF1, KANJI_RARELY_USED, // ç·± + 0x7DF5, KANJI_RARELY_USED, // ç·µ + 0x7DF6, KANJI_RARELY_USED, // ç·¶ + 0x7DF9, KANJI_RARELY_USED, // ç·¹ + 0x7DFA, KANJI_RARELY_USED, // ç·º + 0x7E08, KANJI_RARELY_USED, // 瞈 + 0x7E10, KANJI_RARELY_USED, // 瞐 + 0x7E11, KANJI_RARELY_USED, // 羑 + 0x7E15, KANJI_RARELY_USED, // 羕 + 0x7E17, KANJI_RARELY_USED, // 羗 + 0x7E1C, KANJI_RARELY_USED, // 羜 + 0x7E1D, KANJI_RARELY_USED, // 瞝 + 0x7E20, KANJI_RARELY_USED, // çž  + 0x7E27, KANJI_RARELY_USED, // çž§ + 0x7E28, KANJI_RARELY_USED, // çžš + 0x7E2C, KANJI_RARELY_USED, // 瞬 + 0x7E2D, KANJI_RARELY_USED, // çž­ + 0x7E2F, KANJI_RARELY_USED, // 瞯 + 0x7E33, KANJI_RARELY_USED, // çž³ + 0x7E36, KANJI_RARELY_USED, // çž¶ + 0x7E3F, KANJI_RARELY_USED, // çž¿ + 0x7E44, KANJI_RARELY_USED, // 繄 + 0x7E45, KANJI_RARELY_USED, // 繅 + 0x7E47, KANJI_RARELY_USED, // 繇 + 0x7E4E, KANJI_RARELY_USED, // 繎 + 0x7E50, KANJI_RARELY_USED, // 繐 + 0x7E52, KANJI_RARELY_USED, // 繒 + 0x7E58, KANJI_RARELY_USED, // 繘 + 0x7E5F, KANJI_RARELY_USED, // 繟 + 0x7E61, KANJI_RARELY_USED, // 繡 + 0x7E62, KANJI_RARELY_USED, // ç¹¢ + 0x7E65, KANJI_RARELY_USED, // ç¹¥ + 0x7E6B, KANJI_RARELY_USED, // 繫 + 0x7E6E, KANJI_RARELY_USED, // ç¹® + 0x7E6F, KANJI_RARELY_USED, // 繯 + 0x7E73, KANJI_RARELY_USED, // ç¹³ + 0x7E78, KANJI_RARELY_USED, // 繞 + 0x7E7E, KANJI_RARELY_USED, // 繟 + 0x7E81, KANJI_RARELY_USED, // 纁 + 0x7E86, KANJI_RARELY_USED, // 纆 + 0x7E87, KANJI_RARELY_USED, // 纇 + 0x7E8A, KANJI_RARELY_USED, // 纊 + 0x7E8D, KANJI_RARELY_USED, // 纍 + 0x7E91, KANJI_RARELY_USED, // 纑 + 0x7E95, KANJI_RARELY_USED, // 纕 + 0x7E98, KANJI_RARELY_USED, // 纘 + 0x7E9A, KANJI_RARELY_USED, // 纚 + 0x7E9D, KANJI_RARELY_USED, // 纝 + 0x7E9E, KANJI_RARELY_USED, // 纞 + 0x7F3C, KANJI_RARELY_USED, // 猌 + 0x7F3B, KANJI_RARELY_USED, // 猻 + 0x7F3D, KANJI_RARELY_USED, // 猜 + 0x7F3E, KANJI_RARELY_USED, // 猟 + 0x7F3F, KANJI_RARELY_USED, // 猿 + 0x7F43, KANJI_RARELY_USED, // 眃 + 0x7F44, KANJI_RARELY_USED, // 眄 + 0x7F47, KANJI_RARELY_USED, // 眇 + 0x7F4F, KANJI_RARELY_USED, // 眏 + 0x7F52, KANJI_RARELY_USED, // 眒 + 0x7F53, KANJI_RARELY_USED, // 眓 + 0x7F5B, KANJI_RARELY_USED, // 眛 + 0x7F5C, KANJI_RARELY_USED, // 眜 + 0x7F5D, KANJI_RARELY_USED, // 眝 + 0x7F61, KANJI_RARELY_USED, // 眡 + 0x7F63, KANJI_RARELY_USED, // 眣 + 0x7F64, KANJI_RARELY_USED, // 眀 + 0x7F65, KANJI_RARELY_USED, // 眥 + 0x7F66, KANJI_RARELY_USED, // 眊 + 0x7F6D, KANJI_RARELY_USED, // 眭 + 0x7F71, KANJI_RARELY_USED, // 眱 + 0x7F7D, KANJI_RARELY_USED, // 眜 + 0x7F7E, KANJI_RARELY_USED, // 真 + 0x7F7F, KANJI_RARELY_USED, // 眿 + 0x7F80, KANJI_RARELY_USED, // 矀 + 0x7F8B, KANJI_RARELY_USED, // 矋 + 0x7F8D, KANJI_RARELY_USED, // 矍 + 0x7F8F, KANJI_RARELY_USED, // 矏 + 0x7F90, KANJI_RARELY_USED, // 矐 + 0x7F91, KANJI_RARELY_USED, // 矑 + 0x7F96, KANJI_RARELY_USED, // 矖 + 0x7F97, KANJI_RARELY_USED, // 矗 + 0x7F9C, KANJI_RARELY_USED, // 矜 + 0x7FA1, KANJI_RARELY_USED, // 矡 + 0x7FA2, KANJI_RARELY_USED, // 矢 + 0x7FA6, KANJI_RARELY_USED, // 矊 + 0x7FAA, KANJI_RARELY_USED, // 矪 + 0x7FAD, KANJI_RARELY_USED, // 短 + 0x7FB4, KANJI_RARELY_USED, // 矎 + 0x7FBC, KANJI_RARELY_USED, // 矌 + 0x7FBF, KANJI_RARELY_USED, // 矿 + 0x7FC0, KANJI_RARELY_USED, // 翀 + 0x7FC3, KANJI_RARELY_USED, // 翃 + 0x7FC8, KANJI_RARELY_USED, // 翈 + 0x7FCE, KANJI_RARELY_USED, // 翎 + 0x7FCF, KANJI_RARELY_USED, // 翏 + 0x7FDB, KANJI_RARELY_USED, // 翛 + 0x7FDF, KANJI_RARELY_USED, // 翟 + 0x7FE3, KANJI_RARELY_USED, // ç¿£ + 0x7FE5, KANJI_RARELY_USED, // ç¿¥ + 0x7FE8, KANJI_RARELY_USED, // 翚 + 0x7FEC, KANJI_RARELY_USED, // 翬 + 0x7FEE, KANJI_RARELY_USED, // ç¿® + 0x7FEF, KANJI_RARELY_USED, // 翯 + 0x7FF2, KANJI_RARELY_USED, // 翲 + 0x7FFA, KANJI_RARELY_USED, // 翺 + 0x7FFD, KANJI_RARELY_USED, // 翜 + 0x7FFE, KANJI_RARELY_USED, // 翟 + 0x7FFF, KANJI_RARELY_USED, // ç¿¿ + 0x8007, KANJI_RARELY_USED, // 耇 + 0x8008, KANJI_RARELY_USED, // 耈 + 0x800A, KANJI_RARELY_USED, // 耊 + 0x800D, KANJI_RARELY_USED, // 耍 + 0x800E, KANJI_RARELY_USED, // 耎 + 0x800F, KANJI_RARELY_USED, // 耏 + 0x8011, KANJI_RARELY_USED, // 耑 + 0x8013, KANJI_RARELY_USED, // 耓 + 0x8014, KANJI_RARELY_USED, // 耔 + 0x8016, KANJI_RARELY_USED, // 耖 + 0x801D, KANJI_RARELY_USED, // 耝 + 0x801E, KANJI_RARELY_USED, // 耞 + 0x801F, KANJI_RARELY_USED, // 耟 + 0x8020, KANJI_RARELY_USED, // 耠 + 0x8024, KANJI_RARELY_USED, // 耀 + 0x8026, KANJI_RARELY_USED, // 耊 + 0x802C, KANJI_RARELY_USED, // 耬 + 0x802E, KANJI_RARELY_USED, // 耮 + 0x8030, KANJI_RARELY_USED, // 耰 + 0x8034, KANJI_RARELY_USED, // 耎 + 0x8035, KANJI_RARELY_USED, // 耵 + 0x8037, KANJI_RARELY_USED, // 耷 + 0x8039, KANJI_RARELY_USED, // 耹 + 0x803A, KANJI_RARELY_USED, // 耺 + 0x803C, KANJI_RARELY_USED, // 而 + 0x803E, KANJI_RARELY_USED, // 耟 + 0x8040, KANJI_RARELY_USED, // 聀 + 0x8044, KANJI_RARELY_USED, // 聄 + 0x8060, KANJI_RARELY_USED, // 聠 + 0x8064, KANJI_RARELY_USED, // 聀 + 0x8066, KANJI_RARELY_USED, // 聊 + 0x806D, KANJI_RARELY_USED, // 聭 + 0x8071, KANJI_RARELY_USED, // 聱 + 0x8075, KANJI_RARELY_USED, // 聵 + 0x8081, KANJI_RARELY_USED, // 肁 + 0x8088, KANJI_RARELY_USED, // 肈 + 0x808E, KANJI_RARELY_USED, // 肎 + 0x809C, KANJI_RARELY_USED, // 肜 + 0x809E, KANJI_RARELY_USED, // 肞 + 0x80A6, KANJI_RARELY_USED, // 肊 + 0x80A7, KANJI_RARELY_USED, // 肧 + 0x80AB, KANJI_RARELY_USED, // 肫 + 0x80B8, KANJI_RARELY_USED, // 肞 + 0x80B9, KANJI_RARELY_USED, // 肹 + 0x80C8, KANJI_RARELY_USED, // 胈 + 0x80CD, KANJI_RARELY_USED, // 胍 + 0x80CF, KANJI_RARELY_USED, // 胏 + 0x80D2, KANJI_RARELY_USED, // 胒 + 0x80D4, KANJI_RARELY_USED, // 胔 + 0x80D5, KANJI_RARELY_USED, // 胕 + 0x80D7, KANJI_RARELY_USED, // 胗 + 0x80D8, KANJI_RARELY_USED, // 胘 + 0x80E0, KANJI_RARELY_USED, // 胠 + 0x80ED, KANJI_RARELY_USED, // 胭 + 0x80EE, KANJI_RARELY_USED, // 胮 + 0x80F0, KANJI_RARELY_USED, // 胰 + 0x80F2, KANJI_RARELY_USED, // 胲 + 0x80F3, KANJI_RARELY_USED, // 胳 + 0x80F6, KANJI_RARELY_USED, // 胶 + 0x80F9, KANJI_RARELY_USED, // 胹 + 0x80FA, KANJI_RARELY_USED, // 胺 + 0x80FE, KANJI_RARELY_USED, // 胟 + 0x8103, KANJI_RARELY_USED, // 脃 + 0x810B, KANJI_RARELY_USED, // 脋 + 0x8116, KANJI_RARELY_USED, // 脖 + 0x8117, KANJI_RARELY_USED, // 脗 + 0x8118, KANJI_RARELY_USED, // 脘 + 0x811C, KANJI_RARELY_USED, // 脜 + 0x811E, KANJI_RARELY_USED, // 脞 + 0x8120, KANJI_RARELY_USED, // 脠 + 0x8124, KANJI_RARELY_USED, // è„€ + 0x8127, KANJI_RARELY_USED, // 脧 + 0x812C, KANJI_RARELY_USED, // 脬 + 0x8130, KANJI_RARELY_USED, // 脰 + 0x8135, KANJI_RARELY_USED, // 脵 + 0x813A, KANJI_RARELY_USED, // 脺 + 0x813C, KANJI_RARELY_USED, // 脌 + 0x8145, KANJI_RARELY_USED, // 腅 + 0x8147, KANJI_RARELY_USED, // 腇 + 0x814A, KANJI_RARELY_USED, // 腊 + 0x814C, KANJI_RARELY_USED, // 腌 + 0x8152, KANJI_RARELY_USED, // 腒 + 0x8157, KANJI_RARELY_USED, // 腗 + 0x8160, KANJI_RARELY_USED, // 腠 + 0x8161, KANJI_RARELY_USED, // 腡 + 0x8167, KANJI_RARELY_USED, // 腧 + 0x8168, KANJI_RARELY_USED, // è…š + 0x8169, KANJI_RARELY_USED, // 腩 + 0x816D, KANJI_RARELY_USED, // 腭 + 0x816F, KANJI_RARELY_USED, // 腯 + 0x8177, KANJI_RARELY_USED, // 腷 + 0x8181, KANJI_RARELY_USED, // 膁 + 0x8190, KANJI_RARELY_USED, // 膐 + 0x8184, KANJI_RARELY_USED, // 膄 + 0x8185, KANJI_RARELY_USED, // 膅 + 0x8186, KANJI_RARELY_USED, // 膆 + 0x818B, KANJI_RARELY_USED, // 膋 + 0x818E, KANJI_RARELY_USED, // 膎 + 0x8196, KANJI_RARELY_USED, // 膖 + 0x8198, KANJI_RARELY_USED, // 膘 + 0x819B, KANJI_RARELY_USED, // 膛 + 0x819E, KANJI_RARELY_USED, // 膞 + 0x81A2, KANJI_RARELY_USED, // 膢 + 0x81AE, KANJI_RARELY_USED, // 膮 + 0x81B2, KANJI_RARELY_USED, // 膲 + 0x81B4, KANJI_RARELY_USED, // 膎 + 0x81BB, KANJI_RARELY_USED, // 膻 + 0x81CB, KANJI_RARELY_USED, // 臋 + 0x81C3, KANJI_RARELY_USED, // 臃 + 0x81C5, KANJI_RARELY_USED, // 臅 + 0x81CA, KANJI_RARELY_USED, // 臊 + 0x81CE, KANJI_RARELY_USED, // 臎 + 0x81CF, KANJI_RARELY_USED, // 臏 + 0x81D5, KANJI_RARELY_USED, // 臕 + 0x81D7, KANJI_RARELY_USED, // 臗 + 0x81DB, KANJI_RARELY_USED, // 臛 + 0x81DD, KANJI_RARELY_USED, // 臝 + 0x81DE, KANJI_RARELY_USED, // 臞 + 0x81E1, KANJI_RARELY_USED, // 臡 + 0x81E4, KANJI_RARELY_USED, // 臀 + 0x81EB, KANJI_RARELY_USED, // 臫 + 0x81EC, KANJI_RARELY_USED, // 臬 + 0x81F0, KANJI_RARELY_USED, // 臰 + 0x81F1, KANJI_RARELY_USED, // 臱 + 0x81F2, KANJI_RARELY_USED, // 臲 + 0x81F5, KANJI_RARELY_USED, // 臵 + 0x81F6, KANJI_RARELY_USED, // 臶 + 0x81F8, KANJI_RARELY_USED, // 臞 + 0x81F9, KANJI_RARELY_USED, // 臹 + 0x81FD, KANJI_RARELY_USED, // 臜 + 0x81FF, KANJI_RARELY_USED, // 臿 + 0x8200, KANJI_RARELY_USED, // 舀 + 0x8203, KANJI_RARELY_USED, // 舃 + 0x820F, KANJI_RARELY_USED, // 舏 + 0x8213, KANJI_RARELY_USED, // 舓 + 0x8214, KANJI_RARELY_USED, // 舔 + 0x8219, KANJI_RARELY_USED, // 舙 + 0x821A, KANJI_RARELY_USED, // 舚 + 0x821D, KANJI_RARELY_USED, // 舝 + 0x8221, KANJI_RARELY_USED, // 舡 + 0x8222, KANJI_RARELY_USED, // 舢 + 0x8228, KANJI_RARELY_USED, // 舚 + 0x8232, KANJI_RARELY_USED, // 舲 + 0x8234, KANJI_RARELY_USED, // 舎 + 0x823A, KANJI_RARELY_USED, // 舺 + 0x8243, KANJI_RARELY_USED, // 艃 + 0x8244, KANJI_RARELY_USED, // 艄 + 0x8245, KANJI_RARELY_USED, // 艅 + 0x8246, KANJI_RARELY_USED, // 艆 + 0x824B, KANJI_RARELY_USED, // 艋 + 0x824E, KANJI_RARELY_USED, // 艎 + 0x824F, KANJI_RARELY_USED, // 艏 + 0x8251, KANJI_RARELY_USED, // 艑 + 0x8256, KANJI_RARELY_USED, // 艖 + 0x825C, KANJI_RARELY_USED, // 艜 + 0x8260, KANJI_RARELY_USED, // 艠 + 0x8263, KANJI_RARELY_USED, // 艣 + 0x8267, KANJI_RARELY_USED, // 艧 + 0x826D, KANJI_RARELY_USED, // 艭 + 0x8274, KANJI_RARELY_USED, // 艎 + 0x827B, KANJI_RARELY_USED, // 艻 + 0x827D, KANJI_RARELY_USED, // 艜 + 0x827F, KANJI_RARELY_USED, // 艿 + 0x8280, KANJI_RARELY_USED, // 芀 + 0x8281, KANJI_RARELY_USED, // 芁 + 0x8283, KANJI_RARELY_USED, // 芃 + 0x8284, KANJI_RARELY_USED, // 芄 + 0x8287, KANJI_RARELY_USED, // 芇 + 0x8289, KANJI_RARELY_USED, // 芉 + 0x828A, KANJI_RARELY_USED, // 芊 + 0x828E, KANJI_RARELY_USED, // 芎 + 0x8291, KANJI_RARELY_USED, // 芑 + 0x8294, KANJI_RARELY_USED, // 芔 + 0x8296, KANJI_RARELY_USED, // 芖 + 0x8298, KANJI_RARELY_USED, // 芘 + 0x829A, KANJI_RARELY_USED, // 芚 + 0x829B, KANJI_RARELY_USED, // 芛 + 0x82A0, KANJI_RARELY_USED, // 芠 + 0x82A1, KANJI_RARELY_USED, // 芡 + 0x82A3, KANJI_RARELY_USED, // 芣 + 0x82A4, KANJI_RARELY_USED, // 芀 + 0x82A7, KANJI_RARELY_USED, // 芧 + 0x82A8, KANJI_RARELY_USED, // 芚 + 0x82A9, KANJI_RARELY_USED, // 芩 + 0x82AA, KANJI_RARELY_USED, // 芪 + 0x82AE, KANJI_RARELY_USED, // 芮 + 0x82B0, KANJI_RARELY_USED, // 芰 + 0x82B2, KANJI_RARELY_USED, // 芲 + 0x82B4, KANJI_RARELY_USED, // 芎 + 0x82B7, KANJI_RARELY_USED, // 芷 + 0x82BA, KANJI_RARELY_USED, // 芺 + 0x82BC, KANJI_RARELY_USED, // 芌 + 0x82BE, KANJI_RARELY_USED, // 芟 + 0x82BF, KANJI_RARELY_USED, // 芿 + 0x82C6, KANJI_RARELY_USED, // 苆 + 0x82D0, KANJI_RARELY_USED, // 苐 + 0x82D5, KANJI_RARELY_USED, // 苕 + 0x82DA, KANJI_RARELY_USED, // 苚 + 0x82E0, KANJI_RARELY_USED, // 苠 + 0x82E2, KANJI_RARELY_USED, // 苢 + 0x82E4, KANJI_RARELY_USED, // è‹€ + 0x82E8, KANJI_RARELY_USED, // 苚 + 0x82EA, KANJI_RARELY_USED, // 苪 + 0x82ED, KANJI_RARELY_USED, // 苭 + 0x82EF, KANJI_RARELY_USED, // 苯 + 0x82F6, KANJI_RARELY_USED, // 苶 + 0x82F7, KANJI_RARELY_USED, // 苷 + 0x82FD, KANJI_RARELY_USED, // 苜 + 0x82FE, KANJI_RARELY_USED, // 苟 + 0x8300, KANJI_RARELY_USED, // 茀 + 0x8301, KANJI_RARELY_USED, // 茁 + 0x8307, KANJI_RARELY_USED, // 茇 + 0x8308, KANJI_RARELY_USED, // 茈 + 0x830A, KANJI_RARELY_USED, // 茊 + 0x830B, KANJI_RARELY_USED, // 茋 + 0x8354, KANJI_RARELY_USED, // 荔 + 0x831B, KANJI_RARELY_USED, // 茛 + 0x831D, KANJI_RARELY_USED, // 茝 + 0x831E, KANJI_RARELY_USED, // 茞 + 0x831F, KANJI_RARELY_USED, // 茟 + 0x8321, KANJI_RARELY_USED, // 茡 + 0x8322, KANJI_RARELY_USED, // 茢 + 0x832C, KANJI_RARELY_USED, // 茬 + 0x832D, KANJI_RARELY_USED, // 茭 + 0x832E, KANJI_RARELY_USED, // 茮 + 0x8330, KANJI_RARELY_USED, // 茰 + 0x8333, KANJI_RARELY_USED, // 茳 + 0x8337, KANJI_RARELY_USED, // 茷 + 0x833A, KANJI_RARELY_USED, // 茺 + 0x833C, KANJI_RARELY_USED, // 茌 + 0x833D, KANJI_RARELY_USED, // 茜 + 0x8342, KANJI_RARELY_USED, // 荂 + 0x8343, KANJI_RARELY_USED, // 荃 + 0x8344, KANJI_RARELY_USED, // 荄 + 0x8347, KANJI_RARELY_USED, // 荇 + 0x834D, KANJI_RARELY_USED, // 荍 + 0x834E, KANJI_RARELY_USED, // 荎 + 0x8351, KANJI_RARELY_USED, // 荑 + 0x8355, KANJI_RARELY_USED, // 荕 + 0x8356, KANJI_RARELY_USED, // 荖 + 0x8357, KANJI_RARELY_USED, // 荗 + 0x8370, KANJI_RARELY_USED, // 荰 + 0x8378, KANJI_RARELY_USED, // 荞 + 0x837D, KANJI_RARELY_USED, // 荜 + 0x837F, KANJI_RARELY_USED, // 荿 + 0x8380, KANJI_RARELY_USED, // 莀 + 0x8382, KANJI_RARELY_USED, // 莂 + 0x8384, KANJI_RARELY_USED, // 莄 + 0x8386, KANJI_RARELY_USED, // 莆 + 0x838D, KANJI_RARELY_USED, // 莍 + 0x8392, KANJI_RARELY_USED, // 莒 + 0x8394, KANJI_RARELY_USED, // 莔 + 0x8395, KANJI_RARELY_USED, // 莕 + 0x8398, KANJI_RARELY_USED, // 莘 + 0x8399, KANJI_RARELY_USED, // 莙 + 0x839B, KANJI_RARELY_USED, // 莛 + 0x839C, KANJI_RARELY_USED, // 莜 + 0x839D, KANJI_RARELY_USED, // 莝 + 0x83A6, KANJI_RARELY_USED, // 莊 + 0x83A7, KANJI_RARELY_USED, // 莧 + 0x83A9, KANJI_RARELY_USED, // 莩 + 0x83AC, KANJI_RARELY_USED, // 莬 + 0x83BE, KANJI_RARELY_USED, // 莟 + 0x83BF, KANJI_RARELY_USED, // 莿 + 0x83C0, KANJI_RARELY_USED, // 菀 + 0x83C7, KANJI_RARELY_USED, // 菇 + 0x83C9, KANJI_RARELY_USED, // 菉 + 0x83CF, KANJI_RARELY_USED, // 菏 + 0x83D0, KANJI_RARELY_USED, // 菐 + 0x83D1, KANJI_RARELY_USED, // 菑 + 0x83D4, KANJI_RARELY_USED, // 菔 + 0x83DD, KANJI_RARELY_USED, // 菝 + 0x8353, KANJI_RARELY_USED, // 荓 + 0x83E8, KANJI_RARELY_USED, // 菚 + 0x83EA, KANJI_RARELY_USED, // 菪 + 0x83F6, KANJI_RARELY_USED, // 菶 + 0x83F8, KANJI_RARELY_USED, // 菞 + 0x83F9, KANJI_RARELY_USED, // 菹 + 0x83FC, KANJI_RARELY_USED, // 菌 + 0x8401, KANJI_RARELY_USED, // 萁 + 0x8406, KANJI_RARELY_USED, // 萆 + 0x840A, KANJI_RARELY_USED, // 萊 + 0x840F, KANJI_RARELY_USED, // 萏 + 0x8411, KANJI_RARELY_USED, // 萑 + 0x8415, KANJI_RARELY_USED, // 萕 + 0x8419, KANJI_RARELY_USED, // 萙 + 0x83AD, KANJI_RARELY_USED, // 莭 + 0x842F, KANJI_RARELY_USED, // 萯 + 0x8439, KANJI_RARELY_USED, // 萹 + 0x8445, KANJI_RARELY_USED, // 葅 + 0x8447, KANJI_RARELY_USED, // 葇 + 0x8448, KANJI_RARELY_USED, // 葈 + 0x844A, KANJI_RARELY_USED, // 葊 + 0x844D, KANJI_RARELY_USED, // 葍 + 0x844F, KANJI_RARELY_USED, // 葏 + 0x8451, KANJI_RARELY_USED, // 葑 + 0x8452, KANJI_RARELY_USED, // 葒 + 0x8456, KANJI_RARELY_USED, // 葖 + 0x8458, KANJI_RARELY_USED, // 葘 + 0x8459, KANJI_RARELY_USED, // 葙 + 0x845A, KANJI_RARELY_USED, // 葚 + 0x845C, KANJI_RARELY_USED, // 葜 + 0x8460, KANJI_RARELY_USED, // 葠 + 0x8464, KANJI_RARELY_USED, // è‘€ + 0x8465, KANJI_RARELY_USED, // 葥 + 0x8467, KANJI_RARELY_USED, // 葧 + 0x846A, KANJI_RARELY_USED, // 葪 + 0x8470, KANJI_RARELY_USED, // 葰 + 0x8473, KANJI_RARELY_USED, // 葳 + 0x8474, KANJI_RARELY_USED, // 葎 + 0x8476, KANJI_RARELY_USED, // 葶 + 0x8478, KANJI_RARELY_USED, // 葞 + 0x847C, KANJI_RARELY_USED, // 葌 + 0x847D, KANJI_RARELY_USED, // 葜 + 0x8481, KANJI_RARELY_USED, // 蒁 + 0x8485, KANJI_RARELY_USED, // 蒅 + 0x8492, KANJI_RARELY_USED, // 蒒 + 0x8493, KANJI_RARELY_USED, // 蒓 + 0x8495, KANJI_RARELY_USED, // 蒕 + 0x849E, KANJI_RARELY_USED, // 蒞 + 0x84A6, KANJI_RARELY_USED, // è’Š + 0x84A8, KANJI_RARELY_USED, // è’š + 0x84A9, KANJI_RARELY_USED, // 蒩 + 0x84AA, KANJI_RARELY_USED, // 蒪 + 0x84AF, KANJI_RARELY_USED, // 蒯 + 0x84B1, KANJI_RARELY_USED, // 蒱 + 0x84B4, KANJI_RARELY_USED, // è’Ž + 0x84BA, KANJI_RARELY_USED, // 蒺 + 0x84BD, KANJI_RARELY_USED, // è’œ + 0x84BE, KANJI_RARELY_USED, // è’Ÿ + 0x84C0, KANJI_RARELY_USED, // 蓀 + 0x84C2, KANJI_RARELY_USED, // 蓂 + 0x84C7, KANJI_RARELY_USED, // 蓇 + 0x84C8, KANJI_RARELY_USED, // 蓈 + 0x84CC, KANJI_RARELY_USED, // 蓌 + 0x84CF, KANJI_RARELY_USED, // 蓏 + 0x84D3, KANJI_RARELY_USED, // 蓓 + 0x84DC, KANJI_RARELY_USED, // 蓜 + 0x84E7, KANJI_RARELY_USED, // 蓧 + 0x84EA, KANJI_RARELY_USED, // 蓪 + 0x84EF, KANJI_RARELY_USED, // 蓯 + 0x84F0, KANJI_RARELY_USED, // 蓰 + 0x84F1, KANJI_RARELY_USED, // 蓱 + 0x84F2, KANJI_RARELY_USED, // 蓲 + 0x84F7, KANJI_RARELY_USED, // 蓷 + 0x8532, KANJI_RARELY_USED, // 蔲 + 0x84FA, KANJI_RARELY_USED, // 蓺 + 0x84FB, KANJI_RARELY_USED, // 蓻 + 0x84FD, KANJI_RARELY_USED, // 蓜 + 0x8502, KANJI_RARELY_USED, // 蔂 + 0x8503, KANJI_RARELY_USED, // 蔃 + 0x8507, KANJI_RARELY_USED, // 蔇 + 0x850C, KANJI_RARELY_USED, // 蔌 + 0x850E, KANJI_RARELY_USED, // 蔎 + 0x8510, KANJI_RARELY_USED, // 蔐 + 0x851C, KANJI_RARELY_USED, // 蔜 + 0x851E, KANJI_RARELY_USED, // 蔞 + 0x8522, KANJI_RARELY_USED, // 蔢 + 0x8523, KANJI_RARELY_USED, // 蔣 + 0x8524, KANJI_RARELY_USED, // 蔀 + 0x8525, KANJI_RARELY_USED, // 蔥 + 0x8527, KANJI_RARELY_USED, // 蔧 + 0x852A, KANJI_RARELY_USED, // 蔪 + 0x852B, KANJI_RARELY_USED, // 蔫 + 0x852F, KANJI_RARELY_USED, // 蔯 + 0x8533, KANJI_RARELY_USED, // 蔳 + 0x8534, KANJI_RARELY_USED, // 蔎 + 0x8536, KANJI_RARELY_USED, // 蔶 + 0x853F, KANJI_RARELY_USED, // 蔿 + 0x8546, KANJI_RARELY_USED, // 蕆 + 0x854F, KANJI_RARELY_USED, // 蕏 + 0x8550, KANJI_RARELY_USED, // 蕐 + 0x8551, KANJI_RARELY_USED, // 蕑 + 0x8552, KANJI_RARELY_USED, // 蕒 + 0x8553, KANJI_RARELY_USED, // 蕓 + 0x8556, KANJI_RARELY_USED, // 蕖 + 0x8559, KANJI_RARELY_USED, // 蕙 + 0x855C, KANJI_RARELY_USED, // 蕜 + 0x855D, KANJI_RARELY_USED, // 蕝 + 0x855E, KANJI_RARELY_USED, // 蕞 + 0x855F, KANJI_RARELY_USED, // 蕟 + 0x8560, KANJI_RARELY_USED, // 蕠 + 0x8561, KANJI_RARELY_USED, // 蕡 + 0x8562, KANJI_RARELY_USED, // 蕢 + 0x8564, KANJI_RARELY_USED, // è•€ + 0x856B, KANJI_RARELY_USED, // 蕫 + 0x856F, KANJI_RARELY_USED, // 蕯 + 0x8579, KANJI_RARELY_USED, // 蕹 + 0x857A, KANJI_RARELY_USED, // 蕺 + 0x857B, KANJI_RARELY_USED, // 蕻 + 0x857D, KANJI_RARELY_USED, // 蕜 + 0x857F, KANJI_RARELY_USED, // 蕿 + 0x8581, KANJI_RARELY_USED, // 薁 + 0x8585, KANJI_RARELY_USED, // 薅 + 0x8586, KANJI_RARELY_USED, // 薆 + 0x8589, KANJI_RARELY_USED, // 薉 + 0x858B, KANJI_RARELY_USED, // 薋 + 0x858C, KANJI_RARELY_USED, // 薌 + 0x858F, KANJI_RARELY_USED, // 薏 + 0x8593, KANJI_RARELY_USED, // 薓 + 0x8598, KANJI_RARELY_USED, // 薘 + 0x859D, KANJI_RARELY_USED, // 薝 + 0x859F, KANJI_RARELY_USED, // 薟 + 0x85A0, KANJI_RARELY_USED, // 薠 + 0x85A2, KANJI_RARELY_USED, // 薢 + 0x85A5, KANJI_RARELY_USED, // 薥 + 0x85A7, KANJI_RARELY_USED, // 薧 + 0x85B4, KANJI_RARELY_USED, // è–Ž + 0x85B6, KANJI_RARELY_USED, // 薶 + 0x85B7, KANJI_RARELY_USED, // 薷 + 0x85B8, KANJI_RARELY_USED, // è–ž + 0x85BC, KANJI_RARELY_USED, // è–Œ + 0x85BD, KANJI_RARELY_USED, // è–œ + 0x85BE, KANJI_RARELY_USED, // è–Ÿ + 0x85BF, KANJI_RARELY_USED, // 薿 + 0x85C2, KANJI_RARELY_USED, // 藂 + 0x85C7, KANJI_RARELY_USED, // 藇 + 0x85CA, KANJI_RARELY_USED, // 藊 + 0x85CB, KANJI_RARELY_USED, // 藋 + 0x85CE, KANJI_RARELY_USED, // 藎 + 0x85AD, KANJI_RARELY_USED, // 薭 + 0x85D8, KANJI_RARELY_USED, // 藘 + 0x85DA, KANJI_RARELY_USED, // 藚 + 0x85DF, KANJI_RARELY_USED, // 藟 + 0x85E0, KANJI_RARELY_USED, // 藠 + 0x85E6, KANJI_RARELY_USED, // è—Š + 0x85E8, KANJI_RARELY_USED, // è—š + 0x85ED, KANJI_RARELY_USED, // 藭 + 0x85F3, KANJI_RARELY_USED, // 藳 + 0x85F6, KANJI_RARELY_USED, // 藶 + 0x85FC, KANJI_RARELY_USED, // è—Œ + 0x85FF, KANJI_RARELY_USED, // 藿 + 0x8600, KANJI_RARELY_USED, // 蘀 + 0x8604, KANJI_RARELY_USED, // 蘄 + 0x8605, KANJI_RARELY_USED, // 蘅 + 0x860D, KANJI_RARELY_USED, // 蘍 + 0x860E, KANJI_RARELY_USED, // 蘎 + 0x8610, KANJI_RARELY_USED, // 蘐 + 0x8611, KANJI_RARELY_USED, // 蘑 + 0x8612, KANJI_RARELY_USED, // 蘒 + 0x8618, KANJI_RARELY_USED, // 蘘 + 0x8619, KANJI_RARELY_USED, // 蘙 + 0x861B, KANJI_RARELY_USED, // 蘛 + 0x861E, KANJI_RARELY_USED, // 蘞 + 0x8621, KANJI_RARELY_USED, // 蘡 + 0x8627, KANJI_RARELY_USED, // 蘧 + 0x8629, KANJI_RARELY_USED, // 蘩 + 0x8636, KANJI_RARELY_USED, // 蘶 + 0x8638, KANJI_RARELY_USED, // 蘞 + 0x863A, KANJI_RARELY_USED, // 蘺 + 0x863C, KANJI_RARELY_USED, // 蘌 + 0x863D, KANJI_RARELY_USED, // 蘜 + 0x8640, KANJI_RARELY_USED, // 虀 + 0x8642, KANJI_RARELY_USED, // 虂 + 0x8646, KANJI_RARELY_USED, // 虆 + 0x8652, KANJI_RARELY_USED, // 虒 + 0x8653, KANJI_RARELY_USED, // 虓 + 0x8656, KANJI_RARELY_USED, // 虖 + 0x8657, KANJI_RARELY_USED, // 虗 + 0x8658, KANJI_RARELY_USED, // 虘 + 0x8659, KANJI_RARELY_USED, // 虙 + 0x865D, KANJI_RARELY_USED, // 虝 + 0x8660, KANJI_RARELY_USED, // 虠 + 0x8661, KANJI_RARELY_USED, // 虡 + 0x8662, KANJI_RARELY_USED, // 虢 + 0x8663, KANJI_RARELY_USED, // 虣 + 0x8664, KANJI_RARELY_USED, // 虀 + 0x8669, KANJI_RARELY_USED, // 虩 + 0x866C, KANJI_RARELY_USED, // 虬 + 0x866F, KANJI_RARELY_USED, // 虯 + 0x8675, KANJI_RARELY_USED, // 虵 + 0x8676, KANJI_RARELY_USED, // 虶 + 0x8677, KANJI_RARELY_USED, // 虷 + 0x867A, KANJI_RARELY_USED, // 虺 + 0x868D, KANJI_RARELY_USED, // 蚍 + 0x8691, KANJI_RARELY_USED, // 蚑 + 0x8696, KANJI_RARELY_USED, // 蚖 + 0x8698, KANJI_RARELY_USED, // 蚘 + 0x869A, KANJI_RARELY_USED, // 蚚 + 0x869C, KANJI_RARELY_USED, // 蚜 + 0x86A1, KANJI_RARELY_USED, // 蚡 + 0x86A6, KANJI_RARELY_USED, // 蚊 + 0x86A7, KANJI_RARELY_USED, // 蚧 + 0x86A8, KANJI_RARELY_USED, // èšš + 0x86AD, KANJI_RARELY_USED, // 蚭 + 0x86B1, KANJI_RARELY_USED, // 蚱 + 0x86B3, KANJI_RARELY_USED, // 蚳 + 0x86B4, KANJI_RARELY_USED, // 蚎 + 0x86B5, KANJI_RARELY_USED, // 蚵 + 0x86B7, KANJI_RARELY_USED, // 蚷 + 0x86B8, KANJI_RARELY_USED, // èšž + 0x86B9, KANJI_RARELY_USED, // 蚹 + 0x86BF, KANJI_RARELY_USED, // 蚿 + 0x86C0, KANJI_RARELY_USED, // 蛀 + 0x86C1, KANJI_RARELY_USED, // 蛁 + 0x86C3, KANJI_RARELY_USED, // 蛃 + 0x86C5, KANJI_RARELY_USED, // 蛅 + 0x86D1, KANJI_RARELY_USED, // 蛑 + 0x86D2, KANJI_RARELY_USED, // 蛒 + 0x86D5, KANJI_RARELY_USED, // 蛕 + 0x86D7, KANJI_RARELY_USED, // 蛗 + 0x86DA, KANJI_RARELY_USED, // 蛚 + 0x86DC, KANJI_RARELY_USED, // 蛜 + 0x86E0, KANJI_RARELY_USED, // 蛠 + 0x86E3, KANJI_RARELY_USED, // 蛣 + 0x86E5, KANJI_RARELY_USED, // 蛥 + 0x86E7, KANJI_RARELY_USED, // 蛧 + 0x8688, KANJI_RARELY_USED, // 蚈 + 0x86FA, KANJI_RARELY_USED, // 蛺 + 0x86FC, KANJI_RARELY_USED, // 蛌 + 0x86FD, KANJI_RARELY_USED, // 蛜 + 0x8704, KANJI_RARELY_USED, // 蜄 + 0x8705, KANJI_RARELY_USED, // 蜅 + 0x8707, KANJI_RARELY_USED, // 蜇 + 0x870B, KANJI_RARELY_USED, // 蜋 + 0x870E, KANJI_RARELY_USED, // 蜎 + 0x870F, KANJI_RARELY_USED, // 蜏 + 0x8710, KANJI_RARELY_USED, // 蜐 + 0x8713, KANJI_RARELY_USED, // 蜓 + 0x8714, KANJI_RARELY_USED, // 蜔 + 0x8719, KANJI_RARELY_USED, // 蜙 + 0x871E, KANJI_RARELY_USED, // 蜞 + 0x871F, KANJI_RARELY_USED, // 蜟 + 0x8721, KANJI_RARELY_USED, // 蜡 + 0x8723, KANJI_RARELY_USED, // 蜣 + 0x8728, KANJI_RARELY_USED, // 蜚 + 0x872E, KANJI_RARELY_USED, // 蜮 + 0x872F, KANJI_RARELY_USED, // 蜯 + 0x8731, KANJI_RARELY_USED, // 蜱 + 0x8732, KANJI_RARELY_USED, // 蜲 + 0x8739, KANJI_RARELY_USED, // 蜹 + 0x873A, KANJI_RARELY_USED, // 蜺 + 0x873C, KANJI_RARELY_USED, // 蜌 + 0x873D, KANJI_RARELY_USED, // 蜜 + 0x873E, KANJI_RARELY_USED, // 蜟 + 0x8740, KANJI_RARELY_USED, // 蝀 + 0x8743, KANJI_RARELY_USED, // 蝃 + 0x8745, KANJI_RARELY_USED, // 蝅 + 0x874D, KANJI_RARELY_USED, // 蝍 + 0x8758, KANJI_RARELY_USED, // 蝘 + 0x875D, KANJI_RARELY_USED, // 蝝 + 0x8761, KANJI_RARELY_USED, // 蝡 + 0x8764, KANJI_RARELY_USED, // 蝀 + 0x8765, KANJI_RARELY_USED, // 蝥 + 0x876F, KANJI_RARELY_USED, // 蝯 + 0x8771, KANJI_RARELY_USED, // 蝱 + 0x8772, KANJI_RARELY_USED, // 蝲 + 0x877B, KANJI_RARELY_USED, // 蝻 + 0x8783, KANJI_RARELY_USED, // 螃 + 0x8784, KANJI_RARELY_USED, // 螄 + 0x8785, KANJI_RARELY_USED, // 螅 + 0x8786, KANJI_RARELY_USED, // 螆 + 0x8787, KANJI_RARELY_USED, // 螇 + 0x8788, KANJI_RARELY_USED, // 螈 + 0x8789, KANJI_RARELY_USED, // 螉 + 0x878B, KANJI_RARELY_USED, // 螋 + 0x878C, KANJI_RARELY_USED, // 螌 + 0x8790, KANJI_RARELY_USED, // 螐 + 0x8793, KANJI_RARELY_USED, // 螓 + 0x8795, KANJI_RARELY_USED, // 螕 + 0x8797, KANJI_RARELY_USED, // 螗 + 0x8798, KANJI_RARELY_USED, // 螘 + 0x8799, KANJI_RARELY_USED, // 螙 + 0x879E, KANJI_RARELY_USED, // 螞 + 0x87A0, KANJI_RARELY_USED, // 螠 + 0x87A3, KANJI_RARELY_USED, // 螣 + 0x87A7, KANJI_RARELY_USED, // 螧 + 0x87AC, KANJI_RARELY_USED, // 螬 + 0x87AD, KANJI_RARELY_USED, // 螭 + 0x87AE, KANJI_RARELY_USED, // 螮 + 0x87B1, KANJI_RARELY_USED, // 螱 + 0x87B5, KANJI_RARELY_USED, // 螵 + 0x87BE, KANJI_RARELY_USED, // 螟 + 0x87BF, KANJI_RARELY_USED, // 螿 + 0x87C1, KANJI_RARELY_USED, // 蟁 + 0x87C8, KANJI_RARELY_USED, // 蟈 + 0x87C9, KANJI_RARELY_USED, // 蟉 + 0x87CA, KANJI_RARELY_USED, // 蟊 + 0x87CE, KANJI_RARELY_USED, // 蟎 + 0x87D5, KANJI_RARELY_USED, // 蟕 + 0x87D6, KANJI_RARELY_USED, // 蟖 + 0x87D9, KANJI_RARELY_USED, // 蟙 + 0x87DA, KANJI_RARELY_USED, // 蟚 + 0x87DC, KANJI_RARELY_USED, // 蟜 + 0x87DF, KANJI_RARELY_USED, // 蟟 + 0x87E2, KANJI_RARELY_USED, // 蟢 + 0x87E3, KANJI_RARELY_USED, // 蟣 + 0x87E4, KANJI_RARELY_USED, // 蟀 + 0x87EA, KANJI_RARELY_USED, // 蟪 + 0x87EB, KANJI_RARELY_USED, // 蟫 + 0x87ED, KANJI_RARELY_USED, // 蟭 + 0x87F1, KANJI_RARELY_USED, // 蟱 + 0x87F3, KANJI_RARELY_USED, // 蟳 + 0x87F8, KANJI_RARELY_USED, // 蟞 + 0x87FA, KANJI_RARELY_USED, // 蟺 + 0x87FF, KANJI_RARELY_USED, // 蟿 + 0x8801, KANJI_RARELY_USED, // 蠁 + 0x8803, KANJI_RARELY_USED, // 蠃 + 0x8806, KANJI_RARELY_USED, // 蠆 + 0x8809, KANJI_RARELY_USED, // 蠉 + 0x880A, KANJI_RARELY_USED, // 蠊 + 0x880B, KANJI_RARELY_USED, // 蠋 + 0x8810, KANJI_RARELY_USED, // 蠐 + 0x8819, KANJI_RARELY_USED, // 蠙 + 0x8812, KANJI_RARELY_USED, // 蠒 + 0x8813, KANJI_RARELY_USED, // 蠓 + 0x8814, KANJI_RARELY_USED, // 蠔 + 0x8818, KANJI_RARELY_USED, // 蠘 + 0x881A, KANJI_RARELY_USED, // 蠚 + 0x881B, KANJI_RARELY_USED, // 蠛 + 0x881C, KANJI_RARELY_USED, // 蠜 + 0x881E, KANJI_RARELY_USED, // 蠞 + 0x881F, KANJI_RARELY_USED, // 蠟 + 0x8828, KANJI_RARELY_USED, // è š + 0x882D, KANJI_RARELY_USED, // è ­ + 0x882E, KANJI_RARELY_USED, // è ® + 0x8830, KANJI_RARELY_USED, // è ° + 0x8832, KANJI_RARELY_USED, // è ² + 0x8835, KANJI_RARELY_USED, // è µ + 0x883A, KANJI_RARELY_USED, // è º + 0x883C, KANJI_RARELY_USED, // è Œ + 0x8841, KANJI_RARELY_USED, // 衁 + 0x8843, KANJI_RARELY_USED, // 衃 + 0x8845, KANJI_RARELY_USED, // 衅 + 0x8848, KANJI_RARELY_USED, // 衈 + 0x8849, KANJI_RARELY_USED, // 衉 + 0x884A, KANJI_RARELY_USED, // 衊 + 0x884B, KANJI_RARELY_USED, // 衋 + 0x884E, KANJI_RARELY_USED, // 衎 + 0x8851, KANJI_RARELY_USED, // 衑 + 0x8855, KANJI_RARELY_USED, // 衕 + 0x8856, KANJI_RARELY_USED, // 衖 + 0x8858, KANJI_RARELY_USED, // 衘 + 0x885A, KANJI_RARELY_USED, // 衚 + 0x885C, KANJI_RARELY_USED, // 衜 + 0x885F, KANJI_RARELY_USED, // 衟 + 0x8860, KANJI_RARELY_USED, // è¡  + 0x8864, KANJI_RARELY_USED, // è¡€ + 0x8869, KANJI_RARELY_USED, // è¡© + 0x8871, KANJI_RARELY_USED, // 衱 + 0x8879, KANJI_RARELY_USED, // 衹 + 0x887B, KANJI_RARELY_USED, // è¡» + 0x8880, KANJI_RARELY_USED, // 袀 + 0x8898, KANJI_RARELY_USED, // 袘 + 0x889A, KANJI_RARELY_USED, // 袚 + 0x889B, KANJI_RARELY_USED, // 袛 + 0x889C, KANJI_RARELY_USED, // 袜 + 0x889F, KANJI_RARELY_USED, // 袟 + 0x88A0, KANJI_RARELY_USED, // 袠 + 0x88A8, KANJI_RARELY_USED, // 袚 + 0x88AA, KANJI_RARELY_USED, // 袪 + 0x88BA, KANJI_RARELY_USED, // 袺 + 0x88BD, KANJI_RARELY_USED, // 袜 + 0x88BE, KANJI_RARELY_USED, // 袟 + 0x88C0, KANJI_RARELY_USED, // 裀 + 0x88CA, KANJI_RARELY_USED, // 裊 + 0x88CB, KANJI_RARELY_USED, // 裋 + 0x88CC, KANJI_RARELY_USED, // 裌 + 0x88CD, KANJI_RARELY_USED, // 裍 + 0x88CE, KANJI_RARELY_USED, // 裎 + 0x88D1, KANJI_RARELY_USED, // 裑 + 0x88D2, KANJI_RARELY_USED, // 裒 + 0x88D3, KANJI_RARELY_USED, // 裓 + 0x88DB, KANJI_RARELY_USED, // 裛 + 0x88DE, KANJI_RARELY_USED, // 裞 + 0x88E7, KANJI_RARELY_USED, // 裧 + 0x88EF, KANJI_RARELY_USED, // 裯 + 0x88F0, KANJI_RARELY_USED, // 裰 + 0x88F1, KANJI_RARELY_USED, // 裱 + 0x88F5, KANJI_RARELY_USED, // 裵 + 0x88F7, KANJI_RARELY_USED, // 裷 + 0x8901, KANJI_RARELY_USED, // 老 + 0x8906, KANJI_RARELY_USED, // 耆 + 0x890D, KANJI_RARELY_USED, // 耍 + 0x890E, KANJI_RARELY_USED, // 耎 + 0x890F, KANJI_RARELY_USED, // 耏 + 0x8915, KANJI_RARELY_USED, // 耕 + 0x8916, KANJI_RARELY_USED, // 耖 + 0x8918, KANJI_RARELY_USED, // 耘 + 0x8919, KANJI_RARELY_USED, // 耙 + 0x891A, KANJI_RARELY_USED, // 耚 + 0x891C, KANJI_RARELY_USED, // 耜 + 0x8920, KANJI_RARELY_USED, // 耠 + 0x8926, KANJI_RARELY_USED, // 耊 + 0x8927, KANJI_RARELY_USED, // 耧 + 0x8928, KANJI_RARELY_USED, // 耚 + 0x8930, KANJI_RARELY_USED, // 耰 + 0x8931, KANJI_RARELY_USED, // 耱 + 0x8932, KANJI_RARELY_USED, // 耲 + 0x8935, KANJI_RARELY_USED, // 耵 + 0x8939, KANJI_RARELY_USED, // 耹 + 0x893A, KANJI_RARELY_USED, // 耺 + 0x893E, KANJI_RARELY_USED, // 耟 + 0x8940, KANJI_RARELY_USED, // 襀 + 0x8942, KANJI_RARELY_USED, // 襂 + 0x8945, KANJI_RARELY_USED, // 襅 + 0x8946, KANJI_RARELY_USED, // 襆 + 0x8949, KANJI_RARELY_USED, // 襉 + 0x894F, KANJI_RARELY_USED, // 襏 + 0x8952, KANJI_RARELY_USED, // 襒 + 0x8957, KANJI_RARELY_USED, // 襗 + 0x895A, KANJI_RARELY_USED, // 襚 + 0x895B, KANJI_RARELY_USED, // 襛 + 0x895C, KANJI_RARELY_USED, // 襜 + 0x8961, KANJI_RARELY_USED, // 襡 + 0x8962, KANJI_RARELY_USED, // 襢 + 0x8963, KANJI_RARELY_USED, // 襣 + 0x896B, KANJI_RARELY_USED, // 襫 + 0x896E, KANJI_RARELY_USED, // 襮 + 0x8970, KANJI_RARELY_USED, // 襰 + 0x8973, KANJI_RARELY_USED, // 襳 + 0x8975, KANJI_RARELY_USED, // 襵 + 0x897A, KANJI_RARELY_USED, // 襺 + 0x897B, KANJI_RARELY_USED, // 襻 + 0x897C, KANJI_RARELY_USED, // 襌 + 0x897D, KANJI_RARELY_USED, // 襜 + 0x8989, KANJI_RARELY_USED, // 芉 + 0x898D, KANJI_RARELY_USED, // 芍 + 0x8990, KANJI_RARELY_USED, // 芐 + 0x8994, KANJI_RARELY_USED, // 芔 + 0x8995, KANJI_RARELY_USED, // 芕 + 0x899B, KANJI_RARELY_USED, // 芛 + 0x899C, KANJI_RARELY_USED, // 芜 + 0x899F, KANJI_RARELY_USED, // 芟 + 0x89A0, KANJI_RARELY_USED, // 芠 + 0x89A5, KANJI_RARELY_USED, // 芥 + 0x89B0, KANJI_RARELY_USED, // 芰 + 0x89B4, KANJI_RARELY_USED, // 芎 + 0x89B5, KANJI_RARELY_USED, // 芵 + 0x89B6, KANJI_RARELY_USED, // 芶 + 0x89B7, KANJI_RARELY_USED, // 芷 + 0x89BC, KANJI_RARELY_USED, // 芌 + 0x89D4, KANJI_RARELY_USED, // 觔 + 0x89D5, KANJI_RARELY_USED, // 觕 + 0x89D6, KANJI_RARELY_USED, // 觖 + 0x89D7, KANJI_RARELY_USED, // 觗 + 0x89D8, KANJI_RARELY_USED, // 觘 + 0x89E5, KANJI_RARELY_USED, // è§¥ + 0x89E9, KANJI_RARELY_USED, // è§© + 0x89EB, KANJI_RARELY_USED, // è§« + 0x89ED, KANJI_RARELY_USED, // è§­ + 0x89F1, KANJI_RARELY_USED, // è§± + 0x89F3, KANJI_RARELY_USED, // è§³ + 0x89F6, KANJI_RARELY_USED, // è§¶ + 0x89F9, KANJI_RARELY_USED, // è§¹ + 0x89FD, KANJI_RARELY_USED, // è§œ + 0x89FF, KANJI_RARELY_USED, // è§¿ + 0x8A04, KANJI_RARELY_USED, // èš„ + 0x8A05, KANJI_RARELY_USED, // èš… + 0x8A07, KANJI_RARELY_USED, // 蚇 + 0x8A0F, KANJI_RARELY_USED, // 蚏 + 0x8A11, KANJI_RARELY_USED, // èš‘ + 0x8A12, KANJI_RARELY_USED, // èš’ + 0x8A14, KANJI_RARELY_USED, // èš” + 0x8A15, KANJI_RARELY_USED, // èš• + 0x8A1E, KANJI_RARELY_USED, // 蚞 + 0x8A20, KANJI_RARELY_USED, // èš  + 0x8A22, KANJI_RARELY_USED, // 蚢 + 0x8A24, KANJI_RARELY_USED, // 蚀 + 0x8A26, KANJI_RARELY_USED, // 蚊 + 0x8A2B, KANJI_RARELY_USED, // èš« + 0x8A2C, KANJI_RARELY_USED, // 蚬 + 0x8A2F, KANJI_RARELY_USED, // 蚯 + 0x8A35, KANJI_RARELY_USED, // èšµ + 0x8A37, KANJI_RARELY_USED, // èš· + 0x8A3D, KANJI_RARELY_USED, // èšœ + 0x8A3E, KANJI_RARELY_USED, // 蚟 + 0x8A40, KANJI_RARELY_USED, // 詀 + 0x8A43, KANJI_RARELY_USED, // 詃 + 0x8A45, KANJI_RARELY_USED, // 詅 + 0x8A47, KANJI_RARELY_USED, // 詇 + 0x8A49, KANJI_RARELY_USED, // 詉 + 0x8A4D, KANJI_RARELY_USED, // 詍 + 0x8A4E, KANJI_RARELY_USED, // 詎 + 0x8A53, KANJI_RARELY_USED, // 詓 + 0x8A56, KANJI_RARELY_USED, // 詖 + 0x8A57, KANJI_RARELY_USED, // 詗 + 0x8A58, KANJI_RARELY_USED, // 詘 + 0x8A5C, KANJI_RARELY_USED, // 詜 + 0x8A5D, KANJI_RARELY_USED, // 詝 + 0x8A61, KANJI_RARELY_USED, // è©¡ + 0x8A65, KANJI_RARELY_USED, // è©¥ + 0x8A67, KANJI_RARELY_USED, // è©§ + 0x8A75, KANJI_RARELY_USED, // 詵 + 0x8A76, KANJI_RARELY_USED, // è©¶ + 0x8A77, KANJI_RARELY_USED, // è©· + 0x8A79, KANJI_RARELY_USED, // 詹 + 0x8A7A, KANJI_RARELY_USED, // 詺 + 0x8A7B, KANJI_RARELY_USED, // è©» + 0x8A7E, KANJI_RARELY_USED, // 詟 + 0x8A7F, KANJI_RARELY_USED, // è©¿ + 0x8A80, KANJI_RARELY_USED, // 誀 + 0x8A83, KANJI_RARELY_USED, // 誃 + 0x8A86, KANJI_RARELY_USED, // 誆 + 0x8A8B, KANJI_RARELY_USED, // 誋 + 0x8A8F, KANJI_RARELY_USED, // 誏 + 0x8A90, KANJI_RARELY_USED, // 誐 + 0x8A92, KANJI_RARELY_USED, // 誒 + 0x8A96, KANJI_RARELY_USED, // 誖 + 0x8A97, KANJI_RARELY_USED, // 誗 + 0x8A99, KANJI_RARELY_USED, // 誙 + 0x8A9F, KANJI_RARELY_USED, // 誟 + 0x8AA7, KANJI_RARELY_USED, // 誧 + 0x8AA9, KANJI_RARELY_USED, // 誩 + 0x8AAE, KANJI_RARELY_USED, // 誮 + 0x8AAF, KANJI_RARELY_USED, // 誯 + 0x8AB3, KANJI_RARELY_USED, // 誳 + 0x8AB6, KANJI_RARELY_USED, // 誶 + 0x8AB7, KANJI_RARELY_USED, // 誷 + 0x8ABB, KANJI_RARELY_USED, // 誻 + 0x8ABE, KANJI_RARELY_USED, // 誟 + 0x8AC3, KANJI_RARELY_USED, // 諃 + 0x8AC6, KANJI_RARELY_USED, // 諆 + 0x8AC8, KANJI_RARELY_USED, // 諈 + 0x8AC9, KANJI_RARELY_USED, // 諉 + 0x8ACA, KANJI_RARELY_USED, // 諊 + 0x8AD1, KANJI_RARELY_USED, // 諑 + 0x8AD3, KANJI_RARELY_USED, // 諓 + 0x8AD4, KANJI_RARELY_USED, // 諔 + 0x8AD5, KANJI_RARELY_USED, // 諕 + 0x8AD7, KANJI_RARELY_USED, // 諗 + 0x8ADD, KANJI_RARELY_USED, // 諝 + 0x8ADF, KANJI_RARELY_USED, // 諟 + 0x8AEC, KANJI_RARELY_USED, // 諬 + 0x8AF0, KANJI_RARELY_USED, // è«° + 0x8AF4, KANJI_RARELY_USED, // 諎 + 0x8AF5, KANJI_RARELY_USED, // 諵 + 0x8AF6, KANJI_RARELY_USED, // è«¶ + 0x8AFC, KANJI_RARELY_USED, // 諌 + 0x8AFF, KANJI_RARELY_USED, // è«¿ + 0x8B05, KANJI_RARELY_USED, // 謅 + 0x8B06, KANJI_RARELY_USED, // 謆 + 0x8B0B, KANJI_RARELY_USED, // 謋 + 0x8B11, KANJI_RARELY_USED, // 謑 + 0x8B1C, KANJI_RARELY_USED, // 謜 + 0x8B1E, KANJI_RARELY_USED, // 謞 + 0x8B1F, KANJI_RARELY_USED, // 謟 + 0x8B0A, KANJI_RARELY_USED, // 謊 + 0x8B2D, KANJI_RARELY_USED, // 謭 + 0x8B30, KANJI_RARELY_USED, // 謰 + 0x8B37, KANJI_RARELY_USED, // 謷 + 0x8B3C, KANJI_RARELY_USED, // 謌 + 0x8B42, KANJI_RARELY_USED, // 譂 + 0x8B43, KANJI_RARELY_USED, // 譃 + 0x8B44, KANJI_RARELY_USED, // 譄 + 0x8B45, KANJI_RARELY_USED, // 譅 + 0x8B46, KANJI_RARELY_USED, // 譆 + 0x8B48, KANJI_RARELY_USED, // 譈 + 0x8B52, KANJI_RARELY_USED, // 譒 + 0x8B53, KANJI_RARELY_USED, // 譓 + 0x8B54, KANJI_RARELY_USED, // 譔 + 0x8B59, KANJI_RARELY_USED, // 譙 + 0x8B4D, KANJI_RARELY_USED, // 譍 + 0x8B5E, KANJI_RARELY_USED, // 譞 + 0x8B63, KANJI_RARELY_USED, // è­£ + 0x8B6D, KANJI_RARELY_USED, // è­­ + 0x8B76, KANJI_RARELY_USED, // è­¶ + 0x8B78, KANJI_RARELY_USED, // è­ž + 0x8B79, KANJI_RARELY_USED, // è­¹ + 0x8B7C, KANJI_RARELY_USED, // è­Œ + 0x8B7E, KANJI_RARELY_USED, // è­Ÿ + 0x8B81, KANJI_RARELY_USED, // 讁 + 0x8B84, KANJI_RARELY_USED, // 讄 + 0x8B85, KANJI_RARELY_USED, // 讅 + 0x8B8B, KANJI_RARELY_USED, // 讋 + 0x8B8D, KANJI_RARELY_USED, // 讍 + 0x8B8F, KANJI_RARELY_USED, // 讏 + 0x8B94, KANJI_RARELY_USED, // 讔 + 0x8B95, KANJI_RARELY_USED, // 讕 + 0x8B9C, KANJI_RARELY_USED, // 讜 + 0x8B9E, KANJI_RARELY_USED, // 讞 + 0x8B9F, KANJI_RARELY_USED, // 讟 + 0x8C38, KANJI_RARELY_USED, // è°ž + 0x8C39, KANJI_RARELY_USED, // è°¹ + 0x8C3D, KANJI_RARELY_USED, // è°œ + 0x8C3E, KANJI_RARELY_USED, // è°Ÿ + 0x8C45, KANJI_RARELY_USED, // 豅 + 0x8C47, KANJI_RARELY_USED, // 豇 + 0x8C49, KANJI_RARELY_USED, // 豉 + 0x8C4B, KANJI_RARELY_USED, // 豋 + 0x8C4F, KANJI_RARELY_USED, // 豏 + 0x8C51, KANJI_RARELY_USED, // 豑 + 0x8C53, KANJI_RARELY_USED, // 豓 + 0x8C54, KANJI_RARELY_USED, // 豔 + 0x8C57, KANJI_RARELY_USED, // 豗 + 0x8C58, KANJI_RARELY_USED, // 豘 + 0x8C5B, KANJI_RARELY_USED, // 豛 + 0x8C5D, KANJI_RARELY_USED, // 豝 + 0x8C59, KANJI_RARELY_USED, // 豙 + 0x8C63, KANJI_RARELY_USED, // è±£ + 0x8C64, KANJI_RARELY_USED, // è±€ + 0x8C66, KANJI_RARELY_USED, // 豊 + 0x8C68, KANJI_RARELY_USED, // 豚 + 0x8C69, KANJI_RARELY_USED, // 豩 + 0x8C6D, KANJI_RARELY_USED, // è±­ + 0x8C73, KANJI_RARELY_USED, // è±³ + 0x8C75, KANJI_RARELY_USED, // è±µ + 0x8C76, KANJI_RARELY_USED, // è±¶ + 0x8C7B, KANJI_RARELY_USED, // è±» + 0x8C7E, KANJI_RARELY_USED, // 豟 + 0x8C86, KANJI_RARELY_USED, // 貆 + 0x8C87, KANJI_RARELY_USED, // 貇 + 0x8C8B, KANJI_RARELY_USED, // 貋 + 0x8C90, KANJI_RARELY_USED, // 貐 + 0x8C92, KANJI_RARELY_USED, // 貒 + 0x8C93, KANJI_RARELY_USED, // 貓 + 0x8C99, KANJI_RARELY_USED, // 貙 + 0x8C9B, KANJI_RARELY_USED, // 貛 + 0x8C9C, KANJI_RARELY_USED, // 貜 + 0x8CA4, KANJI_RARELY_USED, // è²€ + 0x8CB9, KANJI_RARELY_USED, // è²¹ + 0x8CBA, KANJI_RARELY_USED, // 貺 + 0x8CC5, KANJI_RARELY_USED, // 賅 + 0x8CC6, KANJI_RARELY_USED, // 賆 + 0x8CC9, KANJI_RARELY_USED, // 賉 + 0x8CCB, KANJI_RARELY_USED, // 賋 + 0x8CCF, KANJI_RARELY_USED, // 賏 + 0x8CD6, KANJI_RARELY_USED, // 賖 + 0x8CD5, KANJI_RARELY_USED, // 賕 + 0x8CD9, KANJI_RARELY_USED, // 賙 + 0x8CDD, KANJI_RARELY_USED, // 賝 + 0x8CE1, KANJI_RARELY_USED, // 賡 + 0x8CE8, KANJI_RARELY_USED, // 賚 + 0x8CEC, KANJI_RARELY_USED, // 賬 + 0x8CEF, KANJI_RARELY_USED, // 賯 + 0x8CF0, KANJI_RARELY_USED, // è³° + 0x8CF2, KANJI_RARELY_USED, // è³² + 0x8CF5, KANJI_RARELY_USED, // è³µ + 0x8CF7, KANJI_RARELY_USED, // è³· + 0x8CF8, KANJI_RARELY_USED, // 賞 + 0x8CFE, KANJI_RARELY_USED, // 賟 + 0x8CFF, KANJI_RARELY_USED, // 賿 + 0x8D01, KANJI_RARELY_USED, // 莁 + 0x8D03, KANJI_RARELY_USED, // 莃 + 0x8D09, KANJI_RARELY_USED, // 莉 + 0x8D12, KANJI_RARELY_USED, // 莒 + 0x8D17, KANJI_RARELY_USED, // 莗 + 0x8D1B, KANJI_RARELY_USED, // 莛 + 0x8D65, KANJI_RARELY_USED, // èµ¥ + 0x8D69, KANJI_RARELY_USED, // 赩 + 0x8D6C, KANJI_RARELY_USED, // 赬 + 0x8D6E, KANJI_RARELY_USED, // èµ® + 0x8D7F, KANJI_RARELY_USED, // 赿 + 0x8D82, KANJI_RARELY_USED, // 趂 + 0x8D84, KANJI_RARELY_USED, // 趄 + 0x8D88, KANJI_RARELY_USED, // 趈 + 0x8D8D, KANJI_RARELY_USED, // 趍 + 0x8D90, KANJI_RARELY_USED, // 趐 + 0x8D91, KANJI_RARELY_USED, // 趑 + 0x8D95, KANJI_RARELY_USED, // 趕 + 0x8D9E, KANJI_RARELY_USED, // 趞 + 0x8D9F, KANJI_RARELY_USED, // 趟 + 0x8DA0, KANJI_RARELY_USED, // è¶  + 0x8DA6, KANJI_RARELY_USED, // è¶Š + 0x8DAB, KANJI_RARELY_USED, // è¶« + 0x8DAC, KANJI_RARELY_USED, // 趬 + 0x8DAF, KANJI_RARELY_USED, // 趯 + 0x8DB2, KANJI_RARELY_USED, // è¶² + 0x8DB5, KANJI_RARELY_USED, // è¶µ + 0x8DB7, KANJI_RARELY_USED, // è¶· + 0x8DB9, KANJI_RARELY_USED, // è¶¹ + 0x8DBB, KANJI_RARELY_USED, // è¶» + 0x8DC0, KANJI_RARELY_USED, // 跀 + 0x8DC5, KANJI_RARELY_USED, // 跅 + 0x8DC6, KANJI_RARELY_USED, // 跆 + 0x8DC7, KANJI_RARELY_USED, // 跇 + 0x8DC8, KANJI_RARELY_USED, // 跈 + 0x8DCA, KANJI_RARELY_USED, // 跊 + 0x8DCE, KANJI_RARELY_USED, // 跎 + 0x8DD1, KANJI_RARELY_USED, // 跑 + 0x8DD4, KANJI_RARELY_USED, // 跔 + 0x8DD5, KANJI_RARELY_USED, // 跕 + 0x8DD7, KANJI_RARELY_USED, // 跗 + 0x8DD9, KANJI_RARELY_USED, // 跙 + 0x8DE4, KANJI_RARELY_USED, // è·€ + 0x8DE5, KANJI_RARELY_USED, // è·¥ + 0x8DE7, KANJI_RARELY_USED, // è·§ + 0x8DEC, KANJI_RARELY_USED, // è·¬ + 0x8DF0, KANJI_RARELY_USED, // è·° + 0x8DBC, KANJI_RARELY_USED, // è¶Œ + 0x8DF1, KANJI_RARELY_USED, // è·± + 0x8DF2, KANJI_RARELY_USED, // è·² + 0x8DF4, KANJI_RARELY_USED, // è·Ž + 0x8DFD, KANJI_RARELY_USED, // è·œ + 0x8E01, KANJI_RARELY_USED, // 螁 + 0x8E04, KANJI_RARELY_USED, // èž„ + 0x8E05, KANJI_RARELY_USED, // èž… + 0x8E06, KANJI_RARELY_USED, // 螆 + 0x8E0B, KANJI_RARELY_USED, // èž‹ + 0x8E11, KANJI_RARELY_USED, // èž‘ + 0x8E14, KANJI_RARELY_USED, // èž” + 0x8E16, KANJI_RARELY_USED, // èž– + 0x8E20, KANJI_RARELY_USED, // èž  + 0x8E21, KANJI_RARELY_USED, // èž¡ + 0x8E22, KANJI_RARELY_USED, // 螢 + 0x8E23, KANJI_RARELY_USED, // 螣 + 0x8E26, KANJI_RARELY_USED, // 螊 + 0x8E27, KANJI_RARELY_USED, // èž§ + 0x8E31, KANJI_RARELY_USED, // èž± + 0x8E33, KANJI_RARELY_USED, // èž³ + 0x8E36, KANJI_RARELY_USED, // èž¶ + 0x8E37, KANJI_RARELY_USED, // èž· + 0x8E38, KANJI_RARELY_USED, // èžž + 0x8E39, KANJI_RARELY_USED, // èž¹ + 0x8E3D, KANJI_RARELY_USED, // èžœ + 0x8E40, KANJI_RARELY_USED, // 蹀 + 0x8E41, KANJI_RARELY_USED, // 蹁 + 0x8E4B, KANJI_RARELY_USED, // 蹋 + 0x8E4D, KANJI_RARELY_USED, // 蹍 + 0x8E4E, KANJI_RARELY_USED, // 蹎 + 0x8E4F, KANJI_RARELY_USED, // 蹏 + 0x8E54, KANJI_RARELY_USED, // 蹔 + 0x8E5B, KANJI_RARELY_USED, // 蹛 + 0x8E5C, KANJI_RARELY_USED, // 蹜 + 0x8E5D, KANJI_RARELY_USED, // 蹝 + 0x8E5E, KANJI_RARELY_USED, // 蹞 + 0x8E61, KANJI_RARELY_USED, // 蹡 + 0x8E62, KANJI_RARELY_USED, // è¹¢ + 0x8E69, KANJI_RARELY_USED, // 蹩 + 0x8E6C, KANJI_RARELY_USED, // 蹬 + 0x8E6D, KANJI_RARELY_USED, // è¹­ + 0x8E6F, KANJI_RARELY_USED, // 蹯 + 0x8E70, KANJI_RARELY_USED, // è¹° + 0x8E71, KANJI_RARELY_USED, // è¹± + 0x8E79, KANJI_RARELY_USED, // è¹¹ + 0x8E7A, KANJI_RARELY_USED, // 蹺 + 0x8E7B, KANJI_RARELY_USED, // è¹» + 0x8E82, KANJI_RARELY_USED, // 躂 + 0x8E83, KANJI_RARELY_USED, // 躃 + 0x8E89, KANJI_RARELY_USED, // 躉 + 0x8E90, KANJI_RARELY_USED, // 躐 + 0x8E92, KANJI_RARELY_USED, // 躒 + 0x8E95, KANJI_RARELY_USED, // 躕 + 0x8E9A, KANJI_RARELY_USED, // 躚 + 0x8E9B, KANJI_RARELY_USED, // 躛 + 0x8E9D, KANJI_RARELY_USED, // 躝 + 0x8E9E, KANJI_RARELY_USED, // 躞 + 0x8EA2, KANJI_RARELY_USED, // 躢 + 0x8EA7, KANJI_RARELY_USED, // 躧 + 0x8EA9, KANJI_RARELY_USED, // 躩 + 0x8EAD, KANJI_RARELY_USED, // 躭 + 0x8EAE, KANJI_RARELY_USED, // 躮 + 0x8EB3, KANJI_RARELY_USED, // 躳 + 0x8EB5, KANJI_RARELY_USED, // 躵 + 0x8EBA, KANJI_RARELY_USED, // 躺 + 0x8EBB, KANJI_RARELY_USED, // 躻 + 0x8EC0, KANJI_RARELY_USED, // 軀 + 0x8EC1, KANJI_RARELY_USED, // 軁 + 0x8EC3, KANJI_RARELY_USED, // 軃 + 0x8EC4, KANJI_RARELY_USED, // 軄 + 0x8EC7, KANJI_RARELY_USED, // 軇 + 0x8ECF, KANJI_RARELY_USED, // 軏 + 0x8ED1, KANJI_RARELY_USED, // 軑 + 0x8ED4, KANJI_RARELY_USED, // 軔 + 0x8EDC, KANJI_RARELY_USED, // 軜 + 0x8EE8, KANJI_RARELY_USED, // 軚 + 0x8EEE, KANJI_RARELY_USED, // è»® + 0x8EF0, KANJI_RARELY_USED, // è»° + 0x8EF1, KANJI_RARELY_USED, // è»± + 0x8EF7, KANJI_RARELY_USED, // è»· + 0x8EF9, KANJI_RARELY_USED, // 軹 + 0x8EFA, KANJI_RARELY_USED, // 軺 + 0x8EED, KANJI_RARELY_USED, // è»­ + 0x8F00, KANJI_RARELY_USED, // 茀 + 0x8F02, KANJI_RARELY_USED, // 茂 + 0x8F07, KANJI_RARELY_USED, // 茇 + 0x8F08, KANJI_RARELY_USED, // 茈 + 0x8F0F, KANJI_RARELY_USED, // 茏 + 0x8F10, KANJI_RARELY_USED, // 茐 + 0x8F16, KANJI_RARELY_USED, // 茖 + 0x8F17, KANJI_RARELY_USED, // 茗 + 0x8F18, KANJI_RARELY_USED, // 茘 + 0x8F1E, KANJI_RARELY_USED, // 茞 + 0x8F20, KANJI_RARELY_USED, // 茠 + 0x8F21, KANJI_RARELY_USED, // 茡 + 0x8F23, KANJI_RARELY_USED, // 茣 + 0x8F25, KANJI_RARELY_USED, // 茥 + 0x8F27, KANJI_RARELY_USED, // 茧 + 0x8F28, KANJI_RARELY_USED, // 茚 + 0x8F2C, KANJI_RARELY_USED, // 茬 + 0x8F2D, KANJI_RARELY_USED, // 茭 + 0x8F2E, KANJI_RARELY_USED, // 茮 + 0x8F34, KANJI_RARELY_USED, // 茎 + 0x8F35, KANJI_RARELY_USED, // 茵 + 0x8F36, KANJI_RARELY_USED, // 茶 + 0x8F37, KANJI_RARELY_USED, // 茷 + 0x8F3A, KANJI_RARELY_USED, // 茺 + 0x8F40, KANJI_RARELY_USED, // 蜀 + 0x8F41, KANJI_RARELY_USED, // 蜁 + 0x8F43, KANJI_RARELY_USED, // 蜃 + 0x8F47, KANJI_RARELY_USED, // 蜇 + 0x8F4F, KANJI_RARELY_USED, // 蜏 + 0x8F51, KANJI_RARELY_USED, // 蜑 + 0x8F52, KANJI_RARELY_USED, // 蜒 + 0x8F53, KANJI_RARELY_USED, // 蜓 + 0x8F54, KANJI_RARELY_USED, // 蜔 + 0x8F55, KANJI_RARELY_USED, // 蜕 + 0x8F58, KANJI_RARELY_USED, // 蜘 + 0x8F5D, KANJI_RARELY_USED, // 蜝 + 0x8F5E, KANJI_RARELY_USED, // 蜞 + 0x8F65, KANJI_RARELY_USED, // 蜥 + 0x8F9D, KANJI_RARELY_USED, // 蟝 + 0x8FA0, KANJI_RARELY_USED, // 蟠 + 0x8FA1, KANJI_RARELY_USED, // 蟡 + 0x8FA4, KANJI_RARELY_USED, // 蟀 + 0x8FA5, KANJI_RARELY_USED, // 蟥 + 0x8FA6, KANJI_RARELY_USED, // 蟊 + 0x8FB5, KANJI_RARELY_USED, // 蟵 + 0x8FB6, KANJI_RARELY_USED, // 蟶 + 0x8FB8, KANJI_RARELY_USED, // 蟞 + 0x8FBE, KANJI_RARELY_USED, // 蟟 + 0x8FC0, KANJI_RARELY_USED, // 迀 + 0x8FC1, KANJI_RARELY_USED, // 迁 + 0x8FC6, KANJI_RARELY_USED, // 迆 + 0x8FCA, KANJI_RARELY_USED, // 迊 + 0x8FCB, KANJI_RARELY_USED, // 迋 + 0x8FCD, KANJI_RARELY_USED, // 迍 + 0x8FD0, KANJI_RARELY_USED, // 运 + 0x8FD2, KANJI_RARELY_USED, // 迒 + 0x8FD3, KANJI_RARELY_USED, // 迓 + 0x8FD5, KANJI_RARELY_USED, // 迕 + 0x8FE0, KANJI_RARELY_USED, // è¿  + 0x8FE3, KANJI_RARELY_USED, // è¿£ + 0x8FE4, KANJI_RARELY_USED, // è¿€ + 0x8FE8, KANJI_RARELY_USED, // 迚 + 0x8FEE, KANJI_RARELY_USED, // è¿® + 0x8FF1, KANJI_RARELY_USED, // 迱 + 0x8FF5, KANJI_RARELY_USED, // 迵 + 0x8FF6, KANJI_RARELY_USED, // è¿¶ + 0x8FFB, KANJI_RARELY_USED, // è¿» + 0x8FFE, KANJI_RARELY_USED, // 迟 + 0x9002, KANJI_RARELY_USED, // 适 + 0x9004, KANJI_RARELY_USED, // 逄 + 0x9008, KANJI_RARELY_USED, // 逈 + 0x900C, KANJI_RARELY_USED, // 逌 + 0x9018, KANJI_RARELY_USED, // 逘 + 0x901B, KANJI_RARELY_USED, // 逛 + 0x9028, KANJI_RARELY_USED, // 逹 + 0x9029, KANJI_RARELY_USED, // 逩 + 0x902F, KANJI_RARELY_USED, // 逯 + 0x902A, KANJI_RARELY_USED, // 逪 + 0x902C, KANJI_RARELY_USED, // 逬 + 0x902D, KANJI_RARELY_USED, // 逭 + 0x9033, KANJI_RARELY_USED, // 逳 + 0x9034, KANJI_RARELY_USED, // 逮 + 0x9037, KANJI_RARELY_USED, // 逷 + 0x903F, KANJI_RARELY_USED, // 逿 + 0x9043, KANJI_RARELY_USED, // 遃 + 0x9044, KANJI_RARELY_USED, // 遄 + 0x904C, KANJI_RARELY_USED, // 遌 + 0x905B, KANJI_RARELY_USED, // 遛 + 0x905D, KANJI_RARELY_USED, // 遝 + 0x9062, KANJI_RARELY_USED, // 遢 + 0x9066, KANJI_RARELY_USED, // 遊 + 0x9067, KANJI_RARELY_USED, // 遧 + 0x906C, KANJI_RARELY_USED, // 遬 + 0x9070, KANJI_RARELY_USED, // 遰 + 0x9074, KANJI_RARELY_USED, // 過 + 0x9079, KANJI_RARELY_USED, // 遹 + 0x9085, KANJI_RARELY_USED, // 邅 + 0x9088, KANJI_RARELY_USED, // 邈 + 0x908B, KANJI_RARELY_USED, // 邋 + 0x908C, KANJI_RARELY_USED, // 邌 + 0x908E, KANJI_RARELY_USED, // 邎 + 0x9090, KANJI_RARELY_USED, // 邐 + 0x9095, KANJI_RARELY_USED, // 邕 + 0x9097, KANJI_RARELY_USED, // 邗 + 0x9098, KANJI_RARELY_USED, // 邘 + 0x9099, KANJI_RARELY_USED, // 邙 + 0x909B, KANJI_RARELY_USED, // 邛 + 0x90A0, KANJI_RARELY_USED, // 邠 + 0x90A1, KANJI_RARELY_USED, // 邡 + 0x90A2, KANJI_RARELY_USED, // 邢 + 0x90A5, KANJI_RARELY_USED, // 邥 + 0x90B0, KANJI_RARELY_USED, // 邰 + 0x90B2, KANJI_RARELY_USED, // 邲 + 0x90B3, KANJI_RARELY_USED, // 邳 + 0x90B4, KANJI_RARELY_USED, // 邮 + 0x90B6, KANJI_RARELY_USED, // 邶 + 0x90BD, KANJI_RARELY_USED, // 邜 + 0x90CC, KANJI_RARELY_USED, // 郌 + 0x90BE, KANJI_RARELY_USED, // 邟 + 0x90C3, KANJI_RARELY_USED, // 郃 + 0x90C4, KANJI_RARELY_USED, // 郄 + 0x90C5, KANJI_RARELY_USED, // 郅 + 0x90C7, KANJI_RARELY_USED, // 郇 + 0x90C8, KANJI_RARELY_USED, // 郈 + 0x90D5, KANJI_RARELY_USED, // 郕 + 0x90D7, KANJI_RARELY_USED, // 郗 + 0x90D8, KANJI_RARELY_USED, // 郘 + 0x90D9, KANJI_RARELY_USED, // 郙 + 0x90DC, KANJI_RARELY_USED, // 郜 + 0x90DD, KANJI_RARELY_USED, // 郝 + 0x90DF, KANJI_RARELY_USED, // 郟 + 0x90E5, KANJI_RARELY_USED, // 郥 + 0x90D2, KANJI_RARELY_USED, // 郒 + 0x90F6, KANJI_RARELY_USED, // 郶 + 0x90EB, KANJI_RARELY_USED, // 郫 + 0x90EF, KANJI_RARELY_USED, // 郯 + 0x90F0, KANJI_RARELY_USED, // 郰 + 0x90F4, KANJI_RARELY_USED, // 郎 + 0x90FE, KANJI_RARELY_USED, // 郟 + 0x90FF, KANJI_RARELY_USED, // 郿 + 0x9100, KANJI_RARELY_USED, // 鄀 + 0x9104, KANJI_RARELY_USED, // 鄄 + 0x9105, KANJI_RARELY_USED, // 鄅 + 0x9106, KANJI_RARELY_USED, // 鄆 + 0x9108, KANJI_RARELY_USED, // 鄈 + 0x910D, KANJI_RARELY_USED, // 鄍 + 0x9110, KANJI_RARELY_USED, // 鄐 + 0x9114, KANJI_RARELY_USED, // 鄔 + 0x9116, KANJI_RARELY_USED, // 鄖 + 0x9117, KANJI_RARELY_USED, // 鄗 + 0x9118, KANJI_RARELY_USED, // 鄘 + 0x911A, KANJI_RARELY_USED, // 鄚 + 0x911C, KANJI_RARELY_USED, // 鄜 + 0x911E, KANJI_RARELY_USED, // 鄞 + 0x9120, KANJI_RARELY_USED, // 鄠 + 0x9125, KANJI_RARELY_USED, // 鄥 + 0x9122, KANJI_RARELY_USED, // 鄢 + 0x9123, KANJI_RARELY_USED, // 鄣 + 0x9127, KANJI_RARELY_USED, // 鄧 + 0x9129, KANJI_RARELY_USED, // 鄩 + 0x912E, KANJI_RARELY_USED, // 鄮 + 0x912F, KANJI_RARELY_USED, // 鄯 + 0x9131, KANJI_RARELY_USED, // 鄱 + 0x9134, KANJI_RARELY_USED, // 鄮 + 0x9136, KANJI_RARELY_USED, // 鄶 + 0x9137, KANJI_RARELY_USED, // 鄷 + 0x9139, KANJI_RARELY_USED, // 鄹 + 0x913A, KANJI_RARELY_USED, // 鄺 + 0x913C, KANJI_RARELY_USED, // 鄌 + 0x913D, KANJI_RARELY_USED, // 鄜 + 0x9143, KANJI_RARELY_USED, // 酃 + 0x9147, KANJI_RARELY_USED, // 酇 + 0x9148, KANJI_RARELY_USED, // 酈 + 0x914F, KANJI_RARELY_USED, // 酏 + 0x9153, KANJI_RARELY_USED, // 酓 + 0x9157, KANJI_RARELY_USED, // 酗 + 0x9159, KANJI_RARELY_USED, // 酙 + 0x915A, KANJI_RARELY_USED, // 酚 + 0x915B, KANJI_RARELY_USED, // 酛 + 0x9161, KANJI_RARELY_USED, // 酡 + 0x9164, KANJI_RARELY_USED, // é…€ + 0x9167, KANJI_RARELY_USED, // 酧 + 0x916D, KANJI_RARELY_USED, // 酭 + 0x9174, KANJI_RARELY_USED, // 酮 + 0x9179, KANJI_RARELY_USED, // 酹 + 0x917A, KANJI_RARELY_USED, // 酺 + 0x917B, KANJI_RARELY_USED, // 酻 + 0x9181, KANJI_RARELY_USED, // 醁 + 0x9183, KANJI_RARELY_USED, // 醃 + 0x9185, KANJI_RARELY_USED, // 醅 + 0x9186, KANJI_RARELY_USED, // 醆 + 0x918A, KANJI_RARELY_USED, // 醊 + 0x918E, KANJI_RARELY_USED, // 醎 + 0x9191, KANJI_RARELY_USED, // 醑 + 0x9193, KANJI_RARELY_USED, // 醓 + 0x9194, KANJI_RARELY_USED, // 醔 + 0x9195, KANJI_RARELY_USED, // 醕 + 0x9198, KANJI_RARELY_USED, // 醘 + 0x919E, KANJI_RARELY_USED, // 醞 + 0x91A1, KANJI_RARELY_USED, // 醡 + 0x91A6, KANJI_RARELY_USED, // 醩 + 0x91A8, KANJI_RARELY_USED, // 醹 + 0x91AC, KANJI_RARELY_USED, // 醬 + 0x91AD, KANJI_RARELY_USED, // 醭 + 0x91AE, KANJI_RARELY_USED, // 醮 + 0x91B0, KANJI_RARELY_USED, // 醰 + 0x91B1, KANJI_RARELY_USED, // 醱 + 0x91B2, KANJI_RARELY_USED, // 醲 + 0x91B3, KANJI_RARELY_USED, // 醳 + 0x91B6, KANJI_RARELY_USED, // 醶 + 0x91BB, KANJI_RARELY_USED, // 醻 + 0x91BC, KANJI_RARELY_USED, // 醌 + 0x91BD, KANJI_RARELY_USED, // 醜 + 0x91BF, KANJI_RARELY_USED, // 醿 + 0x91C2, KANJI_RARELY_USED, // 釂 + 0x91C3, KANJI_RARELY_USED, // 釃 + 0x91C5, KANJI_RARELY_USED, // 釅 + 0x91D3, KANJI_RARELY_USED, // 釓 + 0x91D4, KANJI_RARELY_USED, // 釔 + 0x91D7, KANJI_RARELY_USED, // 釗 + 0x91D9, KANJI_RARELY_USED, // 釙 + 0x91DA, KANJI_RARELY_USED, // 釚 + 0x91DE, KANJI_RARELY_USED, // 釞 + 0x91E4, KANJI_RARELY_USED, // 釀 + 0x91E5, KANJI_RARELY_USED, // 釥 + 0x91E9, KANJI_RARELY_USED, // 釩 + 0x91EA, KANJI_RARELY_USED, // 釪 + 0x91EC, KANJI_RARELY_USED, // 釬 + 0x91ED, KANJI_RARELY_USED, // 釭 + 0x91EE, KANJI_RARELY_USED, // 釮 + 0x91EF, KANJI_RARELY_USED, // 釯 + 0x91F0, KANJI_RARELY_USED, // 釰 + 0x91F1, KANJI_RARELY_USED, // 釱 + 0x91F7, KANJI_RARELY_USED, // 釷 + 0x91F9, KANJI_RARELY_USED, // 釹 + 0x91FB, KANJI_RARELY_USED, // 釻 + 0x91FD, KANJI_RARELY_USED, // 釜 + 0x9200, KANJI_RARELY_USED, // 鈀 + 0x9201, KANJI_RARELY_USED, // 鈁 + 0x9204, KANJI_RARELY_USED, // 鈄 + 0x9205, KANJI_RARELY_USED, // 鈅 + 0x9206, KANJI_RARELY_USED, // 鈆 + 0x9207, KANJI_RARELY_USED, // 鈇 + 0x9209, KANJI_RARELY_USED, // 鈉 + 0x920A, KANJI_RARELY_USED, // 鈊 + 0x920C, KANJI_RARELY_USED, // 鈌 + 0x9210, KANJI_RARELY_USED, // 鈐 + 0x9212, KANJI_RARELY_USED, // 鈒 + 0x9213, KANJI_RARELY_USED, // 鈓 + 0x9216, KANJI_RARELY_USED, // 鈖 + 0x9218, KANJI_RARELY_USED, // 鈘 + 0x921C, KANJI_RARELY_USED, // 鈜 + 0x921D, KANJI_RARELY_USED, // 鈝 + 0x9223, KANJI_RARELY_USED, // 鈣 + 0x9224, KANJI_RARELY_USED, // 鈀 + 0x9225, KANJI_RARELY_USED, // 鈥 + 0x9226, KANJI_RARELY_USED, // 鈊 + 0x9228, KANJI_RARELY_USED, // 鈚 + 0x922E, KANJI_RARELY_USED, // 鈮 + 0x922F, KANJI_RARELY_USED, // 鈯 + 0x9230, KANJI_RARELY_USED, // 鈰 + 0x9233, KANJI_RARELY_USED, // 鈳 + 0x9235, KANJI_RARELY_USED, // 鈵 + 0x9236, KANJI_RARELY_USED, // 鈶 + 0x9238, KANJI_RARELY_USED, // 鈞 + 0x9239, KANJI_RARELY_USED, // 鈹 + 0x923A, KANJI_RARELY_USED, // 鈺 + 0x923C, KANJI_RARELY_USED, // 鈌 + 0x923E, KANJI_RARELY_USED, // 鈟 + 0x9240, KANJI_RARELY_USED, // 鉀 + 0x9242, KANJI_RARELY_USED, // 鉂 + 0x9243, KANJI_RARELY_USED, // 鉃 + 0x9246, KANJI_RARELY_USED, // 鉆 + 0x9247, KANJI_RARELY_USED, // 鉇 + 0x924A, KANJI_RARELY_USED, // 鉊 + 0x924D, KANJI_RARELY_USED, // 鉍 + 0x924E, KANJI_RARELY_USED, // 鉎 + 0x924F, KANJI_RARELY_USED, // 鉏 + 0x9251, KANJI_RARELY_USED, // 鉑 + 0x9258, KANJI_RARELY_USED, // 鉘 + 0x9259, KANJI_RARELY_USED, // 鉙 + 0x925C, KANJI_RARELY_USED, // 鉜 + 0x925D, KANJI_RARELY_USED, // 鉝 + 0x9260, KANJI_RARELY_USED, // 鉠 + 0x9261, KANJI_RARELY_USED, // 鉡 + 0x9265, KANJI_RARELY_USED, // 鉥 + 0x9267, KANJI_RARELY_USED, // 鉧 + 0x9268, KANJI_RARELY_USED, // 鉹 + 0x9269, KANJI_RARELY_USED, // 鉩 + 0x926E, KANJI_RARELY_USED, // 鉮 + 0x926F, KANJI_RARELY_USED, // 鉯 + 0x9270, KANJI_RARELY_USED, // 鉰 + 0x9275, KANJI_RARELY_USED, // 鉵 + 0x9276, KANJI_RARELY_USED, // 鉶 + 0x9277, KANJI_RARELY_USED, // 鉷 + 0x9278, KANJI_RARELY_USED, // 鉾 + 0x9279, KANJI_RARELY_USED, // 鉹 + 0x927B, KANJI_RARELY_USED, // 鉻 + 0x927C, KANJI_RARELY_USED, // 鉌 + 0x927D, KANJI_RARELY_USED, // 鉜 + 0x927F, KANJI_RARELY_USED, // 鉿 + 0x9288, KANJI_RARELY_USED, // 銈 + 0x9289, KANJI_RARELY_USED, // 銉 + 0x928A, KANJI_RARELY_USED, // 銊 + 0x928D, KANJI_RARELY_USED, // 銍 + 0x928E, KANJI_RARELY_USED, // 銎 + 0x9292, KANJI_RARELY_USED, // 銒 + 0x9297, KANJI_RARELY_USED, // 銗 + 0x9299, KANJI_RARELY_USED, // 銙 + 0x929F, KANJI_RARELY_USED, // 銟 + 0x92A0, KANJI_RARELY_USED, // 銠 + 0x92A4, KANJI_RARELY_USED, // 銀 + 0x92A5, KANJI_RARELY_USED, // 銥 + 0x92A7, KANJI_RARELY_USED, // 銧 + 0x92A8, KANJI_RARELY_USED, // 銹 + 0x92AB, KANJI_RARELY_USED, // 銫 + 0x92AF, KANJI_RARELY_USED, // 銯 + 0x92B2, KANJI_RARELY_USED, // 銲 + 0x92B6, KANJI_RARELY_USED, // 銶 + 0x92B8, KANJI_RARELY_USED, // 銾 + 0x92BA, KANJI_RARELY_USED, // 銺 + 0x92BB, KANJI_RARELY_USED, // 銻 + 0x92BC, KANJI_RARELY_USED, // 銌 + 0x92BD, KANJI_RARELY_USED, // 銜 + 0x92BF, KANJI_RARELY_USED, // 銿 + 0x92C0, KANJI_RARELY_USED, // 鋀 + 0x92C1, KANJI_RARELY_USED, // 鋁 + 0x92C2, KANJI_RARELY_USED, // 鋂 + 0x92C3, KANJI_RARELY_USED, // 鋃 + 0x92C5, KANJI_RARELY_USED, // 鋅 + 0x92C6, KANJI_RARELY_USED, // 鋆 + 0x92C7, KANJI_RARELY_USED, // 鋇 + 0x92C8, KANJI_RARELY_USED, // 鋈 + 0x92CB, KANJI_RARELY_USED, // 鋋 + 0x92CC, KANJI_RARELY_USED, // 鋌 + 0x92CD, KANJI_RARELY_USED, // 鋍 + 0x92CE, KANJI_RARELY_USED, // 鋎 + 0x92D0, KANJI_RARELY_USED, // 鋐 + 0x92D3, KANJI_RARELY_USED, // 鋓 + 0x92D5, KANJI_RARELY_USED, // 鋕 + 0x92D7, KANJI_RARELY_USED, // 鋗 + 0x92D8, KANJI_RARELY_USED, // 鋘 + 0x92D9, KANJI_RARELY_USED, // 鋙 + 0x92DC, KANJI_RARELY_USED, // 鋜 + 0x92DD, KANJI_RARELY_USED, // 鋝 + 0x92DF, KANJI_RARELY_USED, // 鋟 + 0x92E0, KANJI_RARELY_USED, // 鋠 + 0x92E1, KANJI_RARELY_USED, // 鋡 + 0x92E3, KANJI_RARELY_USED, // 鋣 + 0x92E5, KANJI_RARELY_USED, // 鋥 + 0x92E7, KANJI_RARELY_USED, // 鋧 + 0x92E8, KANJI_RARELY_USED, // 鋹 + 0x92EC, KANJI_RARELY_USED, // 鋬 + 0x92EE, KANJI_RARELY_USED, // 鋮 + 0x92F0, KANJI_RARELY_USED, // 鋰 + 0x92F9, KANJI_RARELY_USED, // 鋹 + 0x92FB, KANJI_RARELY_USED, // 鋻 + 0x92FF, KANJI_RARELY_USED, // 鋿 + 0x9300, KANJI_RARELY_USED, // 錀 + 0x9302, KANJI_RARELY_USED, // 錂 + 0x9308, KANJI_RARELY_USED, // 錈 + 0x930D, KANJI_RARELY_USED, // 錍 + 0x9311, KANJI_RARELY_USED, // 錑 + 0x9314, KANJI_RARELY_USED, // 錔 + 0x9315, KANJI_RARELY_USED, // 錕 + 0x931C, KANJI_RARELY_USED, // 錜 + 0x931D, KANJI_RARELY_USED, // 錝 + 0x931E, KANJI_RARELY_USED, // 錞 + 0x931F, KANJI_RARELY_USED, // 錟 + 0x9321, KANJI_RARELY_USED, // 錡 + 0x9324, KANJI_RARELY_USED, // 錀 + 0x9325, KANJI_RARELY_USED, // 錥 + 0x9327, KANJI_RARELY_USED, // 錧 + 0x9329, KANJI_RARELY_USED, // 錩 + 0x932A, KANJI_RARELY_USED, // 錪 + 0x9333, KANJI_RARELY_USED, // 錳 + 0x9334, KANJI_RARELY_USED, // 錮 + 0x9336, KANJI_RARELY_USED, // 錶 + 0x9337, KANJI_RARELY_USED, // 錷 + 0x9347, KANJI_RARELY_USED, // 鍇 + 0x9348, KANJI_RARELY_USED, // 鍈 + 0x9349, KANJI_RARELY_USED, // 鍉 + 0x9350, KANJI_RARELY_USED, // 鍐 + 0x9351, KANJI_RARELY_USED, // 鍑 + 0x9352, KANJI_RARELY_USED, // 鍒 + 0x9355, KANJI_RARELY_USED, // 鍕 + 0x9357, KANJI_RARELY_USED, // 鍗 + 0x9358, KANJI_RARELY_USED, // 鍘 + 0x935A, KANJI_RARELY_USED, // 鍚 + 0x935E, KANJI_RARELY_USED, // 鍞 + 0x9364, KANJI_RARELY_USED, // 鍀 + 0x9365, KANJI_RARELY_USED, // 鍥 + 0x9367, KANJI_RARELY_USED, // 鍧 + 0x9369, KANJI_RARELY_USED, // 鍩 + 0x936A, KANJI_RARELY_USED, // 鍪 + 0x936D, KANJI_RARELY_USED, // 鍭 + 0x936F, KANJI_RARELY_USED, // 鍯 + 0x9370, KANJI_RARELY_USED, // 鍰 + 0x9371, KANJI_RARELY_USED, // 鍱 + 0x9373, KANJI_RARELY_USED, // 鍳 + 0x9374, KANJI_RARELY_USED, // 鍎 + 0x9376, KANJI_RARELY_USED, // 鍶 + 0x937A, KANJI_RARELY_USED, // 鍺 + 0x937D, KANJI_RARELY_USED, // 鍜 + 0x937F, KANJI_RARELY_USED, // 鍿 + 0x9380, KANJI_RARELY_USED, // 鎀 + 0x9381, KANJI_RARELY_USED, // 鎁 + 0x9382, KANJI_RARELY_USED, // 鎂 + 0x9388, KANJI_RARELY_USED, // 鎈 + 0x938A, KANJI_RARELY_USED, // 鎊 + 0x938B, KANJI_RARELY_USED, // 鎋 + 0x938D, KANJI_RARELY_USED, // 鎍 + 0x938F, KANJI_RARELY_USED, // 鎏 + 0x9392, KANJI_RARELY_USED, // 鎒 + 0x9395, KANJI_RARELY_USED, // 鎕 + 0x9398, KANJI_RARELY_USED, // 鎘 + 0x939B, KANJI_RARELY_USED, // 鎛 + 0x939E, KANJI_RARELY_USED, // 鎞 + 0x93A1, KANJI_RARELY_USED, // 鎡 + 0x93A3, KANJI_RARELY_USED, // 鎣 + 0x93A4, KANJI_RARELY_USED, // 鎀 + 0x93A6, KANJI_RARELY_USED, // 鎊 + 0x93A8, KANJI_RARELY_USED, // 鎚 + 0x93AB, KANJI_RARELY_USED, // 鎫 + 0x93B4, KANJI_RARELY_USED, // 鎮 + 0x93B5, KANJI_RARELY_USED, // 鎵 + 0x93B6, KANJI_RARELY_USED, // 鎶 + 0x93BA, KANJI_RARELY_USED, // 鎺 + 0x93A9, KANJI_RARELY_USED, // 鎩 + 0x93C1, KANJI_RARELY_USED, // 鏁 + 0x93C4, KANJI_RARELY_USED, // 鏄 + 0x93C5, KANJI_RARELY_USED, // 鏅 + 0x93C6, KANJI_RARELY_USED, // 鏆 + 0x93C7, KANJI_RARELY_USED, // 鏇 + 0x93C9, KANJI_RARELY_USED, // 鏉 + 0x93CA, KANJI_RARELY_USED, // 鏊 + 0x93CB, KANJI_RARELY_USED, // 鏋 + 0x93CC, KANJI_RARELY_USED, // 鏌 + 0x93CD, KANJI_RARELY_USED, // 鏍 + 0x93D3, KANJI_RARELY_USED, // 鏓 + 0x93D9, KANJI_RARELY_USED, // 鏙 + 0x93DC, KANJI_RARELY_USED, // 鏜 + 0x93DE, KANJI_RARELY_USED, // 鏞 + 0x93DF, KANJI_RARELY_USED, // 鏟 + 0x93E2, KANJI_RARELY_USED, // 鏢 + 0x93E6, KANJI_RARELY_USED, // 鏊 + 0x93E7, KANJI_RARELY_USED, // 鏧 + 0x93F9, KANJI_RARELY_USED, // 鏹 + 0x93F7, KANJI_RARELY_USED, // 鏷 + 0x93F8, KANJI_RARELY_USED, // 鏞 + 0x93FA, KANJI_RARELY_USED, // 鏺 + 0x93FB, KANJI_RARELY_USED, // 鏻 + 0x93FD, KANJI_RARELY_USED, // 鏜 + 0x9401, KANJI_RARELY_USED, // 鐁 + 0x9402, KANJI_RARELY_USED, // 鐂 + 0x9404, KANJI_RARELY_USED, // 鐄 + 0x9408, KANJI_RARELY_USED, // 鐈 + 0x9409, KANJI_RARELY_USED, // 鐉 + 0x940D, KANJI_RARELY_USED, // 鐍 + 0x940E, KANJI_RARELY_USED, // 鐎 + 0x940F, KANJI_RARELY_USED, // 鐏 + 0x9415, KANJI_RARELY_USED, // 鐕 + 0x9416, KANJI_RARELY_USED, // 鐖 + 0x9417, KANJI_RARELY_USED, // 鐗 + 0x941F, KANJI_RARELY_USED, // 鐟 + 0x942E, KANJI_RARELY_USED, // 鐮 + 0x942F, KANJI_RARELY_USED, // 鐯 + 0x9431, KANJI_RARELY_USED, // 鐱 + 0x9432, KANJI_RARELY_USED, // 鐲 + 0x9433, KANJI_RARELY_USED, // 鐳 + 0x9434, KANJI_RARELY_USED, // 鐎 + 0x943B, KANJI_RARELY_USED, // 鐻 + 0x943F, KANJI_RARELY_USED, // 鐿 + 0x943D, KANJI_RARELY_USED, // 鐜 + 0x9443, KANJI_RARELY_USED, // 鑃 + 0x9445, KANJI_RARELY_USED, // 鑅 + 0x9448, KANJI_RARELY_USED, // 鑈 + 0x944A, KANJI_RARELY_USED, // 鑊 + 0x944C, KANJI_RARELY_USED, // 鑌 + 0x9455, KANJI_RARELY_USED, // 鑕 + 0x9459, KANJI_RARELY_USED, // 鑙 + 0x945C, KANJI_RARELY_USED, // 鑜 + 0x945F, KANJI_RARELY_USED, // 鑟 + 0x9461, KANJI_RARELY_USED, // 鑡 + 0x9463, KANJI_RARELY_USED, // 鑣 + 0x9468, KANJI_RARELY_USED, // 鑹 + 0x946B, KANJI_RARELY_USED, // 鑫 + 0x946D, KANJI_RARELY_USED, // 鑭 + 0x946E, KANJI_RARELY_USED, // 鑮 + 0x946F, KANJI_RARELY_USED, // 鑯 + 0x9471, KANJI_RARELY_USED, // 鑱 + 0x9472, KANJI_RARELY_USED, // 鑲 + 0x9484, KANJI_RARELY_USED, // 钄 + 0x9483, KANJI_RARELY_USED, // 钃 + 0x9578, KANJI_RARELY_USED, // 镾 + 0x9579, KANJI_RARELY_USED, // 镹 + 0x957E, KANJI_RARELY_USED, // 镟 + 0x9584, KANJI_RARELY_USED, // 閄 + 0x9588, KANJI_RARELY_USED, // 閈 + 0x958C, KANJI_RARELY_USED, // 閌 + 0x958D, KANJI_RARELY_USED, // 閍 + 0x958E, KANJI_RARELY_USED, // 閎 + 0x959D, KANJI_RARELY_USED, // 閝 + 0x959E, KANJI_RARELY_USED, // 閞 + 0x959F, KANJI_RARELY_USED, // 閟 + 0x95A1, KANJI_RARELY_USED, // 閡 + 0x95A6, KANJI_RARELY_USED, // 閩 + 0x95A9, KANJI_RARELY_USED, // 閩 + 0x95AB, KANJI_RARELY_USED, // 閫 + 0x95AC, KANJI_RARELY_USED, // 閬 + 0x95B4, KANJI_RARELY_USED, // 閮 + 0x95B6, KANJI_RARELY_USED, // 閶 + 0x95BA, KANJI_RARELY_USED, // 閺 + 0x95BD, KANJI_RARELY_USED, // é–œ + 0x95BF, KANJI_RARELY_USED, // 閿 + 0x95C6, KANJI_RARELY_USED, // 闆 + 0x95C8, KANJI_RARELY_USED, // 闈 + 0x95C9, KANJI_RARELY_USED, // 闉 + 0x95CB, KANJI_RARELY_USED, // 闋 + 0x95D0, KANJI_RARELY_USED, // 闐 + 0x95D1, KANJI_RARELY_USED, // 闑 + 0x95D2, KANJI_RARELY_USED, // 闒 + 0x95D3, KANJI_RARELY_USED, // 闓 + 0x95D9, KANJI_RARELY_USED, // 闙 + 0x95DA, KANJI_RARELY_USED, // 闚 + 0x95DD, KANJI_RARELY_USED, // 闝 + 0x95DE, KANJI_RARELY_USED, // 闞 + 0x95DF, KANJI_RARELY_USED, // 闟 + 0x95E0, KANJI_RARELY_USED, // 闠 + 0x95E4, KANJI_RARELY_USED, // é—€ + 0x95E6, KANJI_RARELY_USED, // 闩 + 0x961D, KANJI_RARELY_USED, // 阝 + 0x961E, KANJI_RARELY_USED, // 阞 + 0x9622, KANJI_RARELY_USED, // 阢 + 0x9624, KANJI_RARELY_USED, // 阀 + 0x9625, KANJI_RARELY_USED, // 阥 + 0x9626, KANJI_RARELY_USED, // 阊 + 0x962C, KANJI_RARELY_USED, // 阬 + 0x9631, KANJI_RARELY_USED, // 阱 + 0x9633, KANJI_RARELY_USED, // 阳 + 0x9637, KANJI_RARELY_USED, // 阷 + 0x9638, KANJI_RARELY_USED, // 阞 + 0x9639, KANJI_RARELY_USED, // 阹 + 0x963A, KANJI_RARELY_USED, // 阺 + 0x963C, KANJI_RARELY_USED, // 阌 + 0x963D, KANJI_RARELY_USED, // 阜 + 0x9641, KANJI_RARELY_USED, // 陁 + 0x9652, KANJI_RARELY_USED, // 陒 + 0x9654, KANJI_RARELY_USED, // 陔 + 0x9656, KANJI_RARELY_USED, // 陖 + 0x9657, KANJI_RARELY_USED, // 陗 + 0x9658, KANJI_RARELY_USED, // 陘 + 0x9661, KANJI_RARELY_USED, // 陡 + 0x966E, KANJI_RARELY_USED, // 陮 + 0x9674, KANJI_RARELY_USED, // 陮 + 0x967B, KANJI_RARELY_USED, // 陻 + 0x967C, KANJI_RARELY_USED, // 陌 + 0x967E, KANJI_RARELY_USED, // 陟 + 0x967F, KANJI_RARELY_USED, // 陿 + 0x9681, KANJI_RARELY_USED, // 隁 + 0x9682, KANJI_RARELY_USED, // 隂 + 0x9683, KANJI_RARELY_USED, // 隃 + 0x9684, KANJI_RARELY_USED, // 隄 + 0x9689, KANJI_RARELY_USED, // 隉 + 0x9691, KANJI_RARELY_USED, // 隑 + 0x9696, KANJI_RARELY_USED, // 隖 + 0x969A, KANJI_RARELY_USED, // 隚 + 0x969D, KANJI_RARELY_USED, // 隝 + 0x969F, KANJI_RARELY_USED, // 隟 + 0x96A4, KANJI_RARELY_USED, // 隀 + 0x96A5, KANJI_RARELY_USED, // 隥 + 0x96A6, KANJI_RARELY_USED, // 隩 + 0x96A9, KANJI_RARELY_USED, // 隩 + 0x96AE, KANJI_RARELY_USED, // 隮 + 0x96AF, KANJI_RARELY_USED, // 隯 + 0x96B3, KANJI_RARELY_USED, // 隳 + 0x96BA, KANJI_RARELY_USED, // 隺 + 0x96CA, KANJI_RARELY_USED, // 雊 + 0x96D2, KANJI_RARELY_USED, // 雒 + 0x5DB2, KANJI_RARELY_USED, // å¶² + 0x96D8, KANJI_RARELY_USED, // 雘 + 0x96DA, KANJI_RARELY_USED, // 雚 + 0x96DD, KANJI_RARELY_USED, // 雝 + 0x96DE, KANJI_RARELY_USED, // 雞 + 0x96DF, KANJI_RARELY_USED, // 雟 + 0x96E9, KANJI_RARELY_USED, // 雩 + 0x96EF, KANJI_RARELY_USED, // 雯 + 0x96F1, KANJI_RARELY_USED, // 雱 + 0x96FA, KANJI_RARELY_USED, // 雺 + 0x9702, KANJI_RARELY_USED, // 霂 + 0x9703, KANJI_RARELY_USED, // 霃 + 0x9705, KANJI_RARELY_USED, // 霅 + 0x9709, KANJI_RARELY_USED, // 霉 + 0x971A, KANJI_RARELY_USED, // 霚 + 0x971B, KANJI_RARELY_USED, // 霛 + 0x971D, KANJI_RARELY_USED, // 霝 + 0x9721, KANJI_RARELY_USED, // 霡 + 0x9722, KANJI_RARELY_USED, // 霢 + 0x9723, KANJI_RARELY_USED, // 霣 + 0x9728, KANJI_RARELY_USED, // 霹 + 0x9731, KANJI_RARELY_USED, // 霱 + 0x9733, KANJI_RARELY_USED, // 霳 + 0x9741, KANJI_RARELY_USED, // 靁 + 0x9743, KANJI_RARELY_USED, // 靃 + 0x974A, KANJI_RARELY_USED, // 靊 + 0x974E, KANJI_RARELY_USED, // 靎 + 0x974F, KANJI_RARELY_USED, // 靏 + 0x9755, KANJI_RARELY_USED, // 靕 + 0x9757, KANJI_RARELY_USED, // 靗 + 0x9758, KANJI_RARELY_USED, // 靘 + 0x975A, KANJI_RARELY_USED, // 靚 + 0x975B, KANJI_RARELY_USED, // 靛 + 0x9763, KANJI_RARELY_USED, // 靣 + 0x9767, KANJI_RARELY_USED, // 靧 + 0x976A, KANJI_RARELY_USED, // 靪 + 0x976E, KANJI_RARELY_USED, // 靮 + 0x9773, KANJI_RARELY_USED, // 靳 + 0x9776, KANJI_RARELY_USED, // 靶 + 0x9777, KANJI_RARELY_USED, // 靷 + 0x9778, KANJI_RARELY_USED, // 非 + 0x977B, KANJI_RARELY_USED, // 靻 + 0x977D, KANJI_RARELY_USED, // 靜 + 0x977F, KANJI_RARELY_USED, // 靿 + 0x9780, KANJI_RARELY_USED, // 鞀 + 0x9789, KANJI_RARELY_USED, // 鞉 + 0x9795, KANJI_RARELY_USED, // 鞕 + 0x9796, KANJI_RARELY_USED, // 鞖 + 0x9797, KANJI_RARELY_USED, // 鞗 + 0x9799, KANJI_RARELY_USED, // 鞙 + 0x979A, KANJI_RARELY_USED, // 鞚 + 0x979E, KANJI_RARELY_USED, // 鞞 + 0x979F, KANJI_RARELY_USED, // 鞟 + 0x97A2, KANJI_RARELY_USED, // 鞢 + 0x97AC, KANJI_RARELY_USED, // 鞬 + 0x97AE, KANJI_RARELY_USED, // 鞮 + 0x97B1, KANJI_RARELY_USED, // 鞱 + 0x97B2, KANJI_RARELY_USED, // 鞲 + 0x97B5, KANJI_RARELY_USED, // 鞵 + 0x97B6, KANJI_RARELY_USED, // 鞶 + 0x97B8, KANJI_RARELY_USED, // 鞾 + 0x97B9, KANJI_RARELY_USED, // 鞹 + 0x97BA, KANJI_RARELY_USED, // 鞺 + 0x97BC, KANJI_RARELY_USED, // 鞌 + 0x97BE, KANJI_RARELY_USED, // 鞟 + 0x97BF, KANJI_RARELY_USED, // 鞿 + 0x97C1, KANJI_RARELY_USED, // 韁 + 0x97C4, KANJI_RARELY_USED, // 韄 + 0x97C5, KANJI_RARELY_USED, // 韅 + 0x97C7, KANJI_RARELY_USED, // 韇 + 0x97C9, KANJI_RARELY_USED, // 韉 + 0x97CA, KANJI_RARELY_USED, // 韊 + 0x97CC, KANJI_RARELY_USED, // 韌 + 0x97CD, KANJI_RARELY_USED, // 韍 + 0x97CE, KANJI_RARELY_USED, // 韎 + 0x97D0, KANJI_RARELY_USED, // 韐 + 0x97D1, KANJI_RARELY_USED, // 韑 + 0x97D4, KANJI_RARELY_USED, // 韔 + 0x97D7, KANJI_RARELY_USED, // 韗 + 0x97D8, KANJI_RARELY_USED, // 韘 + 0x97D9, KANJI_RARELY_USED, // 韙 + 0x97DD, KANJI_RARELY_USED, // 韝 + 0x97DE, KANJI_RARELY_USED, // 韞 + 0x97E0, KANJI_RARELY_USED, // 韠 + 0x97DB, KANJI_RARELY_USED, // 韛 + 0x97E1, KANJI_RARELY_USED, // 韡 + 0x97E4, KANJI_RARELY_USED, // 韀 + 0x97EF, KANJI_RARELY_USED, // 韯 + 0x97F1, KANJI_RARELY_USED, // 韱 + 0x97F4, KANJI_RARELY_USED, // 韮 + 0x97F7, KANJI_RARELY_USED, // 韷 + 0x97F8, KANJI_RARELY_USED, // 韾 + 0x97FA, KANJI_RARELY_USED, // 韺 + 0x9807, KANJI_RARELY_USED, // 頇 + 0x980A, KANJI_RARELY_USED, // 頊 + 0x9819, KANJI_RARELY_USED, // 頙 + 0x980D, KANJI_RARELY_USED, // 頍 + 0x980E, KANJI_RARELY_USED, // 頎 + 0x9814, KANJI_RARELY_USED, // 頔 + 0x9816, KANJI_RARELY_USED, // 頖 + 0x981C, KANJI_RARELY_USED, // 頜 + 0x981E, KANJI_RARELY_USED, // 頞 + 0x9820, KANJI_RARELY_USED, // é   + 0x9823, KANJI_RARELY_USED, // é £ + 0x9826, KANJI_RARELY_USED, // é Š + 0x982B, KANJI_RARELY_USED, // é « + 0x982E, KANJI_RARELY_USED, // é ® + 0x982F, KANJI_RARELY_USED, // é ¯ + 0x9830, KANJI_RARELY_USED, // é ° + 0x9832, KANJI_RARELY_USED, // é ² + 0x9833, KANJI_RARELY_USED, // é ³ + 0x9835, KANJI_RARELY_USED, // é µ + 0x9825, KANJI_RARELY_USED, // é ¥ + 0x983E, KANJI_RARELY_USED, // é Ÿ + 0x9844, KANJI_RARELY_USED, // 顄 + 0x9847, KANJI_RARELY_USED, // 顇 + 0x984A, KANJI_RARELY_USED, // 顊 + 0x9851, KANJI_RARELY_USED, // 顑 + 0x9852, KANJI_RARELY_USED, // 顒 + 0x9853, KANJI_RARELY_USED, // 顓 + 0x9856, KANJI_RARELY_USED, // 顖 + 0x9857, KANJI_RARELY_USED, // 顗 + 0x9859, KANJI_RARELY_USED, // 顙 + 0x985A, KANJI_RARELY_USED, // 顚 + 0x9862, KANJI_RARELY_USED, // é¡¢ + 0x9863, KANJI_RARELY_USED, // é¡£ + 0x9865, KANJI_RARELY_USED, // é¡¥ + 0x9866, KANJI_RARELY_USED, // 顊 + 0x986A, KANJI_RARELY_USED, // 顪 + 0x986C, KANJI_RARELY_USED, // 顬 + 0x98AB, KANJI_RARELY_USED, // 颫 + 0x98AD, KANJI_RARELY_USED, // 颭 + 0x98AE, KANJI_RARELY_USED, // 颮 + 0x98B0, KANJI_RARELY_USED, // 颰 + 0x98B4, KANJI_RARELY_USED, // 颎 + 0x98B7, KANJI_RARELY_USED, // 颷 + 0x98B8, KANJI_RARELY_USED, // 颞 + 0x98BA, KANJI_RARELY_USED, // 颺 + 0x98BB, KANJI_RARELY_USED, // 颻 + 0x98BF, KANJI_RARELY_USED, // 颿 + 0x98C2, KANJI_RARELY_USED, // 飂 + 0x98C5, KANJI_RARELY_USED, // 飅 + 0x98C8, KANJI_RARELY_USED, // 飈 + 0x98CC, KANJI_RARELY_USED, // 飌 + 0x98E1, KANJI_RARELY_USED, // 飡 + 0x98E3, KANJI_RARELY_USED, // 飣 + 0x98E5, KANJI_RARELY_USED, // 飥 + 0x98E6, KANJI_RARELY_USED, // 飊 + 0x98E7, KANJI_RARELY_USED, // 飧 + 0x98EA, KANJI_RARELY_USED, // 飪 + 0x98F3, KANJI_RARELY_USED, // 飳 + 0x98F6, KANJI_RARELY_USED, // 飶 + 0x9902, KANJI_RARELY_USED, // 适 + 0x9907, KANJI_RARELY_USED, // 逇 + 0x9908, KANJI_RARELY_USED, // 逈 + 0x9911, KANJI_RARELY_USED, // 逑 + 0x9915, KANJI_RARELY_USED, // 逕 + 0x9916, KANJI_RARELY_USED, // 逖 + 0x9917, KANJI_RARELY_USED, // 逗 + 0x991A, KANJI_RARELY_USED, // 通 + 0x991B, KANJI_RARELY_USED, // 逛 + 0x991C, KANJI_RARELY_USED, // 逜 + 0x991F, KANJI_RARELY_USED, // 速 + 0x9922, KANJI_RARELY_USED, // 逢 + 0x9926, KANJI_RARELY_USED, // 逊 + 0x9927, KANJI_RARELY_USED, // 逧 + 0x992B, KANJI_RARELY_USED, // 逫 + 0x9931, KANJI_RARELY_USED, // 週 + 0x9932, KANJI_RARELY_USED, // 進 + 0x9933, KANJI_RARELY_USED, // 逳 + 0x9934, KANJI_RARELY_USED, // 逎 + 0x9935, KANJI_RARELY_USED, // 逵 + 0x9939, KANJI_RARELY_USED, // 逹 + 0x993A, KANJI_RARELY_USED, // 逺 + 0x993B, KANJI_RARELY_USED, // 逻 + 0x993C, KANJI_RARELY_USED, // 逌 + 0x9940, KANJI_RARELY_USED, // 饀 + 0x9941, KANJI_RARELY_USED, // 饁 + 0x9946, KANJI_RARELY_USED, // 饆 + 0x9947, KANJI_RARELY_USED, // 饇 + 0x9948, KANJI_RARELY_USED, // 饈 + 0x994D, KANJI_RARELY_USED, // 饍 + 0x994E, KANJI_RARELY_USED, // 饎 + 0x9954, KANJI_RARELY_USED, // 饔 + 0x9958, KANJI_RARELY_USED, // 饘 + 0x9959, KANJI_RARELY_USED, // 饙 + 0x995B, KANJI_RARELY_USED, // 饛 + 0x995C, KANJI_RARELY_USED, // 饜 + 0x995E, KANJI_RARELY_USED, // 饞 + 0x995F, KANJI_RARELY_USED, // 饟 + 0x9960, KANJI_RARELY_USED, // 饠 + 0x999B, KANJI_RARELY_USED, // 驛 + 0x999D, KANJI_RARELY_USED, // 銝 + 0x999F, KANJI_RARELY_USED, // 驟 + 0x99A6, KANJI_RARELY_USED, // 銊 + 0x99B0, KANJI_RARELY_USED, // 銰 + 0x99B1, KANJI_RARELY_USED, // 銱 + 0x99B2, KANJI_RARELY_USED, // 銲 + 0x99B5, KANJI_RARELY_USED, // 銵 + 0x99B9, KANJI_RARELY_USED, // 銹 + 0x99BA, KANJI_RARELY_USED, // 銺 + 0x99BD, KANJI_RARELY_USED, // 銜 + 0x99BF, KANJI_RARELY_USED, // 銿 + 0x99C3, KANJI_RARELY_USED, // 駃 + 0x99C9, KANJI_RARELY_USED, // 駉 + 0x99D3, KANJI_RARELY_USED, // 駓 + 0x99D4, KANJI_RARELY_USED, // 駔 + 0x99D9, KANJI_RARELY_USED, // 駙 + 0x99DA, KANJI_RARELY_USED, // 駚 + 0x99DC, KANJI_RARELY_USED, // 駜 + 0x99DE, KANJI_RARELY_USED, // 駞 + 0x99E7, KANJI_RARELY_USED, // é§§ + 0x99EA, KANJI_RARELY_USED, // 駪 + 0x99EB, KANJI_RARELY_USED, // é§« + 0x99EC, KANJI_RARELY_USED, // 駬 + 0x99F0, KANJI_RARELY_USED, // é§° + 0x99F4, KANJI_RARELY_USED, // é§Ž + 0x99F5, KANJI_RARELY_USED, // é§µ + 0x99F9, KANJI_RARELY_USED, // é§¹ + 0x99FD, KANJI_RARELY_USED, // é§œ + 0x99FE, KANJI_RARELY_USED, // é§Ÿ + 0x9A02, KANJI_RARELY_USED, // 鹂 + 0x9A03, KANJI_RARELY_USED, // 隃 + 0x9A04, KANJI_RARELY_USED, // 鹄 + 0x9A0B, KANJI_RARELY_USED, // 鹋 + 0x9A0C, KANJI_RARELY_USED, // 鹌 + 0x9A10, KANJI_RARELY_USED, // 隐 + 0x9A11, KANJI_RARELY_USED, // 鹑 + 0x9A16, KANJI_RARELY_USED, // 鹖 + 0x9A1E, KANJI_RARELY_USED, // 隞 + 0x9A20, KANJI_RARELY_USED, // éš  + 0x9A22, KANJI_RARELY_USED, // 隢 + 0x9A23, KANJI_RARELY_USED, // 隣 + 0x9A24, KANJI_RARELY_USED, // 隀 + 0x9A27, KANJI_RARELY_USED, // éš§ + 0x9A2D, KANJI_RARELY_USED, // éš­ + 0x9A2E, KANJI_RARELY_USED, // éš® + 0x9A33, KANJI_RARELY_USED, // éš³ + 0x9A35, KANJI_RARELY_USED, // éšµ + 0x9A36, KANJI_RARELY_USED, // éš¶ + 0x9A38, KANJI_RARELY_USED, // éšž + 0x9A47, KANJI_RARELY_USED, // 驇 + 0x9A41, KANJI_RARELY_USED, // 驁 + 0x9A44, KANJI_RARELY_USED, // 驄 + 0x9A4A, KANJI_RARELY_USED, // 驊 + 0x9A4B, KANJI_RARELY_USED, // 驋 + 0x9A4C, KANJI_RARELY_USED, // 驌 + 0x9A4E, KANJI_RARELY_USED, // 驎 + 0x9A51, KANJI_RARELY_USED, // 驑 + 0x9A54, KANJI_RARELY_USED, // 驔 + 0x9A56, KANJI_RARELY_USED, // 驖 + 0x9A5D, KANJI_RARELY_USED, // 驝 + 0x9AAA, KANJI_RARELY_USED, // 骪 + 0x9AAC, KANJI_RARELY_USED, // 骬 + 0x9AAE, KANJI_RARELY_USED, // 骮 + 0x9AAF, KANJI_RARELY_USED, // 骯 + 0x9AB2, KANJI_RARELY_USED, // 骲 + 0x9AB4, KANJI_RARELY_USED, // 骎 + 0x9AB5, KANJI_RARELY_USED, // 骵 + 0x9AB6, KANJI_RARELY_USED, // 骶 + 0x9AB9, KANJI_RARELY_USED, // 骹 + 0x9ABB, KANJI_RARELY_USED, // 骻 + 0x9ABE, KANJI_RARELY_USED, // 骟 + 0x9ABF, KANJI_RARELY_USED, // 骿 + 0x9AC1, KANJI_RARELY_USED, // 髁 + 0x9AC3, KANJI_RARELY_USED, // 髃 + 0x9AC6, KANJI_RARELY_USED, // 髆 + 0x9AC8, KANJI_RARELY_USED, // 髈 + 0x9ACE, KANJI_RARELY_USED, // 髎 + 0x9AD0, KANJI_RARELY_USED, // 髐 + 0x9AD2, KANJI_RARELY_USED, // 髒 + 0x9AD5, KANJI_RARELY_USED, // 髕 + 0x9AD6, KANJI_RARELY_USED, // 髖 + 0x9AD7, KANJI_RARELY_USED, // 髗 + 0x9ADB, KANJI_RARELY_USED, // 髛 + 0x9ADC, KANJI_RARELY_USED, // 髜 + 0x9AE0, KANJI_RARELY_USED, // é«  + 0x9AE4, KANJI_RARELY_USED, // é«€ + 0x9AE5, KANJI_RARELY_USED, // é«¥ + 0x9AE7, KANJI_RARELY_USED, // é«§ + 0x9AE9, KANJI_RARELY_USED, // é«© + 0x9AEC, KANJI_RARELY_USED, // 髬 + 0x9AF2, KANJI_RARELY_USED, // 髲 + 0x9AF3, KANJI_RARELY_USED, // 髳 + 0x9AF5, KANJI_RARELY_USED, // 髵 + 0x9AF9, KANJI_RARELY_USED, // 髹 + 0x9AFA, KANJI_RARELY_USED, // 髺 + 0x9AFD, KANJI_RARELY_USED, // 髜 + 0x9AFF, KANJI_RARELY_USED, // é«¿ + 0x9B00, KANJI_RARELY_USED, // 鬀 + 0x9B01, KANJI_RARELY_USED, // 鬁 + 0x9B02, KANJI_RARELY_USED, // 鬂 + 0x9B03, KANJI_RARELY_USED, // 鬃 + 0x9B04, KANJI_RARELY_USED, // 鬄 + 0x9B05, KANJI_RARELY_USED, // 鬅 + 0x9B08, KANJI_RARELY_USED, // 鬈 + 0x9B09, KANJI_RARELY_USED, // 鬉 + 0x9B0B, KANJI_RARELY_USED, // 鬋 + 0x9B0C, KANJI_RARELY_USED, // 鬌 + 0x9B0D, KANJI_RARELY_USED, // 鬍 + 0x9B0E, KANJI_RARELY_USED, // 鬎 + 0x9B10, KANJI_RARELY_USED, // 鬐 + 0x9B12, KANJI_RARELY_USED, // 鬒 + 0x9B16, KANJI_RARELY_USED, // 鬖 + 0x9B19, KANJI_RARELY_USED, // 鬙 + 0x9B1B, KANJI_RARELY_USED, // 鬛 + 0x9B1C, KANJI_RARELY_USED, // 鬜 + 0x9B20, KANJI_RARELY_USED, // 鬠 + 0x9B26, KANJI_RARELY_USED, // 鬊 + 0x9B2B, KANJI_RARELY_USED, // 鬫 + 0x9B2D, KANJI_RARELY_USED, // 鬭 + 0x9B33, KANJI_RARELY_USED, // 鬳 + 0x9B34, KANJI_RARELY_USED, // 鬎 + 0x9B35, KANJI_RARELY_USED, // 鬵 + 0x9B37, KANJI_RARELY_USED, // 鬷 + 0x9B39, KANJI_RARELY_USED, // 鬹 + 0x9B3A, KANJI_RARELY_USED, // 鬺 + 0x9B3D, KANJI_RARELY_USED, // 鬜 + 0x9B48, KANJI_RARELY_USED, // 魈 + 0x9B4B, KANJI_RARELY_USED, // 魋 + 0x9B4C, KANJI_RARELY_USED, // 魌 + 0x9B55, KANJI_RARELY_USED, // 魕 + 0x9B56, KANJI_RARELY_USED, // 魖 + 0x9B57, KANJI_RARELY_USED, // 魗 + 0x9B5B, KANJI_RARELY_USED, // 魛 + 0x9B5E, KANJI_RARELY_USED, // 魞 + 0x9B61, KANJI_RARELY_USED, // é­¡ + 0x9B63, KANJI_RARELY_USED, // é­£ + 0x9B65, KANJI_RARELY_USED, // é­¥ + 0x9B66, KANJI_RARELY_USED, // é­Š + 0x9B68, KANJI_RARELY_USED, // é­š + 0x9B6A, KANJI_RARELY_USED, // é­ª + 0x9B6B, KANJI_RARELY_USED, // é­« + 0x9B6C, KANJI_RARELY_USED, // é­¬ + 0x9B6D, KANJI_RARELY_USED, // é­­ + 0x9B6E, KANJI_RARELY_USED, // é­® + 0x9B73, KANJI_RARELY_USED, // é­³ + 0x9B75, KANJI_RARELY_USED, // é­µ + 0x9B77, KANJI_RARELY_USED, // é­· + 0x9B78, KANJI_RARELY_USED, // é­ž + 0x9B79, KANJI_RARELY_USED, // é­¹ + 0x9B7F, KANJI_RARELY_USED, // é­¿ + 0x9B80, KANJI_RARELY_USED, // 鮀 + 0x9B84, KANJI_RARELY_USED, // 鮄 + 0x9B85, KANJI_RARELY_USED, // 鮅 + 0x9B86, KANJI_RARELY_USED, // 鮆 + 0x9B87, KANJI_RARELY_USED, // 鮇 + 0x9B89, KANJI_RARELY_USED, // 鮉 + 0x9B8A, KANJI_RARELY_USED, // 鮊 + 0x9B8B, KANJI_RARELY_USED, // 鮋 + 0x9B8D, KANJI_RARELY_USED, // 鮍 + 0x9B8F, KANJI_RARELY_USED, // 鮏 + 0x9B90, KANJI_RARELY_USED, // 鮐 + 0x9B94, KANJI_RARELY_USED, // 鮔 + 0x9B9A, KANJI_RARELY_USED, // 鮚 + 0x9B9D, KANJI_RARELY_USED, // 鮝 + 0x9B9E, KANJI_RARELY_USED, // 鮞 + 0x9BA6, KANJI_RARELY_USED, // 鮊 + 0x9BA7, KANJI_RARELY_USED, // é®§ + 0x9BA9, KANJI_RARELY_USED, // 鮩 + 0x9BAC, KANJI_RARELY_USED, // 鮬 + 0x9BB0, KANJI_RARELY_USED, // é®° + 0x9BB1, KANJI_RARELY_USED, // é®± + 0x9BB2, KANJI_RARELY_USED, // 鮲 + 0x9BB7, KANJI_RARELY_USED, // é®· + 0x9BB8, KANJI_RARELY_USED, // 鮞 + 0x9BBB, KANJI_RARELY_USED, // é®» + 0x9BBC, KANJI_RARELY_USED, // 鮌 + 0x9BBE, KANJI_RARELY_USED, // 鮟 + 0x9BBF, KANJI_RARELY_USED, // 鮿 + 0x9BC1, KANJI_RARELY_USED, // 鯁 + 0x9BC7, KANJI_RARELY_USED, // 鯇 + 0x9BC8, KANJI_RARELY_USED, // 鯈 + 0x9BCE, KANJI_RARELY_USED, // 鯎 + 0x9BD0, KANJI_RARELY_USED, // 鯐 + 0x9BD7, KANJI_RARELY_USED, // 鯗 + 0x9BD8, KANJI_RARELY_USED, // 鯘 + 0x9BDD, KANJI_RARELY_USED, // 鯝 + 0x9BDF, KANJI_RARELY_USED, // 鯟 + 0x9BE5, KANJI_RARELY_USED, // 鯥 + 0x9BE7, KANJI_RARELY_USED, // 鯧 + 0x9BEA, KANJI_RARELY_USED, // 鯪 + 0x9BEB, KANJI_RARELY_USED, // 鯫 + 0x9BEF, KANJI_RARELY_USED, // 鯯 + 0x9BF3, KANJI_RARELY_USED, // 鯳 + 0x9BF7, KANJI_RARELY_USED, // 鯷 + 0x9BF8, KANJI_RARELY_USED, // 鯞 + 0x9BF9, KANJI_RARELY_USED, // 鯹 + 0x9BFA, KANJI_RARELY_USED, // 鯺 + 0x9BFD, KANJI_RARELY_USED, // 鯜 + 0x9BFF, KANJI_RARELY_USED, // 鯿 + 0x9C00, KANJI_RARELY_USED, // 鰀 + 0x9C02, KANJI_RARELY_USED, // 鰂 + 0x9C0B, KANJI_RARELY_USED, // 鰋 + 0x9C0F, KANJI_RARELY_USED, // 鰏 + 0x9C11, KANJI_RARELY_USED, // 鰑 + 0x9C16, KANJI_RARELY_USED, // 鰖 + 0x9C18, KANJI_RARELY_USED, // 鰘 + 0x9C19, KANJI_RARELY_USED, // 鰙 + 0x9C1A, KANJI_RARELY_USED, // 鰚 + 0x9C1C, KANJI_RARELY_USED, // 鰜 + 0x9C1E, KANJI_RARELY_USED, // 鰞 + 0x9C22, KANJI_RARELY_USED, // é°¢ + 0x9C23, KANJI_RARELY_USED, // é°£ + 0x9C26, KANJI_RARELY_USED, // é°Š + 0x9C27, KANJI_RARELY_USED, // é°§ + 0x9C28, KANJI_RARELY_USED, // é°š + 0x9C29, KANJI_RARELY_USED, // é°© + 0x9C2A, KANJI_RARELY_USED, // é°ª + 0x9C31, KANJI_RARELY_USED, // é°± + 0x9C35, KANJI_RARELY_USED, // é°µ + 0x9C36, KANJI_RARELY_USED, // é°¶ + 0x9C37, KANJI_RARELY_USED, // é°· + 0x9C3D, KANJI_RARELY_USED, // é°œ + 0x9C41, KANJI_RARELY_USED, // 鱁 + 0x9C43, KANJI_RARELY_USED, // 鱃 + 0x9C44, KANJI_RARELY_USED, // 鱄 + 0x9C45, KANJI_RARELY_USED, // 鱅 + 0x9C49, KANJI_RARELY_USED, // 鱉 + 0x9C4A, KANJI_RARELY_USED, // 鱊 + 0x9C4E, KANJI_RARELY_USED, // 鱎 + 0x9C4F, KANJI_RARELY_USED, // 鱏 + 0x9C50, KANJI_RARELY_USED, // 鱐 + 0x9C53, KANJI_RARELY_USED, // 鱓 + 0x9C54, KANJI_RARELY_USED, // 鱔 + 0x9C56, KANJI_RARELY_USED, // 鱖 + 0x9C58, KANJI_RARELY_USED, // 鱘 + 0x9C5B, KANJI_RARELY_USED, // 鱛 + 0x9C5D, KANJI_RARELY_USED, // 鱝 + 0x9C5E, KANJI_RARELY_USED, // 鱞 + 0x9C5F, KANJI_RARELY_USED, // 鱟 + 0x9C63, KANJI_RARELY_USED, // é±£ + 0x9C69, KANJI_RARELY_USED, // 鱩 + 0x9C6A, KANJI_RARELY_USED, // 鱪 + 0x9C5C, KANJI_RARELY_USED, // 鱜 + 0x9C6B, KANJI_RARELY_USED, // 鱫 + 0x9C68, KANJI_RARELY_USED, // 鱚 + 0x9C6E, KANJI_RARELY_USED, // é±® + 0x9C70, KANJI_RARELY_USED, // é±° + 0x9C72, KANJI_RARELY_USED, // é±² + 0x9C75, KANJI_RARELY_USED, // é±µ + 0x9C77, KANJI_RARELY_USED, // é±· + 0x9C7B, KANJI_RARELY_USED, // é±» + 0x9CE6, KANJI_RARELY_USED, // 鳊 + 0x9CF2, KANJI_RARELY_USED, // é³² + 0x9CF7, KANJI_RARELY_USED, // é³· + 0x9CF9, KANJI_RARELY_USED, // é³¹ + 0x9D0B, KANJI_RARELY_USED, // 鮋 + 0x9D02, KANJI_RARELY_USED, // 鮂 + 0x9D11, KANJI_RARELY_USED, // 鮑 + 0x9D17, KANJI_RARELY_USED, // 鮗 + 0x9D18, KANJI_RARELY_USED, // 鎘 + 0x9D1C, KANJI_RARELY_USED, // 鮜 + 0x9D1D, KANJI_RARELY_USED, // 鎝 + 0x9D1E, KANJI_RARELY_USED, // 鮞 + 0x9D2F, KANJI_RARELY_USED, // 鎯 + 0x9D30, KANJI_RARELY_USED, // 鎰 + 0x9D32, KANJI_RARELY_USED, // 鎲 + 0x9D33, KANJI_RARELY_USED, // 鎳 + 0x9D34, KANJI_RARELY_USED, // 鎎 + 0x9D3A, KANJI_RARELY_USED, // 鎺 + 0x9D3C, KANJI_RARELY_USED, // 鎌 + 0x9D45, KANJI_RARELY_USED, // 鵅 + 0x9D3D, KANJI_RARELY_USED, // 鎜 + 0x9D42, KANJI_RARELY_USED, // 鵂 + 0x9D43, KANJI_RARELY_USED, // 鵃 + 0x9D47, KANJI_RARELY_USED, // 鵇 + 0x9D4A, KANJI_RARELY_USED, // 鵊 + 0x9D53, KANJI_RARELY_USED, // 鵓 + 0x9D54, KANJI_RARELY_USED, // 鵔 + 0x9D5F, KANJI_RARELY_USED, // 鵟 + 0x9D63, KANJI_RARELY_USED, // éµ£ + 0x9D62, KANJI_RARELY_USED, // éµ¢ + 0x9D65, KANJI_RARELY_USED, // éµ¥ + 0x9D69, KANJI_RARELY_USED, // 鵩 + 0x9D6A, KANJI_RARELY_USED, // 鵪 + 0x9D6B, KANJI_RARELY_USED, // 鵫 + 0x9D70, KANJI_RARELY_USED, // éµ° + 0x9D76, KANJI_RARELY_USED, // éµ¶ + 0x9D77, KANJI_RARELY_USED, // éµ· + 0x9D7B, KANJI_RARELY_USED, // éµ» + 0x9D7C, KANJI_RARELY_USED, // 鵌 + 0x9D7E, KANJI_RARELY_USED, // 鵟 + 0x9D83, KANJI_RARELY_USED, // 鶃 + 0x9D84, KANJI_RARELY_USED, // 鶄 + 0x9D86, KANJI_RARELY_USED, // 鶆 + 0x9D8A, KANJI_RARELY_USED, // 鶊 + 0x9D8D, KANJI_RARELY_USED, // 鶍 + 0x9D8E, KANJI_RARELY_USED, // 鶎 + 0x9D92, KANJI_RARELY_USED, // 鶒 + 0x9D93, KANJI_RARELY_USED, // 鶓 + 0x9D95, KANJI_RARELY_USED, // 鶕 + 0x9D96, KANJI_RARELY_USED, // 鶖 + 0x9D97, KANJI_RARELY_USED, // 鶗 + 0x9D98, KANJI_RARELY_USED, // 鶘 + 0x9DA1, KANJI_RARELY_USED, // é¶¡ + 0x9DAA, KANJI_RARELY_USED, // 鶪 + 0x9DAC, KANJI_RARELY_USED, // 鶬 + 0x9DAE, KANJI_RARELY_USED, // é¶® + 0x9DB1, KANJI_RARELY_USED, // é¶± + 0x9DB5, KANJI_RARELY_USED, // é¶µ + 0x9DB9, KANJI_RARELY_USED, // é¶¹ + 0x9DBC, KANJI_RARELY_USED, // é¶Œ + 0x9DBF, KANJI_RARELY_USED, // é¶¿ + 0x9DC3, KANJI_RARELY_USED, // 鷃 + 0x9DC7, KANJI_RARELY_USED, // 鷇 + 0x9DC9, KANJI_RARELY_USED, // 鷉 + 0x9DCA, KANJI_RARELY_USED, // 鷊 + 0x9DD4, KANJI_RARELY_USED, // 鷔 + 0x9DD5, KANJI_RARELY_USED, // 鷕 + 0x9DD6, KANJI_RARELY_USED, // 鷖 + 0x9DD7, KANJI_RARELY_USED, // 鷗 + 0x9DDA, KANJI_RARELY_USED, // 鷚 + 0x9DDE, KANJI_RARELY_USED, // 鷞 + 0x9DDF, KANJI_RARELY_USED, // 鷟 + 0x9DE0, KANJI_RARELY_USED, // é·  + 0x9DE5, KANJI_RARELY_USED, // é·¥ + 0x9DE7, KANJI_RARELY_USED, // é·§ + 0x9DE9, KANJI_RARELY_USED, // é·© + 0x9DEB, KANJI_RARELY_USED, // é·« + 0x9DEE, KANJI_RARELY_USED, // é·® + 0x9DF0, KANJI_RARELY_USED, // é·° + 0x9DF3, KANJI_RARELY_USED, // é·³ + 0x9DF4, KANJI_RARELY_USED, // é·Ž + 0x9DFE, KANJI_RARELY_USED, // é·Ÿ + 0x9E0A, KANJI_RARELY_USED, // 龊 + 0x9E02, KANJI_RARELY_USED, // 龂 + 0x9E07, KANJI_RARELY_USED, // 龇 + 0x9E0E, KANJI_RARELY_USED, // 龎 + 0x9E10, KANJI_RARELY_USED, // 鞐 + 0x9E11, KANJI_RARELY_USED, // 龑 + 0x9E12, KANJI_RARELY_USED, // 龒 + 0x9E15, KANJI_RARELY_USED, // 龕 + 0x9E16, KANJI_RARELY_USED, // 龖 + 0x9E19, KANJI_RARELY_USED, // 龙 + 0x9E1C, KANJI_RARELY_USED, // 龜 + 0x9E1D, KANJI_RARELY_USED, // 鞝 + 0x9E7A, KANJI_RARELY_USED, // 鹺 + 0x9E7B, KANJI_RARELY_USED, // é¹» + 0x9E7C, KANJI_RARELY_USED, // 鹌 + 0x9E80, KANJI_RARELY_USED, // 麀 + 0x9E82, KANJI_RARELY_USED, // 麂 + 0x9E83, KANJI_RARELY_USED, // 麃 + 0x9E84, KANJI_RARELY_USED, // 麄 + 0x9E85, KANJI_RARELY_USED, // 麅 + 0x9E87, KANJI_RARELY_USED, // 麇 + 0x9E8E, KANJI_RARELY_USED, // 麎 + 0x9E8F, KANJI_RARELY_USED, // 麏 + 0x9E96, KANJI_RARELY_USED, // 麖 + 0x9E98, KANJI_RARELY_USED, // 麘 + 0x9E9B, KANJI_RARELY_USED, // 麛 + 0x9E9E, KANJI_RARELY_USED, // 麞 + 0x9EA4, KANJI_RARELY_USED, // 麀 + 0x9EA8, KANJI_RARELY_USED, // 麚 + 0x9EAC, KANJI_RARELY_USED, // 麬 + 0x9EAE, KANJI_RARELY_USED, // 麮 + 0x9EAF, KANJI_RARELY_USED, // 麯 + 0x9EB0, KANJI_RARELY_USED, // 麰 + 0x9EB3, KANJI_RARELY_USED, // 麳 + 0x9EB4, KANJI_RARELY_USED, // 麎 + 0x9EB5, KANJI_RARELY_USED, // 麵 + 0x9EC6, KANJI_RARELY_USED, // 黆 + 0x9EC8, KANJI_RARELY_USED, // 黈 + 0x9ECB, KANJI_RARELY_USED, // 黋 + 0x9ED5, KANJI_RARELY_USED, // 黕 + 0x9EDF, KANJI_RARELY_USED, // 黟 + 0x9EE4, KANJI_RARELY_USED, // 黀 + 0x9EE7, KANJI_RARELY_USED, // é»§ + 0x9EEC, KANJI_RARELY_USED, // 黬 + 0x9EED, KANJI_RARELY_USED, // é»­ + 0x9EEE, KANJI_RARELY_USED, // é»® + 0x9EF0, KANJI_RARELY_USED, // é»° + 0x9EF1, KANJI_RARELY_USED, // é»± + 0x9EF2, KANJI_RARELY_USED, // 黲 + 0x9EF5, KANJI_RARELY_USED, // 黵 + 0x9EF8, KANJI_RARELY_USED, // 點 + 0x9EFF, KANJI_RARELY_USED, // 黿 + 0x9F02, KANJI_RARELY_USED, // 錂 + 0x9F03, KANJI_RARELY_USED, // 錃 + 0x9F09, KANJI_RARELY_USED, // 錉 + 0x9F0F, KANJI_RARELY_USED, // 錏 + 0x9F10, KANJI_RARELY_USED, // 錐 + 0x9F11, KANJI_RARELY_USED, // 錑 + 0x9F12, KANJI_RARELY_USED, // 錒 + 0x9F14, KANJI_RARELY_USED, // 錔 + 0x9F16, KANJI_RARELY_USED, // 錖 + 0x9F17, KANJI_RARELY_USED, // 錗 + 0x9F19, KANJI_RARELY_USED, // 錙 + 0x9F1A, KANJI_RARELY_USED, // 錚 + 0x9F1B, KANJI_RARELY_USED, // 錛 + 0x9F1F, KANJI_RARELY_USED, // 錟 + 0x9F22, KANJI_RARELY_USED, // 錢 + 0x9F26, KANJI_RARELY_USED, // 錊 + 0x9F2A, KANJI_RARELY_USED, // 錪 + 0x9F2B, KANJI_RARELY_USED, // 錫 + 0x9F2F, KANJI_RARELY_USED, // 錯 + 0x9F31, KANJI_RARELY_USED, // 錱 + 0x9F32, KANJI_RARELY_USED, // 録 + 0x9F34, KANJI_RARELY_USED, // 錎 + 0x9F37, KANJI_RARELY_USED, // 錷 + 0x9F39, KANJI_RARELY_USED, // 錹 + 0x9F3A, KANJI_RARELY_USED, // 錺 + 0x9F3C, KANJI_RARELY_USED, // 錌 + 0x9F3D, KANJI_RARELY_USED, // 錜 + 0x9F3F, KANJI_RARELY_USED, // 錿 + 0x9F41, KANJI_RARELY_USED, // 霁 + 0x9F43, KANJI_RARELY_USED, // 霃 + 0x9F44, KANJI_RARELY_USED, // 霄 + 0x9F45, KANJI_RARELY_USED, // 霅 + 0x9F46, KANJI_RARELY_USED, // 霆 + 0x9F47, KANJI_RARELY_USED, // 震 + 0x9F53, KANJI_RARELY_USED, // 霓 + 0x9F55, KANJI_RARELY_USED, // 霕 + 0x9F56, KANJI_RARELY_USED, // 霖 + 0x9F57, KANJI_RARELY_USED, // 霗 + 0x9F58, KANJI_RARELY_USED, // 霘 + 0x9F5A, KANJI_RARELY_USED, // 霚 + 0x9F5D, KANJI_RARELY_USED, // 霝 + 0x9F5E, KANJI_RARELY_USED, // 霞 + 0x9F68, KANJI_RARELY_USED, // 霚 + 0x9F69, KANJI_RARELY_USED, // 霩 + 0x9F6D, KANJI_RARELY_USED, // 霭 + 0x9F6E, KANJI_RARELY_USED, // 霮 + 0x9F6F, KANJI_RARELY_USED, // 霯 + 0x9F70, KANJI_RARELY_USED, // 霰 + 0x9F71, KANJI_RARELY_USED, // 霱 + 0x9F73, KANJI_RARELY_USED, // 霳 + 0x9F75, KANJI_RARELY_USED, // 霵 + 0x9F7A, KANJI_RARELY_USED, // 霺 + 0x9F7D, KANJI_RARELY_USED, // 霜 + 0x9F8F, KANJI_RARELY_USED, // 韏 + 0x9F90, KANJI_RARELY_USED, // 韐 + 0x9F91, KANJI_RARELY_USED, // 韑 + 0x9F92, KANJI_RARELY_USED, // 韒 + 0x9F94, KANJI_RARELY_USED, // 韔 + 0x9F96, KANJI_RARELY_USED, // 韖 + 0x9F97, KANJI_RARELY_USED, // 韗 + 0x9F9E, KANJI_RARELY_USED, // 韞 + 0x9FA1, KANJI_RARELY_USED, // 韡 + 0x9FA2, KANJI_RARELY_USED, // 韢 + 0x9FA3, KANJI_RARELY_USED, // 韣 + 0x9FA5, KANJI_RARELY_USED, // 韥 + 0x4FF1, KANJI_LEVEL4, // 俱 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDC0B, KANJI_LEVEL4, // ᅵ + 0x3402, KANJI_LEVEL4, // 㐂 + 0x4E28, KANJI_LEVEL4, // äžš + 0x4E2F, KANJI_LEVEL4, // 䞯 + 0x4E30, KANJI_LEVEL4, // äž° + 0x4E8D, KANJI_LEVEL4, // 亍 + 0x4EE1, KANJI_LEVEL4, // 仡 + 0x4EFD, KANJI_LEVEL4, // 仜 + 0x4EFF, KANJI_LEVEL4, // 仿 + 0x4F03, KANJI_LEVEL4, // 䌃 + 0x4F0B, KANJI_LEVEL4, // 䌋 + 0x4F60, KANJI_LEVEL4, // 䜠 + 0x4F48, KANJI_LEVEL4, // 䜈 + 0x4F49, KANJI_LEVEL4, // 䜉 + 0x4F56, KANJI_LEVEL4, // 䜖 + 0x4F5F, KANJI_LEVEL4, // 䜟 + 0x4F6A, KANJI_LEVEL4, // 䜪 + 0x4F6C, KANJI_LEVEL4, // 䜬 + 0x4F7E, KANJI_LEVEL4, // 䜟 + 0x4F8A, KANJI_LEVEL4, // 䟊 + 0x4F94, KANJI_LEVEL4, // 䟔 + 0x4F97, KANJI_LEVEL4, // 䟗 + 0xFA30, KANJI_LEVEL4, // ïš° + 0x4FC9, KANJI_LEVEL4, // 俉 + 0x4FE0, KANJI_LEVEL4, // ä¿  + 0x5001, KANJI_LEVEL4, // 倁 + 0x5002, KANJI_LEVEL4, // 倂 + 0x500E, KANJI_LEVEL4, // 倎 + 0x5018, KANJI_LEVEL4, // 倘 + 0x5027, KANJI_LEVEL4, // 倧 + 0x502E, KANJI_LEVEL4, // 倮 + 0x5040, KANJI_LEVEL4, // 偀 + 0x503B, KANJI_LEVEL4, // 倻 + 0x5041, KANJI_LEVEL4, // 偁 + 0x5094, KANJI_LEVEL4, // 傔 + 0x50CC, KANJI_LEVEL4, // 僌 + 0x50F2, KANJI_LEVEL4, // 僲 + 0x50D0, KANJI_LEVEL4, // 僐 + 0x50E6, KANJI_LEVEL4, // 僊 + 0xFA31, KANJI_LEVEL4, // ïš± + 0x5106, KANJI_LEVEL4, // 儆 + 0x5103, KANJI_LEVEL4, // 儃 + 0x510B, KANJI_LEVEL4, // 儋 + 0x511E, KANJI_LEVEL4, // 儞 + 0x5135, KANJI_LEVEL4, // 儵 + 0x514A, KANJI_LEVEL4, // 兊 + 0xFA32, KANJI_LEVEL4, // ïš² + 0x5155, KANJI_LEVEL4, // 兕 + 0x5157, KANJI_LEVEL4, // 兗 + 0x34B5, KANJI_LEVEL4, // 㒵 + 0x519D, KANJI_LEVEL4, // 冝 + 0x51C3, KANJI_LEVEL4, // 凃 + 0x51CA, KANJI_LEVEL4, // 凊 + 0x51DE, KANJI_LEVEL4, // 凞 + 0x51E2, KANJI_LEVEL4, // 凢 + 0x51EE, KANJI_LEVEL4, // 凮 + 0x5201, KANJI_LEVEL4, // 刁 + 0x34DB, KANJI_LEVEL4, // 㓛 + 0x5213, KANJI_LEVEL4, // 刓 + 0x5215, KANJI_LEVEL4, // 刕 + 0x5249, KANJI_LEVEL4, // 剉 + 0x5257, KANJI_LEVEL4, // 剗 + 0x5261, KANJI_LEVEL4, // 剡 + 0x5293, KANJI_LEVEL4, // 劓 + 0x52C8, KANJI_LEVEL4, // 勈 + 0xFA33, KANJI_LEVEL4, // ïš³ + 0x52CC, KANJI_LEVEL4, // 勌 + 0x52D0, KANJI_LEVEL4, // 勐 + 0x52D6, KANJI_LEVEL4, // 勖 + 0x52DB, KANJI_LEVEL4, // 勛 + 0xFA34, KANJI_LEVEL4, //  + 0x52F0, KANJI_LEVEL4, // 勰 + 0x52FB, KANJI_LEVEL4, // 勻 + 0x5300, KANJI_LEVEL4, // 匀 + 0x5307, KANJI_LEVEL4, // 匇 + 0x531C, KANJI_LEVEL4, // 匜 + 0xFA35, KANJI_LEVEL4, // ïšµ + 0x5361, KANJI_LEVEL4, // 卡 + 0x5363, KANJI_LEVEL4, // 卣 + 0x537D, KANJI_LEVEL4, // 卜 + 0x5393, KANJI_LEVEL4, // 厓 + 0x539D, KANJI_LEVEL4, // 厝 + 0x53B2, KANJI_LEVEL4, // 厲 + 0x5412, KANJI_LEVEL4, // 吒 + 0x5427, KANJI_LEVEL4, // 吧 + 0x544D, KANJI_LEVEL4, // 呍 + 0x549C, KANJI_LEVEL4, // 咜 + 0x546B, KANJI_LEVEL4, // 呫 + 0x5474, KANJI_LEVEL4, // 呎 + 0x547F, KANJI_LEVEL4, // 呿 + 0x5488, KANJI_LEVEL4, // 咈 + 0x5496, KANJI_LEVEL4, // 咖 + 0x54A1, KANJI_LEVEL4, // 咡 + 0x54A9, KANJI_LEVEL4, // 咩 + 0x54C6, KANJI_LEVEL4, // 哆 + 0x54FF, KANJI_LEVEL4, // 哿 + 0x550E, KANJI_LEVEL4, // 唎 + 0x552B, KANJI_LEVEL4, // 唫 + 0x5535, KANJI_LEVEL4, // 唵 + 0x5550, KANJI_LEVEL4, // 啐 + 0x555E, KANJI_LEVEL4, // 啞 + 0x5581, KANJI_LEVEL4, // 喁 + 0x5586, KANJI_LEVEL4, // 喆 + 0x558E, KANJI_LEVEL4, // 喎 + 0xFA36, KANJI_LEVEL4, // ïš¶ + 0x55AD, KANJI_LEVEL4, // 喭 + 0x55CE, KANJI_LEVEL4, // 嗎 + 0xFA37, KANJI_LEVEL4, // ïš· + 0x5608, KANJI_LEVEL4, // 嘈 + 0x560E, KANJI_LEVEL4, // 嘎 + 0x563B, KANJI_LEVEL4, // 嘻 + 0x5649, KANJI_LEVEL4, // 噉 + 0x5676, KANJI_LEVEL4, // 噶 + 0x5666, KANJI_LEVEL4, // 噊 + 0xFA38, KANJI_LEVEL4, // ïšž + 0x566F, KANJI_LEVEL4, // 噯 + 0x5671, KANJI_LEVEL4, // 噱 + 0x5672, KANJI_LEVEL4, // 噲 + 0x5699, KANJI_LEVEL4, // 嚙 + 0x569E, KANJI_LEVEL4, // 嚞 + 0x56A9, KANJI_LEVEL4, // 嚩 + 0x56AC, KANJI_LEVEL4, // 嚬 + 0x56B3, KANJI_LEVEL4, // 嚳 + 0x56C9, KANJI_LEVEL4, // 囉 + 0x56CA, KANJI_LEVEL4, // 囊 + 0x570A, KANJI_LEVEL4, // 圊 + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDE3D, KANJI_LEVEL4, // ᅵ + 0x5721, KANJI_LEVEL4, // 圡 + 0x572F, KANJI_LEVEL4, // 圯 + 0x5733, KANJI_LEVEL4, // 圳 + 0x5734, KANJI_LEVEL4, // 圎 + 0x5770, KANJI_LEVEL4, // 坰 + 0x5777, KANJI_LEVEL4, // 坷 + 0x577C, KANJI_LEVEL4, // 坌 + 0x579C, KANJI_LEVEL4, // 垜 + 0xFA0F, KANJI_LEVEL4, //  + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDF1B, KANJI_LEVEL4, // ᅵ + 0x57B8, KANJI_LEVEL4, // åžž + 0x57C7, KANJI_LEVEL4, // 埇 + 0x57C8, KANJI_LEVEL4, // 埈 + 0x57CF, KANJI_LEVEL4, // 埏 + 0x57E4, KANJI_LEVEL4, // 埀 + 0x57ED, KANJI_LEVEL4, // 埭 + 0x57F5, KANJI_LEVEL4, // 埵 + 0x57F6, KANJI_LEVEL4, // 埶 + 0x57FF, KANJI_LEVEL4, // 埿 + 0x5809, KANJI_LEVEL4, // 堉 + 0xFA10, KANJI_LEVEL4, //  + 0x5861, KANJI_LEVEL4, // å¡¡ + 0x5864, KANJI_LEVEL4, // å¡€ + 0xFA39, KANJI_LEVEL4, // ïš¹ + 0x587C, KANJI_LEVEL4, // 塌 + 0x5889, KANJI_LEVEL4, // 墉 + 0x589E, KANJI_LEVEL4, // 增 + 0xFA3A, KANJI_LEVEL4, //  + 0x58A9, KANJI_LEVEL4, // 墩 + 0xD845, KANJI_LEVEL4, // ᅵ + 0xDC6E, KANJI_LEVEL4, // ᅵ + 0x58D2, KANJI_LEVEL4, // 壒 + 0x58CE, KANJI_LEVEL4, // 壎 + 0x58D4, KANJI_LEVEL4, // 壔 + 0x58DA, KANJI_LEVEL4, // 壚 + 0x58E0, KANJI_LEVEL4, // 壠 + 0x58E9, KANJI_LEVEL4, // 壩 + 0x590C, KANJI_LEVEL4, // 倌 + 0x8641, KANJI_LEVEL4, // 虁 + 0x595D, KANJI_LEVEL4, // 奝 + 0x596D, KANJI_LEVEL4, // 奭 + 0x598B, KANJI_LEVEL4, // 劋 + 0x5992, KANJI_LEVEL4, // 劒 + 0x59A4, KANJI_LEVEL4, // 劀 + 0x59C3, KANJI_LEVEL4, // 姃 + 0x59D2, KANJI_LEVEL4, // 姒 + 0x59DD, KANJI_LEVEL4, // 姝 + 0x5A13, KANJI_LEVEL4, // åš“ + 0x5A23, KANJI_LEVEL4, // 嚣 + 0x5A67, KANJI_LEVEL4, // å©§ + 0x5A6D, KANJI_LEVEL4, // å©­ + 0x5A77, KANJI_LEVEL4, // å©· + 0x5A7E, KANJI_LEVEL4, // 婟 + 0x5A84, KANJI_LEVEL4, // 媄 + 0x5A9E, KANJI_LEVEL4, // 媞 + 0x5AA7, KANJI_LEVEL4, // 媧 + 0x5AC4, KANJI_LEVEL4, // 嫄 + 0xD846, KANJI_LEVEL4, // ᅵ + 0xDCBD, KANJI_LEVEL4, // ᅵ + 0x5B19, KANJI_LEVEL4, // 嬙 + 0x5B25, KANJI_LEVEL4, // 嬥 + 0x525D, KANJI_LEVEL4, // 剝 + 0x4E9C, KANJI_LEVEL4, // 亜 + 0x5516, KANJI_LEVEL4, // 唖 + 0x5A03, KANJI_LEVEL4, // 嚃 + 0x963F, KANJI_LEVEL4, // 阿 + 0x54C0, KANJI_LEVEL4, // 哀 + 0x611B, KANJI_LEVEL4, // 愛 + 0x6328, KANJI_LEVEL4, // 挚 + 0x59F6, KANJI_LEVEL4, // å§¶ + 0x9022, KANJI_LEVEL4, // 逢 + 0x8475, KANJI_LEVEL4, // 葵 + 0x831C, KANJI_LEVEL4, // 茜 + 0x7A50, KANJI_LEVEL4, // 穐 + 0x60AA, KANJI_LEVEL4, // 悪 + 0x63E1, KANJI_LEVEL4, // 握 + 0x6E25, KANJI_LEVEL4, // 枥 + 0x65ED, KANJI_LEVEL4, // 旭 + 0x8466, KANJI_LEVEL4, // 葊 + 0x82A6, KANJI_LEVEL4, // 芊 + 0x9BF5, KANJI_LEVEL4, // 鯵 + 0x6893, KANJI_LEVEL4, // 梓 + 0x5727, KANJI_LEVEL4, // 圧 + 0x65A1, KANJI_LEVEL4, // 斡 + 0x6271, KANJI_LEVEL4, // 扱 + 0x5B9B, KANJI_LEVEL4, // 宛 + 0x59D0, KANJI_LEVEL4, // 姐 + 0x867B, KANJI_LEVEL4, // 虻 + 0x98F4, KANJI_LEVEL4, // 风 + 0x7D62, KANJI_LEVEL4, // çµ¢ + 0x7DBE, KANJI_LEVEL4, // ç¶Ÿ + 0x9B8E, KANJI_LEVEL4, // 鮎 + 0x6216, KANJI_LEVEL4, // 或 + 0x7C9F, KANJI_LEVEL4, // 粟 + 0x88B7, KANJI_LEVEL4, // 袷 + 0x5B89, KANJI_LEVEL4, // 安 + 0x5EB5, KANJI_LEVEL4, // 庵 + 0x6309, KANJI_LEVEL4, // 按 + 0x6697, KANJI_LEVEL4, // 暗 + 0x6848, KANJI_LEVEL4, // 案 + 0x95C7, KANJI_LEVEL4, // 闇 + 0x978D, KANJI_LEVEL4, // 鞍 + 0x674F, KANJI_LEVEL4, // 杏 + 0x4EE5, KANJI_LEVEL4, // 以 + 0x4F0A, KANJI_LEVEL4, // 䌊 + 0x4F4D, KANJI_LEVEL4, // 䜍 + 0x4F9D, KANJI_LEVEL4, // 䟝 + 0x5049, KANJI_LEVEL4, // 偉 + 0x56F2, KANJI_LEVEL4, // 囲 + 0x5937, KANJI_LEVEL4, // 倷 + 0x59D4, KANJI_LEVEL4, // 委 + 0x5A01, KANJI_LEVEL4, // 嚁 + 0x5C09, KANJI_LEVEL4, // 尉 + 0x60DF, KANJI_LEVEL4, // 惟 + 0x610F, KANJI_LEVEL4, // 意 + 0x6170, KANJI_LEVEL4, // 慰 + 0x6613, KANJI_LEVEL4, // 易 + 0x6905, KANJI_LEVEL4, // 怅 + 0x70BA, KANJI_LEVEL4, // 為 + 0x754F, KANJI_LEVEL4, // 畏 + 0x7570, KANJI_LEVEL4, // 異 + 0x79FB, KANJI_LEVEL4, // ç§» + 0x7DAD, KANJI_LEVEL4, // ç¶­ + 0x7DEF, KANJI_LEVEL4, // ç·¯ + 0x80C3, KANJI_LEVEL4, // 胃 + 0x840E, KANJI_LEVEL4, // 萎 + 0x8863, KANJI_LEVEL4, // è¡£ + 0x8B02, KANJI_LEVEL4, // 謂 + 0x9055, KANJI_LEVEL4, // 違 + 0x907A, KANJI_LEVEL4, // 遺 + 0x533B, KANJI_LEVEL4, // 医 + 0x4E95, KANJI_LEVEL4, // 井 + 0x4EA5, KANJI_LEVEL4, // 亥 + 0x57DF, KANJI_LEVEL4, // 域 + 0x80B2, KANJI_LEVEL4, // 育 + 0x90C1, KANJI_LEVEL4, // 郁 + 0x78EF, KANJI_LEVEL4, // 磯 + 0x4E00, KANJI_LEVEL4, // 侀 + 0x58F1, KANJI_LEVEL4, // 壱 + 0x6EA2, KANJI_LEVEL4, // 溢 + 0x9038, KANJI_LEVEL4, // 逾 + 0x7A32, KANJI_LEVEL4, // çš² + 0x8328, KANJI_LEVEL4, // 茚 + 0x828B, KANJI_LEVEL4, // 芋 + 0x9C2F, KANJI_LEVEL4, // é°¯ + 0x5141, KANJI_LEVEL4, // 允 + 0x5370, KANJI_LEVEL4, // 印 + 0x54BD, KANJI_LEVEL4, // å’œ + 0x54E1, KANJI_LEVEL4, // 員 + 0x56E0, KANJI_LEVEL4, // 因 + 0x59FB, KANJI_LEVEL4, // å§» + 0x5F15, KANJI_LEVEL4, // 匕 + 0x98F2, KANJI_LEVEL4, // 飲 + 0x6DEB, KANJI_LEVEL4, // æ·« + 0x80E4, KANJI_LEVEL4, // 胀 + 0x852D, KANJI_LEVEL4, // 蔭 + 0x9662, KANJI_LEVEL4, // 院 + 0x9670, KANJI_LEVEL4, // 陰 + 0x96A0, KANJI_LEVEL4, // 隠 + 0x97FB, KANJI_LEVEL4, // 韻 + 0x540B, KANJI_LEVEL4, // 吋 + 0x53F3, KANJI_LEVEL4, // 右 + 0x5B87, KANJI_LEVEL4, // 宇 + 0x70CF, KANJI_LEVEL4, // 烏 + 0x7FBD, KANJI_LEVEL4, // 矜 + 0x8FC2, KANJI_LEVEL4, // 迂 + 0x96E8, KANJI_LEVEL4, // 雹 + 0x536F, KANJI_LEVEL4, // 卯 + 0x9D5C, KANJI_LEVEL4, // 鵜 + 0x7ABA, KANJI_LEVEL4, // 窺 + 0x4E11, KANJI_LEVEL4, // 侑 + 0x7893, KANJI_LEVEL4, // 碓 + 0x81FC, KANJI_LEVEL4, // 臌 + 0x6E26, KANJI_LEVEL4, // 枊 + 0x5618, KANJI_LEVEL4, // 嘘 + 0x5504, KANJI_LEVEL4, // 唄 + 0x6B1D, KANJI_LEVEL4, // 欝 + 0x851A, KANJI_LEVEL4, // 蔚 + 0x9C3B, KANJI_LEVEL4, // é°» + 0x59E5, KANJI_LEVEL4, // å§¥ + 0x53A9, KANJI_LEVEL4, // 厩 + 0x6D66, KANJI_LEVEL4, // 浊 + 0x74DC, KANJI_LEVEL4, // 瓜 + 0x958F, KANJI_LEVEL4, // 閏 + 0x5642, KANJI_LEVEL4, // 噂 + 0x4E91, KANJI_LEVEL4, // 云 + 0x904B, KANJI_LEVEL4, // 運 + 0x96F2, KANJI_LEVEL4, // 雲 + 0x834F, KANJI_LEVEL4, // 荏 + 0x990C, KANJI_LEVEL4, // 逌 + 0x53E1, KANJI_LEVEL4, // 叡 + 0x55B6, KANJI_LEVEL4, // 営 + 0x5B30, KANJI_LEVEL4, // 嬰 + 0x5F71, KANJI_LEVEL4, // 圱 + 0x6620, KANJI_LEVEL4, // 映 + 0x66F3, KANJI_LEVEL4, // 曳 + 0x6804, KANJI_LEVEL4, // 栄 + 0x6C38, KANJI_LEVEL4, // æ°ž + 0x6CF3, KANJI_LEVEL4, // æ³³ + 0x6D29, KANJI_LEVEL4, // 掩 + 0x745B, KANJI_LEVEL4, // 瑛 + 0x76C8, KANJI_LEVEL4, // 盈 + 0x7A4E, KANJI_LEVEL4, // 穎 + 0x9834, KANJI_LEVEL4, // é Ž + 0x82F1, KANJI_LEVEL4, // 英 + 0x885B, KANJI_LEVEL4, // 衛 + 0x8A60, KANJI_LEVEL4, // è©  + 0x92ED, KANJI_LEVEL4, // 鋭 + 0x6DB2, KANJI_LEVEL4, // æ¶² + 0x75AB, KANJI_LEVEL4, // 疫 + 0x76CA, KANJI_LEVEL4, // 益 + 0x99C5, KANJI_LEVEL4, // 駅 + 0x60A6, KANJI_LEVEL4, // 悊 + 0x8B01, KANJI_LEVEL4, // 謁 + 0x8D8A, KANJI_LEVEL4, // 越 + 0x95B2, KANJI_LEVEL4, // 閲 + 0x698E, KANJI_LEVEL4, // 抎 + 0x53AD, KANJI_LEVEL4, // 厭 + 0x5186, KANJI_LEVEL4, // 円 + 0x5712, KANJI_LEVEL4, // 園 + 0x5830, KANJI_LEVEL4, // å ° + 0x5944, KANJI_LEVEL4, // 奄 + 0x5BB4, KANJI_LEVEL4, // 宎 + 0x5EF6, KANJI_LEVEL4, // å»¶ + 0x6028, KANJI_LEVEL4, // 怚 + 0x63A9, KANJI_LEVEL4, // 掩 + 0x63F4, KANJI_LEVEL4, // 揎 + 0x6CBF, KANJI_LEVEL4, // 沿 + 0x6F14, KANJI_LEVEL4, // 挔 + 0x708E, KANJI_LEVEL4, // 炎 + 0x7114, KANJI_LEVEL4, // 焔 + 0x7159, KANJI_LEVEL4, // 煙 + 0x71D5, KANJI_LEVEL4, // 燕 + 0x733F, KANJI_LEVEL4, // 猿 + 0x7E01, KANJI_LEVEL4, // 瞁 + 0x8276, KANJI_LEVEL4, // 艶 + 0x82D1, KANJI_LEVEL4, // 苑 + 0x8597, KANJI_LEVEL4, // 薗 + 0x9060, KANJI_LEVEL4, // 遠 + 0x925B, KANJI_LEVEL4, // 鉛 + 0x9D1B, KANJI_LEVEL4, // 鮛 + 0x5869, KANJI_LEVEL4, // å¡© + 0x65BC, KANJI_LEVEL4, // æ–Œ + 0x6C5A, KANJI_LEVEL4, // 汚 + 0x7525, KANJI_LEVEL4, // 甥 + 0x51F9, KANJI_LEVEL4, // 凹 + 0x592E, KANJI_LEVEL4, // 倮 + 0x5965, KANJI_LEVEL4, // 奥 + 0x5F80, KANJI_LEVEL4, // 埀 + 0x5FDC, KANJI_LEVEL4, // 応 + 0x62BC, KANJI_LEVEL4, // 抌 + 0x65FA, KANJI_LEVEL4, // 旺 + 0x6A2A, KANJI_LEVEL4, // 暪 + 0x6B27, KANJI_LEVEL4, // 欧 + 0x6BB4, KANJI_LEVEL4, // 殎 + 0x738B, KANJI_LEVEL4, // 王 + 0x7FC1, KANJI_LEVEL4, // 翁 + 0x8956, KANJI_LEVEL4, // 襖 + 0x9D2C, KANJI_LEVEL4, // 鎬 + 0x9D0E, KANJI_LEVEL4, // 鮎 + 0x9EC4, KANJI_LEVEL4, // 黄 + 0x5CA1, KANJI_LEVEL4, // 岡 + 0x6C96, KANJI_LEVEL4, // 沖 + 0x837B, KANJI_LEVEL4, // 荻 + 0x5104, KANJI_LEVEL4, // 億 + 0x5C4B, KANJI_LEVEL4, // 屋 + 0x61B6, KANJI_LEVEL4, // 憶 + 0x81C6, KANJI_LEVEL4, // 臆 + 0x6876, KANJI_LEVEL4, // æ¡¶ + 0x7261, KANJI_LEVEL4, // 牡 + 0x4E59, KANJI_LEVEL4, // 乙 + 0x4FFA, KANJI_LEVEL4, // 俺 + 0x5378, KANJI_LEVEL4, // 卞 + 0x6069, KANJI_LEVEL4, // 恩 + 0x6E29, KANJI_LEVEL4, // æž© + 0x7A4F, KANJI_LEVEL4, // 穏 + 0x97F3, KANJI_LEVEL4, // 音 + 0x4E0B, KANJI_LEVEL4, // 例 + 0x5316, KANJI_LEVEL4, // 化 + 0x4EEE, KANJI_LEVEL4, // ä»® + 0x4F55, KANJI_LEVEL4, // 䜕 + 0x4F3D, KANJI_LEVEL4, // 䌜 + 0x4FA1, KANJI_LEVEL4, // 䟡 + 0x4F73, KANJI_LEVEL4, // 䜳 + 0x52A0, KANJI_LEVEL4, // 加 + 0x53EF, KANJI_LEVEL4, // 可 + 0x5609, KANJI_LEVEL4, // 嘉 + 0x590F, KANJI_LEVEL4, // 倏 + 0x5AC1, KANJI_LEVEL4, // 嫁 + 0x5BB6, KANJI_LEVEL4, // å®¶ + 0x5BE1, KANJI_LEVEL4, // 寡 + 0x79D1, KANJI_LEVEL4, // 科 + 0x6687, KANJI_LEVEL4, // 暇 + 0x679C, KANJI_LEVEL4, // 果 + 0x67B6, KANJI_LEVEL4, // 架 + 0x6B4C, KANJI_LEVEL4, // 歌 + 0x6CB3, KANJI_LEVEL4, // æ²³ + 0x706B, KANJI_LEVEL4, // 火 + 0x73C2, KANJI_LEVEL4, // 珂 + 0x798D, KANJI_LEVEL4, // 犍 + 0x79BE, KANJI_LEVEL4, // 犟 + 0x7A3C, KANJI_LEVEL4, // 皌 + 0x7B87, KANJI_LEVEL4, // 箇 + 0x82B1, KANJI_LEVEL4, // 花 + 0x82DB, KANJI_LEVEL4, // 苛 + 0x8304, KANJI_LEVEL4, // 茄 + 0x8377, KANJI_LEVEL4, // 荷 + 0x83EF, KANJI_LEVEL4, // 華 + 0x83D3, KANJI_LEVEL4, // 菓 + 0x8766, KANJI_LEVEL4, // 蝊 + 0x8AB2, KANJI_LEVEL4, // 課 + 0x5629, KANJI_LEVEL4, // 嘩 + 0x8CA8, KANJI_LEVEL4, // 貚 + 0x8FE6, KANJI_LEVEL4, // 迊 + 0x904E, KANJI_LEVEL4, // 過 + 0x971E, KANJI_LEVEL4, // 霞 + 0x868A, KANJI_LEVEL4, // 蚊 + 0x4FC4, KANJI_LEVEL4, // 俄 + 0x5CE8, KANJI_LEVEL4, // 峚 + 0x6211, KANJI_LEVEL4, // 我 + 0x7259, KANJI_LEVEL4, // 牙 + 0x753B, KANJI_LEVEL4, // 画 + 0x81E5, KANJI_LEVEL4, // 臥 + 0x82BD, KANJI_LEVEL4, // 芜 + 0x86FE, KANJI_LEVEL4, // 蛟 + 0x8CC0, KANJI_LEVEL4, // 賀 + 0x96C5, KANJI_LEVEL4, // 雅 + 0x9913, KANJI_LEVEL4, // 逓 + 0x99D5, KANJI_LEVEL4, // 駕 + 0x4ECB, KANJI_LEVEL4, // 介 + 0x4F1A, KANJI_LEVEL4, // 䌚 + 0x89E3, KANJI_LEVEL4, // è§£ + 0x56DE, KANJI_LEVEL4, // 回 + 0x584A, KANJI_LEVEL4, // 塊 + 0x58CA, KANJI_LEVEL4, // 壊 + 0x5EFB, KANJI_LEVEL4, // å»» + 0x5FEB, KANJI_LEVEL4, // å¿« + 0x602A, KANJI_LEVEL4, // 怪 + 0x6094, KANJI_LEVEL4, // 悔 + 0x6062, KANJI_LEVEL4, // 恢 + 0x61D0, KANJI_LEVEL4, // 懐 + 0x6212, KANJI_LEVEL4, // 戒 + 0x62D0, KANJI_LEVEL4, // 拐 + 0x6539, KANJI_LEVEL4, // 改 + 0x9B41, KANJI_LEVEL4, // 魁 + 0x6666, KANJI_LEVEL4, // 晊 + 0x68B0, KANJI_LEVEL4, // 械 + 0x6D77, KANJI_LEVEL4, // æµ· + 0x7070, KANJI_LEVEL4, // 灰 + 0x754C, KANJI_LEVEL4, // 界 + 0x7686, KANJI_LEVEL4, // 皆 + 0x7D75, KANJI_LEVEL4, // çµµ + 0x82A5, KANJI_LEVEL4, // 芥 + 0x87F9, KANJI_LEVEL4, // 蟹 + 0x958B, KANJI_LEVEL4, // 開 + 0x968E, KANJI_LEVEL4, // 階 + 0x8C9D, KANJI_LEVEL4, // 貝 + 0x51F1, KANJI_LEVEL4, // 凱 + 0x52BE, KANJI_LEVEL4, // 功 + 0x5916, KANJI_LEVEL4, // 倖 + 0x54B3, KANJI_LEVEL4, // 咳 + 0x5BB3, KANJI_LEVEL4, // 害 + 0x5D16, KANJI_LEVEL4, // 厖 + 0x6168, KANJI_LEVEL4, // æ…š + 0x6982, KANJI_LEVEL4, // 抂 + 0x6DAF, KANJI_LEVEL4, // 涯 + 0x788D, KANJI_LEVEL4, // 碍 + 0x84CB, KANJI_LEVEL4, // 蓋 + 0x8857, KANJI_LEVEL4, // 街 + 0x8A72, KANJI_LEVEL4, // 該 + 0x93A7, KANJI_LEVEL4, // 鎧 + 0x9AB8, KANJI_LEVEL4, // 骞 + 0x6D6C, KANJI_LEVEL4, // 浬 + 0x99A8, KANJI_LEVEL4, // 銚 + 0x86D9, KANJI_LEVEL4, // 蛙 + 0x57A3, KANJI_LEVEL4, // 垣 + 0x67FF, KANJI_LEVEL4, // 柿 + 0x86CE, KANJI_LEVEL4, // 蛎 + 0x920E, KANJI_LEVEL4, // 鈎 + 0x5283, KANJI_LEVEL4, // 劃 + 0x5687, KANJI_LEVEL4, // 嚇 + 0x5404, KANJI_LEVEL4, // 各 + 0x5ED3, KANJI_LEVEL4, // 廓 + 0x62E1, KANJI_LEVEL4, // 拡 + 0x64B9, KANJI_LEVEL4, // 撹 + 0x683C, KANJI_LEVEL4, // æ Œ + 0x6838, KANJI_LEVEL4, // æ ž + 0x6BBB, KANJI_LEVEL4, // æ®» + 0x7372, KANJI_LEVEL4, // 獲 + 0x78BA, KANJI_LEVEL4, // 確 + 0x7A6B, KANJI_LEVEL4, // ç©« + 0x899A, KANJI_LEVEL4, // 芚 + 0x89D2, KANJI_LEVEL4, // 角 + 0x8D6B, KANJI_LEVEL4, // 赫 + 0x8F03, KANJI_LEVEL4, // 范 + 0x90ED, KANJI_LEVEL4, // 郭 + 0x95A3, KANJI_LEVEL4, // 閣 + 0x9694, KANJI_LEVEL4, // 隔 + 0x9769, KANJI_LEVEL4, // 革 + 0x5B66, KANJI_LEVEL4, // å­Š + 0x5CB3, KANJI_LEVEL4, // å²³ + 0x697D, KANJI_LEVEL4, // 楜 + 0x984D, KANJI_LEVEL4, // 額 + 0x984E, KANJI_LEVEL4, // 顎 + 0x639B, KANJI_LEVEL4, // 掛 + 0x7B20, KANJI_LEVEL4, // 笠 + 0x6A2B, KANJI_LEVEL4, // æš« + 0x6A7F, KANJI_LEVEL4, // æ©¿ + 0x68B6, KANJI_LEVEL4, // 梶 + 0x9C0D, KANJI_LEVEL4, // 鰍 + 0x6F5F, KANJI_LEVEL4, // 期 + 0x5272, KANJI_LEVEL4, // 割 + 0x559D, KANJI_LEVEL4, // 喝 + 0x6070, KANJI_LEVEL4, // 恰 + 0x62EC, KANJI_LEVEL4, // 括 + 0x6D3B, KANJI_LEVEL4, // 掻 + 0x6E07, KANJI_LEVEL4, // 枇 + 0x6ED1, KANJI_LEVEL4, // 滑 + 0x845B, KANJI_LEVEL4, // 葛 + 0x8910, KANJI_LEVEL4, // 耐 + 0x8F44, KANJI_LEVEL4, // 蜄 + 0x4E14, KANJI_LEVEL4, // 侔 + 0x9C39, KANJI_LEVEL4, // é°¹ + 0x53F6, KANJI_LEVEL4, // 叶 + 0x691B, KANJI_LEVEL4, // 怛 + 0x6A3A, KANJI_LEVEL4, // 暺 + 0x9784, KANJI_LEVEL4, // 鞄 + 0x682A, KANJI_LEVEL4, // æ ª + 0x515C, KANJI_LEVEL4, // 兜 + 0x7AC3, KANJI_LEVEL4, // 竃 + 0x84B2, KANJI_LEVEL4, // 蒲 + 0x91DC, KANJI_LEVEL4, // 釜 + 0x938C, KANJI_LEVEL4, // 鎌 + 0x565B, KANJI_LEVEL4, // 噛 + 0x9D28, KANJI_LEVEL4, // 鎚 + 0x6822, KANJI_LEVEL4, // æ ¢ + 0x8305, KANJI_LEVEL4, // 茅 + 0x8431, KANJI_LEVEL4, // 萱 + 0x7CA5, KANJI_LEVEL4, // ç²¥ + 0x5208, KANJI_LEVEL4, // 刈 + 0x82C5, KANJI_LEVEL4, // 苅 + 0x74E6, KANJI_LEVEL4, // 瓩 + 0x4E7E, KANJI_LEVEL4, // 也 + 0x4F83, KANJI_LEVEL4, // 䟃 + 0x51A0, KANJI_LEVEL4, // 冠 + 0x5BD2, KANJI_LEVEL4, // 寒 + 0x520A, KANJI_LEVEL4, // 刊 + 0x52D8, KANJI_LEVEL4, // 勘 + 0x52E7, KANJI_LEVEL4, // 勧 + 0x5DFB, KANJI_LEVEL4, // å·» + 0x559A, KANJI_LEVEL4, // 喚 + 0x582A, KANJI_LEVEL4, // å ª + 0x59E6, KANJI_LEVEL4, // å§Š + 0x5B8C, KANJI_LEVEL4, // 完 + 0x5B98, KANJI_LEVEL4, // 官 + 0x5BDB, KANJI_LEVEL4, // 寛 + 0x5E72, KANJI_LEVEL4, // å¹² + 0x5E79, KANJI_LEVEL4, // å¹¹ + 0x60A3, KANJI_LEVEL4, // 患 + 0x611F, KANJI_LEVEL4, // 感 + 0x6163, KANJI_LEVEL4, // 慣 + 0x61BE, KANJI_LEVEL4, // 憟 + 0x63DB, KANJI_LEVEL4, // 換 + 0x6562, KANJI_LEVEL4, // 敢 + 0x67D1, KANJI_LEVEL4, // 柑 + 0x6853, KANJI_LEVEL4, // 桓 + 0x68FA, KANJI_LEVEL4, // 棺 + 0x6B3E, KANJI_LEVEL4, // 欟 + 0x6B53, KANJI_LEVEL4, // 歓 + 0x6C57, KANJI_LEVEL4, // 汗 + 0x6F22, KANJI_LEVEL4, // 挢 + 0x6F97, KANJI_LEVEL4, // 柗 + 0x6F45, KANJI_LEVEL4, // 朅 + 0x74B0, KANJI_LEVEL4, // 環 + 0x7518, KANJI_LEVEL4, // 甘 + 0x76E3, KANJI_LEVEL4, // 監 + 0x770B, KANJI_LEVEL4, // 看 + 0x7AFF, KANJI_LEVEL4, // ç«¿ + 0x7BA1, KANJI_LEVEL4, // 管 + 0x7C21, KANJI_LEVEL4, // ç°¡ + 0x7DE9, KANJI_LEVEL4, // ç·© + 0x7F36, KANJI_LEVEL4, // 猶 + 0x7FF0, KANJI_LEVEL4, // ç¿° + 0x809D, KANJI_LEVEL4, // 肝 + 0x8266, KANJI_LEVEL4, // 艊 + 0x839E, KANJI_LEVEL4, // 莞 + 0x89B3, KANJI_LEVEL4, // 芳 + 0x8ACC, KANJI_LEVEL4, // 諌 + 0x8CAB, KANJI_LEVEL4, // 貫 + 0x9084, KANJI_LEVEL4, // 還 + 0x9451, KANJI_LEVEL4, // 鑑 + 0x9593, KANJI_LEVEL4, // 間 + 0x9591, KANJI_LEVEL4, // 閑 + 0x95A2, KANJI_LEVEL4, // 関 + 0x9665, KANJI_LEVEL4, // 陥 + 0x97D3, KANJI_LEVEL4, // 韓 + 0x9928, KANJI_LEVEL4, // 通 + 0x8218, KANJI_LEVEL4, // 舘 + 0x4E38, KANJI_LEVEL4, // äžž + 0x542B, KANJI_LEVEL4, // 含 + 0x5CB8, KANJI_LEVEL4, // 岞 + 0x5DCC, KANJI_LEVEL4, // 巌 + 0x73A9, KANJI_LEVEL4, // 玩 + 0x764C, KANJI_LEVEL4, // 癌 + 0x773C, KANJI_LEVEL4, // 県 + 0x5CA9, KANJI_LEVEL4, // 岩 + 0x7FEB, KANJI_LEVEL4, // ç¿« + 0x8D0B, KANJI_LEVEL4, // 莋 + 0x96C1, KANJI_LEVEL4, // 雁 + 0x9811, KANJI_LEVEL4, // 頑 + 0x9854, KANJI_LEVEL4, // 顔 + 0x9858, KANJI_LEVEL4, // 願 + 0x4F01, KANJI_LEVEL4, // 䌁 + 0x4F0E, KANJI_LEVEL4, // 䌎 + 0x5371, KANJI_LEVEL4, // 危 + 0x559C, KANJI_LEVEL4, // 喜 + 0x5668, KANJI_LEVEL4, // 噚 + 0x57FA, KANJI_LEVEL4, // 基 + 0x5947, KANJI_LEVEL4, // 奇 + 0x5B09, KANJI_LEVEL4, // 嬉 + 0x5BC4, KANJI_LEVEL4, // 寄 + 0x5C90, KANJI_LEVEL4, // 岐 + 0x5E0C, KANJI_LEVEL4, // 垌 + 0x5E7E, KANJI_LEVEL4, // 幟 + 0x5FCC, KANJI_LEVEL4, // 忌 + 0x63EE, KANJI_LEVEL4, // 揮 + 0x673A, KANJI_LEVEL4, // 机 + 0x65D7, KANJI_LEVEL4, // 旗 + 0x65E2, KANJI_LEVEL4, // 既 + 0x671F, KANJI_LEVEL4, // 期 + 0x68CB, KANJI_LEVEL4, // 棋 + 0x68C4, KANJI_LEVEL4, // 棄 + 0x6A5F, KANJI_LEVEL4, // 機 + 0x5E30, KANJI_LEVEL4, // åž° + 0x6BC5, KANJI_LEVEL4, // 毅 + 0x6C17, KANJI_LEVEL4, // 気 + 0x6C7D, KANJI_LEVEL4, // 汜 + 0x757F, KANJI_LEVEL4, // 畿 + 0x7948, KANJI_LEVEL4, // 祈 + 0x5B63, KANJI_LEVEL4, // å­£ + 0x7A00, KANJI_LEVEL4, // 繀 + 0x7D00, KANJI_LEVEL4, // 简 + 0x5FBD, KANJI_LEVEL4, // 埜 + 0x898F, KANJI_LEVEL4, // 芏 + 0x8A18, KANJI_LEVEL4, // 蚘 + 0x8CB4, KANJI_LEVEL4, // 貎 + 0x8D77, KANJI_LEVEL4, // èµ· + 0x8ECC, KANJI_LEVEL4, // 軌 + 0x8F1D, KANJI_LEVEL4, // 茝 + 0x98E2, KANJI_LEVEL4, // 飢 + 0x9A0E, KANJI_LEVEL4, // 階 + 0x9B3C, KANJI_LEVEL4, // 鬌 + 0x4E80, KANJI_LEVEL4, // 亀 + 0x507D, KANJI_LEVEL4, // 停 + 0x5100, KANJI_LEVEL4, // 儀 + 0x5993, KANJI_LEVEL4, // 劓 + 0x5B9C, KANJI_LEVEL4, // 宜 + 0x622F, KANJI_LEVEL4, // 戯 + 0x6280, KANJI_LEVEL4, // 技 + 0x64EC, KANJI_LEVEL4, // 擬 + 0x6B3A, KANJI_LEVEL4, // 欺 + 0x72A0, KANJI_LEVEL4, // 犠 + 0x7591, KANJI_LEVEL4, // 疑 + 0x7947, KANJI_LEVEL4, // 祇 + 0x7FA9, KANJI_LEVEL4, // 矩 + 0x87FB, KANJI_LEVEL4, // 蟻 + 0x8ABC, KANJI_LEVEL4, // 誌 + 0x8B70, KANJI_LEVEL4, // è­° + 0x63AC, KANJI_LEVEL4, // 掬 + 0x83CA, KANJI_LEVEL4, // 菊 + 0x97A0, KANJI_LEVEL4, // 鞠 + 0x5409, KANJI_LEVEL4, // 吉 + 0x5403, KANJI_LEVEL4, // 吃 + 0x55AB, KANJI_LEVEL4, // 喫 + 0x6854, KANJI_LEVEL4, // 桔 + 0x6A58, KANJI_LEVEL4, // 橘 + 0x8A70, KANJI_LEVEL4, // è©° + 0x7827, KANJI_LEVEL4, // ç § + 0x6775, KANJI_LEVEL4, // 杵 + 0x9ECD, KANJI_LEVEL4, // 黍 + 0x5374, KANJI_LEVEL4, // 华 + 0x5BA2, KANJI_LEVEL4, // 客 + 0x811A, KANJI_LEVEL4, // 脚 + 0x8650, KANJI_LEVEL4, // 虐 + 0x9006, KANJI_LEVEL4, // 逆 + 0x4E18, KANJI_LEVEL4, // 䞘 + 0x4E45, KANJI_LEVEL4, // 久 + 0x4EC7, KANJI_LEVEL4, // 仇 + 0x4F11, KANJI_LEVEL4, // 䌑 + 0x53CA, KANJI_LEVEL4, // 及 + 0x5438, KANJI_LEVEL4, // 吞 + 0x5BAE, KANJI_LEVEL4, // å®® + 0x5F13, KANJI_LEVEL4, // 匓 + 0x6025, KANJI_LEVEL4, // 急 + 0x6551, KANJI_LEVEL4, // 救 + 0x673D, KANJI_LEVEL4, // 朜 + 0x6C42, KANJI_LEVEL4, // 求 + 0x6C72, KANJI_LEVEL4, // æ±² + 0x6CE3, KANJI_LEVEL4, // æ³£ + 0x7078, KANJI_LEVEL4, // 灞 + 0x7403, KANJI_LEVEL4, // 球 + 0x7A76, KANJI_LEVEL4, // ç©¶ + 0x7AAE, KANJI_LEVEL4, // 窮 + 0x7B08, KANJI_LEVEL4, // 笈 + 0x7D1A, KANJI_LEVEL4, // 箚 + 0x7CFE, KANJI_LEVEL4, // 糟 + 0x7D66, KANJI_LEVEL4, // 絊 + 0x65E7, KANJI_LEVEL4, // 旧 + 0x725B, KANJI_LEVEL4, // 牛 + 0x53BB, KANJI_LEVEL4, // 去 + 0x5C45, KANJI_LEVEL4, // 居 + 0x5DE8, KANJI_LEVEL4, // å·š + 0x62D2, KANJI_LEVEL4, // 拒 + 0x62E0, KANJI_LEVEL4, // 拠 + 0x6319, KANJI_LEVEL4, // 挙 + 0x6E20, KANJI_LEVEL4, // æž  + 0x865A, KANJI_LEVEL4, // 虚 + 0x8A31, KANJI_LEVEL4, // èš± + 0x8DDD, KANJI_LEVEL4, // 距 + 0x92F8, KANJI_LEVEL4, // 鋾 + 0x6F01, KANJI_LEVEL4, // 持 + 0x79A6, KANJI_LEVEL4, // 犊 + 0x9B5A, KANJI_LEVEL4, // 魚 + 0x4EA8, KANJI_LEVEL4, // 亚 + 0x4EAB, KANJI_LEVEL4, // 享 + 0x4EAC, KANJI_LEVEL4, // 京 + 0x4F9B, KANJI_LEVEL4, // 䟛 + 0x4FA0, KANJI_LEVEL4, // 䟠 + 0x50D1, KANJI_LEVEL4, // 僑 + 0x5147, KANJI_LEVEL4, // 兇 + 0x7AF6, KANJI_LEVEL4, // ç«¶ + 0x5171, KANJI_LEVEL4, // 共 + 0x51F6, KANJI_LEVEL4, // 凶 + 0x5354, KANJI_LEVEL4, // 協 + 0x5321, KANJI_LEVEL4, // 匡 + 0x537F, KANJI_LEVEL4, // 卿 + 0x53EB, KANJI_LEVEL4, // 叫 + 0x55AC, KANJI_LEVEL4, // 喬 + 0x5883, KANJI_LEVEL4, // 境 + 0x5CE1, KANJI_LEVEL4, // 峡 + 0x5F37, KANJI_LEVEL4, // 匷 + 0x5F4A, KANJI_LEVEL4, // 圊 + 0x602F, KANJI_LEVEL4, // 怯 + 0x6050, KANJI_LEVEL4, // 恐 + 0x606D, KANJI_LEVEL4, // 恭 + 0x631F, KANJI_LEVEL4, // 挟 + 0x6559, KANJI_LEVEL4, // 教 + 0x6A4B, KANJI_LEVEL4, // 橋 + 0x6CC1, KANJI_LEVEL4, // 況 + 0x72C2, KANJI_LEVEL4, // 狂 + 0x72ED, KANJI_LEVEL4, // 狭 + 0x77EF, KANJI_LEVEL4, // 矯 + 0x80F8, KANJI_LEVEL4, // 胞 + 0x8105, KANJI_LEVEL4, // 脅 + 0x8208, KANJI_LEVEL4, // 興 + 0x854E, KANJI_LEVEL4, // 蕎 + 0x90F7, KANJI_LEVEL4, // 郷 + 0x93E1, KANJI_LEVEL4, // 鏡 + 0x97FF, KANJI_LEVEL4, // 響 + 0x9957, KANJI_LEVEL4, // 饗 + 0x9A5A, KANJI_LEVEL4, // 驚 + 0x4EF0, KANJI_LEVEL4, // ä»° + 0x51DD, KANJI_LEVEL4, // 凝 + 0x5C2D, KANJI_LEVEL4, // å°­ + 0x6681, KANJI_LEVEL4, // 暁 + 0x696D, KANJI_LEVEL4, // 業 + 0x5C40, KANJI_LEVEL4, // 局 + 0x66F2, KANJI_LEVEL4, // 曲 + 0x6975, KANJI_LEVEL4, // 極 + 0x7389, KANJI_LEVEL4, // 玉 + 0x6850, KANJI_LEVEL4, // 桐 + 0x7C81, KANJI_LEVEL4, // 粁 + 0x50C5, KANJI_LEVEL4, // 僅 + 0x52E4, KANJI_LEVEL4, // å‹€ + 0x5747, KANJI_LEVEL4, // 均 + 0x5DFE, KANJI_LEVEL4, // å·Ÿ + 0x9326, KANJI_LEVEL4, // 錩 + 0x65A4, KANJI_LEVEL4, // æ–€ + 0x6B23, KANJI_LEVEL4, // 欣 + 0x6B3D, KANJI_LEVEL4, // 欜 + 0x7434, KANJI_LEVEL4, // 琎 + 0x7981, KANJI_LEVEL4, // 犁 + 0x79BD, KANJI_LEVEL4, // 犜 + 0x7B4B, KANJI_LEVEL4, // 筋 + 0x7DCA, KANJI_LEVEL4, // 緊 + 0x82B9, KANJI_LEVEL4, // 芹 + 0x83CC, KANJI_LEVEL4, // 菌 + 0x887F, KANJI_LEVEL4, // è¡¿ + 0x895F, KANJI_LEVEL4, // 襟 + 0x8B39, KANJI_LEVEL4, // 謹 + 0x8FD1, KANJI_LEVEL4, // 近 + 0x91D1, KANJI_LEVEL4, // 金 + 0x541F, KANJI_LEVEL4, // 吟 + 0x9280, KANJI_LEVEL4, // 銀 + 0x4E5D, KANJI_LEVEL4, // 九 + 0x5036, KANJI_LEVEL4, // 倶 + 0x53E5, KANJI_LEVEL4, // 句 + 0x533A, KANJI_LEVEL4, // 区 + 0x72D7, KANJI_LEVEL4, // 狗 + 0x7396, KANJI_LEVEL4, // 玖 + 0x77E9, KANJI_LEVEL4, // 矩 + 0x82E6, KANJI_LEVEL4, // 苊 + 0x8EAF, KANJI_LEVEL4, // 躯 + 0x99C6, KANJI_LEVEL4, // 駆 + 0x99C8, KANJI_LEVEL4, // 駈 + 0x99D2, KANJI_LEVEL4, // 駒 + 0x5177, KANJI_LEVEL4, // 具 + 0x611A, KANJI_LEVEL4, // 愚 + 0x865E, KANJI_LEVEL4, // 虞 + 0x55B0, KANJI_LEVEL4, // 喰 + 0x7A7A, KANJI_LEVEL4, // 空 + 0x5076, KANJI_LEVEL4, // 偶 + 0x5BD3, KANJI_LEVEL4, // 寓 + 0x9047, KANJI_LEVEL4, // 遇 + 0x9685, KANJI_LEVEL4, // 隅 + 0x4E32, KANJI_LEVEL4, // äž² + 0x6ADB, KANJI_LEVEL4, // 櫛 + 0x91E7, KANJI_LEVEL4, // 釧 + 0x5C51, KANJI_LEVEL4, // 屑 + 0x5C48, KANJI_LEVEL4, // 屈 + 0x6398, KANJI_LEVEL4, // 掘 + 0x7A9F, KANJI_LEVEL4, // 窟 + 0x6C93, KANJI_LEVEL4, // 沓 + 0x9774, KANJI_LEVEL4, // 靎 + 0x8F61, KANJI_LEVEL4, // 蜡 + 0x7AAA, KANJI_LEVEL4, // 窪 + 0x718A, KANJI_LEVEL4, // 熊 + 0x9688, KANJI_LEVEL4, // 隈 + 0x7C82, KANJI_LEVEL4, // 粂 + 0x6817, KANJI_LEVEL4, // 栗 + 0x7E70, KANJI_LEVEL4, // ç¹° + 0x6851, KANJI_LEVEL4, // 桑 + 0x936C, KANJI_LEVEL4, // 鍬 + 0x52F2, KANJI_LEVEL4, // 勲 + 0x541B, KANJI_LEVEL4, // 君 + 0x85AB, KANJI_LEVEL4, // 薫 + 0x8A13, KANJI_LEVEL4, // èš“ + 0x7FA4, KANJI_LEVEL4, // 矀 + 0x8ECD, KANJI_LEVEL4, // 軍 + 0x90E1, KANJI_LEVEL4, // 郡 + 0x5366, KANJI_LEVEL4, // 半 + 0x8888, KANJI_LEVEL4, // 袈 + 0x7941, KANJI_LEVEL4, // 祁 + 0x4FC2, KANJI_LEVEL4, // 係 + 0x50BE, KANJI_LEVEL4, // 傟 + 0x5211, KANJI_LEVEL4, // 刑 + 0x5144, KANJI_LEVEL4, // 兄 + 0x5553, KANJI_LEVEL4, // 啓 + 0x572D, KANJI_LEVEL4, // 圭 + 0x73EA, KANJI_LEVEL4, // 珪 + 0x578B, KANJI_LEVEL4, // 型 + 0x5951, KANJI_LEVEL4, // 契 + 0x5F62, KANJI_LEVEL4, // 圢 + 0x5F84, KANJI_LEVEL4, // 埄 + 0x6075, KANJI_LEVEL4, // 恵 + 0x6176, KANJI_LEVEL4, // 慶 + 0x6167, KANJI_LEVEL4, // 慧 + 0x61A9, KANJI_LEVEL4, // 憩 + 0x63B2, KANJI_LEVEL4, // 掲 + 0x643A, KANJI_LEVEL4, // 携 + 0x656C, KANJI_LEVEL4, // 敬 + 0x666F, KANJI_LEVEL4, // 景 + 0x6842, KANJI_LEVEL4, // 桂 + 0x6E13, KANJI_LEVEL4, // æž“ + 0x7566, KANJI_LEVEL4, // 畩 + 0x7A3D, KANJI_LEVEL4, // çšœ + 0x7CFB, KANJI_LEVEL4, // ç³» + 0x7D4C, KANJI_LEVEL4, // 経 + 0x7D99, KANJI_LEVEL4, // 継 + 0x7E4B, KANJI_LEVEL4, // 繋 + 0x7F6B, KANJI_LEVEL4, // 眫 + 0x830E, KANJI_LEVEL4, // 茎 + 0x834A, KANJI_LEVEL4, // 荊 + 0x86CD, KANJI_LEVEL4, // 蛍 + 0x8A08, KANJI_LEVEL4, // 蚈 + 0x8A63, KANJI_LEVEL4, // è©£ + 0x8B66, KANJI_LEVEL4, // è­Š + 0x8EFD, KANJI_LEVEL4, // 軜 + 0x981A, KANJI_LEVEL4, // 頚 + 0x9D8F, KANJI_LEVEL4, // 鶏 + 0x82B8, KANJI_LEVEL4, // 芞 + 0x8FCE, KANJI_LEVEL4, // 迎 + 0x9BE8, KANJI_LEVEL4, // 鯚 + 0x5287, KANJI_LEVEL4, // 劇 + 0x621F, KANJI_LEVEL4, // 戟 + 0x6483, KANJI_LEVEL4, // 撃 + 0x6FC0, KANJI_LEVEL4, // 激 + 0x9699, KANJI_LEVEL4, // 隙 + 0x6841, KANJI_LEVEL4, // 桁 + 0x5091, KANJI_LEVEL4, // 傑 + 0x6B20, KANJI_LEVEL4, // 欠 + 0x6C7A, KANJI_LEVEL4, // 決 + 0x6F54, KANJI_LEVEL4, // 朔 + 0x7A74, KANJI_LEVEL4, // 穎 + 0x7D50, KANJI_LEVEL4, // 結 + 0x8840, KANJI_LEVEL4, // 血 + 0x8A23, KANJI_LEVEL4, // 蚣 + 0x6708, KANJI_LEVEL4, // 月 + 0x4EF6, KANJI_LEVEL4, // ä»¶ + 0x5039, KANJI_LEVEL4, // 倹 + 0x5026, KANJI_LEVEL4, // 倊 + 0x5065, KANJI_LEVEL4, // 健 + 0x517C, KANJI_LEVEL4, // å…Œ + 0x5238, KANJI_LEVEL4, // 刞 + 0x5263, KANJI_LEVEL4, // 剣 + 0x55A7, KANJI_LEVEL4, // 喧 + 0x570F, KANJI_LEVEL4, // 圏 + 0x5805, KANJI_LEVEL4, // 堅 + 0x5ACC, KANJI_LEVEL4, // 嫌 + 0x5EFA, KANJI_LEVEL4, // 建 + 0x61B2, KANJI_LEVEL4, // 憲 + 0x61F8, KANJI_LEVEL4, // 懞 + 0x62F3, KANJI_LEVEL4, // 拳 + 0x6372, KANJI_LEVEL4, // 捲 + 0x691C, KANJI_LEVEL4, // 怜 + 0x6A29, KANJI_LEVEL4, // æš© + 0x727D, KANJI_LEVEL4, // 牜 + 0x72AC, KANJI_LEVEL4, // 犬 + 0x732E, KANJI_LEVEL4, // 献 + 0x7814, KANJI_LEVEL4, // 研 + 0x786F, KANJI_LEVEL4, // 硯 + 0x7D79, KANJI_LEVEL4, // çµ¹ + 0x770C, KANJI_LEVEL4, // 県 + 0x80A9, KANJI_LEVEL4, // 肩 + 0x898B, KANJI_LEVEL4, // 芋 + 0x8B19, KANJI_LEVEL4, // 謙 + 0x8CE2, KANJI_LEVEL4, // è³¢ + 0x8ED2, KANJI_LEVEL4, // 軒 + 0x9063, KANJI_LEVEL4, // 遣 + 0x9375, KANJI_LEVEL4, // 鍵 + 0x967A, KANJI_LEVEL4, // 険 + 0x9855, KANJI_LEVEL4, // 顕 + 0x9A13, KANJI_LEVEL4, // 鹓 + 0x9E78, KANJI_LEVEL4, // 鹞 + 0x5143, KANJI_LEVEL4, // 元 + 0x539F, KANJI_LEVEL4, // 原 + 0x53B3, KANJI_LEVEL4, // 厳 + 0x5E7B, KANJI_LEVEL4, // å¹» + 0x5F26, KANJI_LEVEL4, // 匊 + 0x6E1B, KANJI_LEVEL4, // æž› + 0x6E90, KANJI_LEVEL4, // 源 + 0x7384, KANJI_LEVEL4, // 玄 + 0x73FE, KANJI_LEVEL4, // 珟 + 0x7D43, KANJI_LEVEL4, // 絃 + 0x8237, KANJI_LEVEL4, // 舷 + 0x8A00, KANJI_LEVEL4, // 蚀 + 0x8AFA, KANJI_LEVEL4, // 諺 + 0x9650, KANJI_LEVEL4, // 限 + 0x4E4E, KANJI_LEVEL4, // 乎 + 0x500B, KANJI_LEVEL4, // 個 + 0x53E4, KANJI_LEVEL4, // 叀 + 0x547C, KANJI_LEVEL4, // 呌 + 0x56FA, KANJI_LEVEL4, // 固 + 0x59D1, KANJI_LEVEL4, // 姑 + 0x5B64, KANJI_LEVEL4, // å­€ + 0x5DF1, KANJI_LEVEL4, // å·± + 0x5EAB, KANJI_LEVEL4, // 庫 + 0x5F27, KANJI_LEVEL4, // 匧 + 0x6238, KANJI_LEVEL4, // 戞 + 0x6545, KANJI_LEVEL4, // 故 + 0x67AF, KANJI_LEVEL4, // 枯 + 0x6E56, KANJI_LEVEL4, // 湖 + 0x72D0, KANJI_LEVEL4, // 狐 + 0x7CCA, KANJI_LEVEL4, // 糊 + 0x88B4, KANJI_LEVEL4, // 袎 + 0x80A1, KANJI_LEVEL4, // 股 + 0x80E1, KANJI_LEVEL4, // 胡 + 0x83F0, KANJI_LEVEL4, // 菰 + 0x864E, KANJI_LEVEL4, // 虎 + 0x8A87, KANJI_LEVEL4, // 誇 + 0x8DE8, KANJI_LEVEL4, // è·š + 0x9237, KANJI_LEVEL4, // 鈷 + 0x96C7, KANJI_LEVEL4, // 雇 + 0x9867, KANJI_LEVEL4, // é¡§ + 0x9F13, KANJI_LEVEL4, // 錓 + 0x4E94, KANJI_LEVEL4, // 五 + 0x4E92, KANJI_LEVEL4, // 互 + 0x4F0D, KANJI_LEVEL4, // 䌍 + 0x5348, KANJI_LEVEL4, // 午 + 0x5449, KANJI_LEVEL4, // 呉 + 0x543E, KANJI_LEVEL4, // 吟 + 0x5A2F, KANJI_LEVEL4, // 嚯 + 0x5F8C, KANJI_LEVEL4, // 埌 + 0x5FA1, KANJI_LEVEL4, // 埡 + 0x609F, KANJI_LEVEL4, // 悟 + 0x68A7, KANJI_LEVEL4, // 梧 + 0x6A8E, KANJI_LEVEL4, // 檎 + 0x745A, KANJI_LEVEL4, // 瑚 + 0x7881, KANJI_LEVEL4, // 碁 + 0x8A9E, KANJI_LEVEL4, // 語 + 0x8AA4, KANJI_LEVEL4, // 誀 + 0x8B77, KANJI_LEVEL4, // è­· + 0x9190, KANJI_LEVEL4, // 醐 + 0x4E5E, KANJI_LEVEL4, // 乞 + 0x9BC9, KANJI_LEVEL4, // 鯉 + 0x4EA4, KANJI_LEVEL4, // 亀 + 0x4F7C, KANJI_LEVEL4, // 䜌 + 0x4FAF, KANJI_LEVEL4, // 䟯 + 0x5019, KANJI_LEVEL4, // 候 + 0x5016, KANJI_LEVEL4, // 倖 + 0x5149, KANJI_LEVEL4, // 光 + 0x516C, KANJI_LEVEL4, // 公 + 0x529F, KANJI_LEVEL4, // 功 + 0x52B9, KANJI_LEVEL4, // 効 + 0x52FE, KANJI_LEVEL4, // 募 + 0x539A, KANJI_LEVEL4, // 厚 + 0x53E3, KANJI_LEVEL4, // 口 + 0x5411, KANJI_LEVEL4, // 向 + 0x540E, KANJI_LEVEL4, // 后 + 0x5589, KANJI_LEVEL4, // 喉 + 0x5751, KANJI_LEVEL4, // 坑 + 0x57A2, KANJI_LEVEL4, // 垢 + 0x597D, KANJI_LEVEL4, // 奜 + 0x5B54, KANJI_LEVEL4, // 孔 + 0x5B5D, KANJI_LEVEL4, // 孝 + 0x5B8F, KANJI_LEVEL4, // 宏 + 0x5DE5, KANJI_LEVEL4, // å·¥ + 0x5DE7, KANJI_LEVEL4, // å·§ + 0x5DF7, KANJI_LEVEL4, // å·· + 0x5E78, KANJI_LEVEL4, // 幞 + 0x5E83, KANJI_LEVEL4, // 広 + 0x5E9A, KANJI_LEVEL4, // 庚 + 0x5EB7, KANJI_LEVEL4, // 康 + 0x5F18, KANJI_LEVEL4, // 匘 + 0x6052, KANJI_LEVEL4, // 恒 + 0x614C, KANJI_LEVEL4, // 慌 + 0x6297, KANJI_LEVEL4, // 抗 + 0x62D8, KANJI_LEVEL4, // 拘 + 0x63A7, KANJI_LEVEL4, // 控 + 0x653B, KANJI_LEVEL4, // 攻 + 0x6602, KANJI_LEVEL4, // 昂 + 0x6643, KANJI_LEVEL4, // 晃 + 0x66F4, KANJI_LEVEL4, // 曎 + 0x676D, KANJI_LEVEL4, // 杭 + 0x6821, KANJI_LEVEL4, // æ ¡ + 0x6897, KANJI_LEVEL4, // 梗 + 0x69CB, KANJI_LEVEL4, // 構 + 0x6C5F, KANJI_LEVEL4, // 江 + 0x6D2A, KANJI_LEVEL4, // 措 + 0x6D69, KANJI_LEVEL4, // 浩 + 0x6E2F, KANJI_LEVEL4, // 枯 + 0x6E9D, KANJI_LEVEL4, // 溝 + 0x7532, KANJI_LEVEL4, // 甲 + 0x7687, KANJI_LEVEL4, // 皇 + 0x786C, KANJI_LEVEL4, // 硬 + 0x7A3F, KANJI_LEVEL4, // çš¿ + 0x7CE0, KANJI_LEVEL4, // ç³  + 0x7D05, KANJI_LEVEL4, // 箅 + 0x7D18, KANJI_LEVEL4, // 玘 + 0x7D5E, KANJI_LEVEL4, // 絞 + 0x7DB1, KANJI_LEVEL4, // ç¶± + 0x8015, KANJI_LEVEL4, // 耕 + 0x8003, KANJI_LEVEL4, // 考 + 0x80AF, KANJI_LEVEL4, // 肯 + 0x80B1, KANJI_LEVEL4, // 肱 + 0x8154, KANJI_LEVEL4, // 腔 + 0x818F, KANJI_LEVEL4, // 膏 + 0x822A, KANJI_LEVEL4, // 航 + 0x8352, KANJI_LEVEL4, // 荒 + 0x884C, KANJI_LEVEL4, // 行 + 0x8861, KANJI_LEVEL4, // è¡¡ + 0x8B1B, KANJI_LEVEL4, // 講 + 0x8CA2, KANJI_LEVEL4, // è²¢ + 0x8CFC, KANJI_LEVEL4, // 賌 + 0x90CA, KANJI_LEVEL4, // 郊 + 0x9175, KANJI_LEVEL4, // 酵 + 0x9271, KANJI_LEVEL4, // 鉱 + 0x783F, KANJI_LEVEL4, // ç ¿ + 0x92FC, KANJI_LEVEL4, // 鋌 + 0x95A4, KANJI_LEVEL4, // é–€ + 0x964D, KANJI_LEVEL4, // 降 + 0x9805, KANJI_LEVEL4, // 項 + 0x9999, KANJI_LEVEL4, // 驙 + 0x9AD8, KANJI_LEVEL4, // 高 + 0x9D3B, KANJI_LEVEL4, // 鎻 + 0x525B, KANJI_LEVEL4, // 剛 + 0x52AB, KANJI_LEVEL4, // 劫 + 0x53F7, KANJI_LEVEL4, // 号 + 0x5408, KANJI_LEVEL4, // 合 + 0x58D5, KANJI_LEVEL4, // 壕 + 0x62F7, KANJI_LEVEL4, // 拷 + 0x6FE0, KANJI_LEVEL4, // æ¿  + 0x8C6A, KANJI_LEVEL4, // 豪 + 0x8F5F, KANJI_LEVEL4, // 蜟 + 0x9EB9, KANJI_LEVEL4, // 麹 + 0x514B, KANJI_LEVEL4, // 克 + 0x523B, KANJI_LEVEL4, // 刻 + 0x544A, KANJI_LEVEL4, // 告 + 0x56FD, KANJI_LEVEL4, // 囜 + 0x7A40, KANJI_LEVEL4, // 穀 + 0x9177, KANJI_LEVEL4, // 酷 + 0x9D60, KANJI_LEVEL4, // éµ  + 0x9ED2, KANJI_LEVEL4, // 黒 + 0x7344, KANJI_LEVEL4, // 獄 + 0x6F09, KANJI_LEVEL4, // 按 + 0x8170, KANJI_LEVEL4, // 腰 + 0x7511, KANJI_LEVEL4, // 甑 + 0x5FFD, KANJI_LEVEL4, // 応 + 0x60DA, KANJI_LEVEL4, // 惚 + 0x9AA8, KANJI_LEVEL4, // 骚 + 0x72DB, KANJI_LEVEL4, // 狛 + 0x8FBC, KANJI_LEVEL4, // 蟌 + 0x6B64, KANJI_LEVEL4, // æ­€ + 0x9803, KANJI_LEVEL4, // 頃 + 0x4ECA, KANJI_LEVEL4, // 今 + 0x56F0, KANJI_LEVEL4, // 困 + 0x5764, KANJI_LEVEL4, // 址 + 0x58BE, KANJI_LEVEL4, // 墟 + 0x5A5A, KANJI_LEVEL4, // 婚 + 0x6068, KANJI_LEVEL4, // 恚 + 0x61C7, KANJI_LEVEL4, // 懇 + 0x660F, KANJI_LEVEL4, // 昏 + 0x6606, KANJI_LEVEL4, // 昆 + 0x6839, KANJI_LEVEL4, // æ ¹ + 0x68B1, KANJI_LEVEL4, // 梱 + 0x6DF7, KANJI_LEVEL4, // æ·· + 0x75D5, KANJI_LEVEL4, // 痕 + 0x7D3A, KANJI_LEVEL4, // 玺 + 0x826E, KANJI_LEVEL4, // 艮 + 0x9B42, KANJI_LEVEL4, // 魂 + 0x4E9B, KANJI_LEVEL4, // 些 + 0x4F50, KANJI_LEVEL4, // 䜐 + 0x53C9, KANJI_LEVEL4, // 叉 + 0x5506, KANJI_LEVEL4, // 唆 + 0x5D6F, KANJI_LEVEL4, // 嵯 + 0x5DE6, KANJI_LEVEL4, // å·Š + 0x5DEE, KANJI_LEVEL4, // å·® + 0x67FB, KANJI_LEVEL4, // 査 + 0x6C99, KANJI_LEVEL4, // 沙 + 0x7473, KANJI_LEVEL4, // 瑳 + 0x7802, KANJI_LEVEL4, // 砂 + 0x8A50, KANJI_LEVEL4, // 詐 + 0x9396, KANJI_LEVEL4, // 鎖 + 0x88DF, KANJI_LEVEL4, // 裟 + 0x5750, KANJI_LEVEL4, // 坐 + 0x5EA7, KANJI_LEVEL4, // 座 + 0x632B, KANJI_LEVEL4, // 挫 + 0x50B5, KANJI_LEVEL4, // 債 + 0x50AC, KANJI_LEVEL4, // 催 + 0x518D, KANJI_LEVEL4, // 再 + 0x6700, KANJI_LEVEL4, // 最 + 0x54C9, KANJI_LEVEL4, // 哉 + 0x585E, KANJI_LEVEL4, // 塞 + 0x59BB, KANJI_LEVEL4, // 劻 + 0x5BB0, KANJI_LEVEL4, // å®° + 0x5F69, KANJI_LEVEL4, // 圩 + 0x624D, KANJI_LEVEL4, // 才 + 0x63A1, KANJI_LEVEL4, // 採 + 0x683D, KANJI_LEVEL4, // æ œ + 0x6B73, KANJI_LEVEL4, // æ­³ + 0x6E08, KANJI_LEVEL4, // 枈 + 0x707D, KANJI_LEVEL4, // 灜 + 0x91C7, KANJI_LEVEL4, // 采 + 0x7280, KANJI_LEVEL4, // 犀 + 0x7815, KANJI_LEVEL4, // 砕 + 0x7826, KANJI_LEVEL4, // ç Š + 0x796D, KANJI_LEVEL4, // 祭 + 0x658E, KANJI_LEVEL4, // 斎 + 0x7D30, KANJI_LEVEL4, // 现 + 0x83DC, KANJI_LEVEL4, // 菜 + 0x88C1, KANJI_LEVEL4, // 裁 + 0x8F09, KANJI_LEVEL4, // 茉 + 0x969B, KANJI_LEVEL4, // 際 + 0x5264, KANJI_LEVEL4, // 剀 + 0x5728, KANJI_LEVEL4, // 圚 + 0x6750, KANJI_LEVEL4, // 材 + 0x7F6A, KANJI_LEVEL4, // 眪 + 0x8CA1, KANJI_LEVEL4, // 財 + 0x51B4, KANJI_LEVEL4, // 冎 + 0x5742, KANJI_LEVEL4, // 坂 + 0x962A, KANJI_LEVEL4, // 阪 + 0x583A, KANJI_LEVEL4, // å º + 0x698A, KANJI_LEVEL4, // 把 + 0x80B4, KANJI_LEVEL4, // 肎 + 0x54B2, KANJI_LEVEL4, // 咲 + 0x5D0E, KANJI_LEVEL4, // 厎 + 0x57FC, KANJI_LEVEL4, // 埌 + 0x7895, KANJI_LEVEL4, // 碕 + 0x9DFA, KANJI_LEVEL4, // é·º + 0x4F5C, KANJI_LEVEL4, // 䜜 + 0x524A, KANJI_LEVEL4, // 削 + 0x548B, KANJI_LEVEL4, // 咋 + 0x643E, KANJI_LEVEL4, // 搟 + 0x6628, KANJI_LEVEL4, // 昚 + 0x6714, KANJI_LEVEL4, // 朔 + 0x67F5, KANJI_LEVEL4, // 柵 + 0x7A84, KANJI_LEVEL4, // 窄 + 0x7B56, KANJI_LEVEL4, // 策 + 0x7D22, KANJI_LEVEL4, // 玢 + 0x932F, KANJI_LEVEL4, // 錯 + 0x685C, KANJI_LEVEL4, // 桜 + 0x9BAD, KANJI_LEVEL4, // é®­ + 0x7B39, KANJI_LEVEL4, // 笹 + 0x5319, KANJI_LEVEL4, // 匙 + 0x518A, KANJI_LEVEL4, // 冊 + 0x5237, KANJI_LEVEL4, // 刷 + 0x5BDF, KANJI_LEVEL4, // 察 + 0x62F6, KANJI_LEVEL4, // 拶 + 0x64AE, KANJI_LEVEL4, // 撮 + 0x64E6, KANJI_LEVEL4, // 擊 + 0x672D, KANJI_LEVEL4, // 札 + 0x6BBA, KANJI_LEVEL4, // 殺 + 0x85A9, KANJI_LEVEL4, // 薩 + 0x96D1, KANJI_LEVEL4, // 雑 + 0x7690, KANJI_LEVEL4, // 皐 + 0x9BD6, KANJI_LEVEL4, // 鯖 + 0x634C, KANJI_LEVEL4, // 捌 + 0x9306, KANJI_LEVEL4, // 錆 + 0x9BAB, KANJI_LEVEL4, // 鮫 + 0x76BF, KANJI_LEVEL4, // 皿 + 0x6652, KANJI_LEVEL4, // 晒 + 0x4E09, KANJI_LEVEL4, // 侉 + 0x5098, KANJI_LEVEL4, // 傘 + 0x53C2, KANJI_LEVEL4, // 参 + 0x5C71, KANJI_LEVEL4, // å±± + 0x60E8, KANJI_LEVEL4, // 惚 + 0x6492, KANJI_LEVEL4, // 撒 + 0x6563, KANJI_LEVEL4, // 散 + 0x685F, KANJI_LEVEL4, // 桟 + 0x71E6, KANJI_LEVEL4, // 燩 + 0x73CA, KANJI_LEVEL4, // 珊 + 0x7523, KANJI_LEVEL4, // 産 + 0x7B97, KANJI_LEVEL4, // 算 + 0x7E82, KANJI_LEVEL4, // 纂 + 0x8695, KANJI_LEVEL4, // 蚕 + 0x8B83, KANJI_LEVEL4, // 讃 + 0x8CDB, KANJI_LEVEL4, // 賛 + 0x9178, KANJI_LEVEL4, // 酾 + 0x9910, KANJI_LEVEL4, // 逐 + 0x65AC, KANJI_LEVEL4, // 斬 + 0x66AB, KANJI_LEVEL4, // 暫 + 0x6B8B, KANJI_LEVEL4, // 残 + 0x4ED5, KANJI_LEVEL4, // 仕 + 0x4ED4, KANJI_LEVEL4, // 仔 + 0x4F3A, KANJI_LEVEL4, // 䌺 + 0x4F7F, KANJI_LEVEL4, // 䜿 + 0x523A, KANJI_LEVEL4, // 刺 + 0x53F8, KANJI_LEVEL4, // 叞 + 0x53F2, KANJI_LEVEL4, // 史 + 0x55E3, KANJI_LEVEL4, // 嗣 + 0x56DB, KANJI_LEVEL4, // 四 + 0x58EB, KANJI_LEVEL4, // 士 + 0x59CB, KANJI_LEVEL4, // 始 + 0x59C9, KANJI_LEVEL4, // 姉 + 0x59FF, KANJI_LEVEL4, // å§¿ + 0x5B50, KANJI_LEVEL4, // 子 + 0x5C4D, KANJI_LEVEL4, // 屍 + 0x5E02, KANJI_LEVEL4, // åž‚ + 0x5E2B, KANJI_LEVEL4, // åž« + 0x5FD7, KANJI_LEVEL4, // 志 + 0x601D, KANJI_LEVEL4, // 思 + 0x6307, KANJI_LEVEL4, // 指 + 0x652F, KANJI_LEVEL4, // 支 + 0x5B5C, KANJI_LEVEL4, // 孜 + 0x65AF, KANJI_LEVEL4, // 斯 + 0x65BD, KANJI_LEVEL4, // æ–œ + 0x65E8, KANJI_LEVEL4, // æ—š + 0x679D, KANJI_LEVEL4, // 枝 + 0x6B62, KANJI_LEVEL4, // æ­¢ + 0x6B7B, KANJI_LEVEL4, // æ­» + 0x6C0F, KANJI_LEVEL4, // 氏 + 0x7345, KANJI_LEVEL4, // 獅 + 0x7949, KANJI_LEVEL4, // 祉 + 0x79C1, KANJI_LEVEL4, // 私 + 0x7CF8, KANJI_LEVEL4, // 糞 + 0x7D19, KANJI_LEVEL4, // 箙 + 0x7D2B, KANJI_LEVEL4, // 玫 + 0x80A2, KANJI_LEVEL4, // 肢 + 0x8102, KANJI_LEVEL4, // 脂 + 0x81F3, KANJI_LEVEL4, // 至 + 0x8996, KANJI_LEVEL4, // 芖 + 0x8A5E, KANJI_LEVEL4, // 詞 + 0x8A69, KANJI_LEVEL4, // è©© + 0x8A66, KANJI_LEVEL4, // 詊 + 0x8A8C, KANJI_LEVEL4, // 誌 + 0x8AEE, KANJI_LEVEL4, // è«® + 0x8CC7, KANJI_LEVEL4, // 資 + 0x8CDC, KANJI_LEVEL4, // 賜 + 0x96CC, KANJI_LEVEL4, // 雌 + 0x98FC, KANJI_LEVEL4, // 飌 + 0x6B6F, KANJI_LEVEL4, // æ­¯ + 0x4E8B, KANJI_LEVEL4, // 事 + 0x4F3C, KANJI_LEVEL4, // 䌌 + 0x4F8D, KANJI_LEVEL4, // 䟍 + 0x5150, KANJI_LEVEL4, // 児 + 0x5B57, KANJI_LEVEL4, // 字 + 0x5BFA, KANJI_LEVEL4, // 寺 + 0x6148, KANJI_LEVEL4, // 慈 + 0x6301, KANJI_LEVEL4, // 持 + 0x6642, KANJI_LEVEL4, // 時 + 0x6B21, KANJI_LEVEL4, // 次 + 0x6ECB, KANJI_LEVEL4, // 滋 + 0x6CBB, KANJI_LEVEL4, // æ²» + 0x723E, KANJI_LEVEL4, // 爟 + 0x74BD, KANJI_LEVEL4, // ç’œ + 0x75D4, KANJI_LEVEL4, // 痔 + 0x78C1, KANJI_LEVEL4, // 磁 + 0x793A, KANJI_LEVEL4, // 瀺 + 0x800C, KANJI_LEVEL4, // 而 + 0x8033, KANJI_LEVEL4, // 耳 + 0x81EA, KANJI_LEVEL4, // 自 + 0x8494, KANJI_LEVEL4, // 蒔 + 0x8F9E, KANJI_LEVEL4, // 蟞 + 0x6C50, KANJI_LEVEL4, // 汐 + 0x9E7F, KANJI_LEVEL4, // 鹿 + 0x5F0F, KANJI_LEVEL4, // 匏 + 0x8B58, KANJI_LEVEL4, // 識 + 0x9D2B, KANJI_LEVEL4, // 鎫 + 0x7AFA, KANJI_LEVEL4, // 竺 + 0x8EF8, KANJI_LEVEL4, // 軞 + 0x5B8D, KANJI_LEVEL4, // 宍 + 0x96EB, KANJI_LEVEL4, // 雫 + 0x4E03, KANJI_LEVEL4, // 䞃 + 0x53F1, KANJI_LEVEL4, // 叱 + 0x57F7, KANJI_LEVEL4, // 執 + 0x5931, KANJI_LEVEL4, // 倱 + 0x5AC9, KANJI_LEVEL4, // 嫉 + 0x5BA4, KANJI_LEVEL4, // 宀 + 0x6089, KANJI_LEVEL4, // 悉 + 0x6E7F, KANJI_LEVEL4, // 湿 + 0x6F06, KANJI_LEVEL4, // 挆 + 0x75BE, KANJI_LEVEL4, // ç–Ÿ + 0x8CEA, KANJI_LEVEL4, // 質 + 0x5B9F, KANJI_LEVEL4, // 実 + 0x8500, KANJI_LEVEL4, // 蔀 + 0x7BE0, KANJI_LEVEL4, // 篠 + 0x5072, KANJI_LEVEL4, // 偲 + 0x67F4, KANJI_LEVEL4, // 柎 + 0x829D, KANJI_LEVEL4, // 芝 + 0x5C61, KANJI_LEVEL4, // 屡 + 0x854A, KANJI_LEVEL4, // 蕊 + 0x7E1E, KANJI_LEVEL4, // 羞 + 0x820E, KANJI_LEVEL4, // 舎 + 0x5199, KANJI_LEVEL4, // 写 + 0x5C04, KANJI_LEVEL4, // 射 + 0x6368, KANJI_LEVEL4, // 捚 + 0x8D66, KANJI_LEVEL4, // 赊 + 0x659C, KANJI_LEVEL4, // 斜 + 0x716E, KANJI_LEVEL4, // 煮 + 0x793E, KANJI_LEVEL4, // 瀟 + 0x7D17, KANJI_LEVEL4, // 算 + 0x8005, KANJI_LEVEL4, // 者 + 0x8B1D, KANJI_LEVEL4, // 謝 + 0x8ECA, KANJI_LEVEL4, // 車 + 0x906E, KANJI_LEVEL4, // 遮 + 0x86C7, KANJI_LEVEL4, // 蛇 + 0x90AA, KANJI_LEVEL4, // 邪 + 0x501F, KANJI_LEVEL4, // 借 + 0x52FA, KANJI_LEVEL4, // 勺 + 0x5C3A, KANJI_LEVEL4, // å°º + 0x6753, KANJI_LEVEL4, // 杓 + 0x707C, KANJI_LEVEL4, // 灌 + 0x7235, KANJI_LEVEL4, // 爵 + 0x914C, KANJI_LEVEL4, // 酌 + 0x91C8, KANJI_LEVEL4, // 釈 + 0x932B, KANJI_LEVEL4, // 錫 + 0x82E5, KANJI_LEVEL4, // 若 + 0x5BC2, KANJI_LEVEL4, // 寂 + 0x5F31, KANJI_LEVEL4, // 匱 + 0x60F9, KANJI_LEVEL4, // 惹 + 0x4E3B, KANJI_LEVEL4, // äž» + 0x53D6, KANJI_LEVEL4, // 取 + 0x5B88, KANJI_LEVEL4, // 守 + 0x624B, KANJI_LEVEL4, // 手 + 0x6731, KANJI_LEVEL4, // 朱 + 0x6B8A, KANJI_LEVEL4, // 殊 + 0x72E9, KANJI_LEVEL4, // 狩 + 0x73E0, KANJI_LEVEL4, // 珠 + 0x7A2E, KANJI_LEVEL4, // çš® + 0x816B, KANJI_LEVEL4, // 腫 + 0x8DA3, KANJI_LEVEL4, // è¶£ + 0x9152, KANJI_LEVEL4, // 酒 + 0x9996, KANJI_LEVEL4, // 驖 + 0x5112, KANJI_LEVEL4, // 儒 + 0x53D7, KANJI_LEVEL4, // 受 + 0x546A, KANJI_LEVEL4, // 呪 + 0x5BFF, KANJI_LEVEL4, // 寿 + 0x6388, KANJI_LEVEL4, // 授 + 0x6A39, KANJI_LEVEL4, // æš¹ + 0x7DAC, KANJI_LEVEL4, // 綬 + 0x9700, KANJI_LEVEL4, // 需 + 0x56DA, KANJI_LEVEL4, // 囚 + 0x53CE, KANJI_LEVEL4, // 収 + 0x5468, KANJI_LEVEL4, // 呚 + 0x5B97, KANJI_LEVEL4, // 宗 + 0x5C31, KANJI_LEVEL4, // å°± + 0x5DDE, KANJI_LEVEL4, // 州 + 0x4FEE, KANJI_LEVEL4, // ä¿® + 0x6101, KANJI_LEVEL4, // 愁 + 0x62FE, KANJI_LEVEL4, // 拟 + 0x6D32, KANJI_LEVEL4, // 掲 + 0x79C0, KANJI_LEVEL4, // 秀 + 0x79CB, KANJI_LEVEL4, // 秋 + 0x7D42, KANJI_LEVEL4, // 終 + 0x7E4D, KANJI_LEVEL4, // 繍 + 0x7FD2, KANJI_LEVEL4, // 習 + 0x81ED, KANJI_LEVEL4, // 臭 + 0x821F, KANJI_LEVEL4, // 舟 + 0x8490, KANJI_LEVEL4, // 蒐 + 0x8846, KANJI_LEVEL4, // 衆 + 0x8972, KANJI_LEVEL4, // 襲 + 0x8B90, KANJI_LEVEL4, // 讐 + 0x8E74, KANJI_LEVEL4, // 蹎 + 0x8F2F, KANJI_LEVEL4, // 茯 + 0x9031, KANJI_LEVEL4, // 週 + 0x914B, KANJI_LEVEL4, // 酋 + 0x916C, KANJI_LEVEL4, // 酬 + 0x96C6, KANJI_LEVEL4, // 集 + 0x919C, KANJI_LEVEL4, // 醜 + 0x4EC0, KANJI_LEVEL4, // 什 + 0x4F4F, KANJI_LEVEL4, // 䜏 + 0x5145, KANJI_LEVEL4, // 充 + 0x5341, KANJI_LEVEL4, // 十 + 0x5F93, KANJI_LEVEL4, // 埓 + 0x620E, KANJI_LEVEL4, // 戎 + 0x67D4, KANJI_LEVEL4, // 柔 + 0x6C41, KANJI_LEVEL4, // 汁 + 0x6E0B, KANJI_LEVEL4, // æž‹ + 0x7363, KANJI_LEVEL4, // 獣 + 0x7E26, KANJI_LEVEL4, // 瞊 + 0x91CD, KANJI_LEVEL4, // 重 + 0x9283, KANJI_LEVEL4, // 銃 + 0x53D4, KANJI_LEVEL4, // 叔 + 0x5919, KANJI_LEVEL4, // 候 + 0x5BBF, KANJI_LEVEL4, // 宿 + 0x6DD1, KANJI_LEVEL4, // 淑 + 0x795D, KANJI_LEVEL4, // 祝 + 0x7E2E, KANJI_LEVEL4, // çž® + 0x7C9B, KANJI_LEVEL4, // 粛 + 0x587E, KANJI_LEVEL4, // 塟 + 0x719F, KANJI_LEVEL4, // 熟 + 0x51FA, KANJI_LEVEL4, // 出 + 0x8853, KANJI_LEVEL4, // 術 + 0x8FF0, KANJI_LEVEL4, // è¿° + 0x4FCA, KANJI_LEVEL4, // 俊 + 0x5CFB, KANJI_LEVEL4, // å³» + 0x6625, KANJI_LEVEL4, // 春 + 0x77AC, KANJI_LEVEL4, // 瞬 + 0x7AE3, KANJI_LEVEL4, // ç«£ + 0x821C, KANJI_LEVEL4, // 舜 + 0x99FF, KANJI_LEVEL4, // é§¿ + 0x51C6, KANJI_LEVEL4, // 准 + 0x5FAA, KANJI_LEVEL4, // 埪 + 0x65EC, KANJI_LEVEL4, // 旬 + 0x696F, KANJI_LEVEL4, // 楯 + 0x6B89, KANJI_LEVEL4, // 殉 + 0x6DF3, KANJI_LEVEL4, // æ·³ + 0x6E96, KANJI_LEVEL4, // 準 + 0x6F64, KANJI_LEVEL4, // 最 + 0x76FE, KANJI_LEVEL4, // 盟 + 0x7D14, KANJI_LEVEL4, // 箔 + 0x5DE1, KANJI_LEVEL4, // å·¡ + 0x9075, KANJI_LEVEL4, // 遵 + 0x9187, KANJI_LEVEL4, // 醇 + 0x9806, KANJI_LEVEL4, // 順 + 0x51E6, KANJI_LEVEL4, // 凊 + 0x521D, KANJI_LEVEL4, // 初 + 0x6240, KANJI_LEVEL4, // 所 + 0x6691, KANJI_LEVEL4, // 暑 + 0x66D9, KANJI_LEVEL4, // 曙 + 0x6E1A, KANJI_LEVEL4, // æžš + 0x5EB6, KANJI_LEVEL4, // 庶 + 0x7DD2, KANJI_LEVEL4, // 緒 + 0x7F72, KANJI_LEVEL4, // 眲 + 0x66F8, KANJI_LEVEL4, // 曞 + 0x85AF, KANJI_LEVEL4, // 薯 + 0x85F7, KANJI_LEVEL4, // 藷 + 0x8AF8, KANJI_LEVEL4, // 諞 + 0x52A9, KANJI_LEVEL4, // 助 + 0x53D9, KANJI_LEVEL4, // 叙 + 0x5973, KANJI_LEVEL4, // 女 + 0x5E8F, KANJI_LEVEL4, // 序 + 0x5F90, KANJI_LEVEL4, // 埐 + 0x6055, KANJI_LEVEL4, // 恕 + 0x92E4, KANJI_LEVEL4, // é‹€ + 0x9664, KANJI_LEVEL4, // 陀 + 0x50B7, KANJI_LEVEL4, // 傷 + 0x511F, KANJI_LEVEL4, // 償 + 0x52DD, KANJI_LEVEL4, // 勝 + 0x5320, KANJI_LEVEL4, // 匠 + 0x5347, KANJI_LEVEL4, // 升 + 0x53EC, KANJI_LEVEL4, // 召 + 0x54E8, KANJI_LEVEL4, // 哚 + 0x5546, KANJI_LEVEL4, // 商 + 0x5531, KANJI_LEVEL4, // 唱 + 0x5617, KANJI_LEVEL4, // 嘗 + 0x5968, KANJI_LEVEL4, // 奚 + 0x59BE, KANJI_LEVEL4, // 功 + 0x5A3C, KANJI_LEVEL4, // 嚌 + 0x5BB5, KANJI_LEVEL4, // 宵 + 0x5C06, KANJI_LEVEL4, // 将 + 0x5C0F, KANJI_LEVEL4, // 小 + 0x5C11, KANJI_LEVEL4, // 少 + 0x5C1A, KANJI_LEVEL4, // 尚 + 0x5E84, KANJI_LEVEL4, // 庄 + 0x5E8A, KANJI_LEVEL4, // 床 + 0x5EE0, KANJI_LEVEL4, // å»  + 0x5F70, KANJI_LEVEL4, // 地 + 0x627F, KANJI_LEVEL4, // 承 + 0x6284, KANJI_LEVEL4, // 抄 + 0x62DB, KANJI_LEVEL4, // 招 + 0x638C, KANJI_LEVEL4, // 掌 + 0x6377, KANJI_LEVEL4, // 捷 + 0x6607, KANJI_LEVEL4, // 昇 + 0x660C, KANJI_LEVEL4, // 昌 + 0x662D, KANJI_LEVEL4, // 昭 + 0x6676, KANJI_LEVEL4, // 晶 + 0x677E, KANJI_LEVEL4, // 束 + 0x68A2, KANJI_LEVEL4, // 梢 + 0x6A1F, KANJI_LEVEL4, // 暟 + 0x6A35, KANJI_LEVEL4, // æšµ + 0x6CBC, KANJI_LEVEL4, // 沌 + 0x6D88, KANJI_LEVEL4, // 消 + 0x6E09, KANJI_LEVEL4, // 枉 + 0x6E58, KANJI_LEVEL4, // 湘 + 0x713C, KANJI_LEVEL4, // 焌 + 0x7126, KANJI_LEVEL4, // 焩 + 0x7167, KANJI_LEVEL4, // 照 + 0x75C7, KANJI_LEVEL4, // 症 + 0x7701, KANJI_LEVEL4, // 省 + 0x785D, KANJI_LEVEL4, // 硝 + 0x7901, KANJI_LEVEL4, // 瀁 + 0x7965, KANJI_LEVEL4, // 祥 + 0x79F0, KANJI_LEVEL4, // ç§° + 0x7AE0, KANJI_LEVEL4, // ç«  + 0x7B11, KANJI_LEVEL4, // 笑 + 0x7CA7, KANJI_LEVEL4, // ç²§ + 0x7D39, KANJI_LEVEL4, // 玹 + 0x8096, KANJI_LEVEL4, // 肖 + 0x83D6, KANJI_LEVEL4, // 菖 + 0x848B, KANJI_LEVEL4, // 蒋 + 0x8549, KANJI_LEVEL4, // 蕉 + 0x885D, KANJI_LEVEL4, // 衝 + 0x88F3, KANJI_LEVEL4, // 裳 + 0x8A1F, KANJI_LEVEL4, // 蚟 + 0x8A3C, KANJI_LEVEL4, // 蚌 + 0x8A54, KANJI_LEVEL4, // 詔 + 0x8A73, KANJI_LEVEL4, // 詳 + 0x8C61, KANJI_LEVEL4, // 象 + 0x8CDE, KANJI_LEVEL4, // 賞 + 0x91A4, KANJI_LEVEL4, // 醀 + 0x9266, KANJI_LEVEL4, // 鉩 + 0x937E, KANJI_LEVEL4, // 鍟 + 0x9418, KANJI_LEVEL4, // 鐘 + 0x969C, KANJI_LEVEL4, // 障 + 0x9798, KANJI_LEVEL4, // 鞘 + 0x4E0A, KANJI_LEVEL4, // 侊 + 0x4E08, KANJI_LEVEL4, // 䞈 + 0x4E1E, KANJI_LEVEL4, // 侞 + 0x4E57, KANJI_LEVEL4, // 乗 + 0x5197, KANJI_LEVEL4, // 冗 + 0x5270, KANJI_LEVEL4, // 剰 + 0x57CE, KANJI_LEVEL4, // 城 + 0x5834, KANJI_LEVEL4, // å Ž + 0x58CC, KANJI_LEVEL4, // 壌 + 0x5B22, KANJI_LEVEL4, // 嬢 + 0x5E38, KANJI_LEVEL4, // åžž + 0x60C5, KANJI_LEVEL4, // 情 + 0x64FE, KANJI_LEVEL4, // 擟 + 0x6761, KANJI_LEVEL4, // 条 + 0x6756, KANJI_LEVEL4, // 杖 + 0x6D44, KANJI_LEVEL4, // 浄 + 0x72B6, KANJI_LEVEL4, // 状 + 0x7573, KANJI_LEVEL4, // 畳 + 0x7A63, KANJI_LEVEL4, // ç©£ + 0x84B8, KANJI_LEVEL4, // è’ž + 0x8B72, KANJI_LEVEL4, // è­² + 0x91B8, KANJI_LEVEL4, // 醾 + 0x9320, KANJI_LEVEL4, // 錠 + 0x5631, KANJI_LEVEL4, // 嘱 + 0x57F4, KANJI_LEVEL4, // 城 + 0x98FE, KANJI_LEVEL4, // 食 + 0x62ED, KANJI_LEVEL4, // 拭 + 0x690D, KANJI_LEVEL4, // 怍 + 0x6B96, KANJI_LEVEL4, // 殖 + 0x71ED, KANJI_LEVEL4, // 燭 + 0x7E54, KANJI_LEVEL4, // 織 + 0x8077, KANJI_LEVEL4, // 職 + 0x8272, KANJI_LEVEL4, // 色 + 0x89E6, KANJI_LEVEL4, // è§Š + 0x98DF, KANJI_LEVEL4, // 食 + 0x8755, KANJI_LEVEL4, // 蝕 + 0x8FB1, KANJI_LEVEL4, // 蟱 + 0x5C3B, KANJI_LEVEL4, // å°» + 0x4F38, KANJI_LEVEL4, // 䌞 + 0x4FE1, KANJI_LEVEL4, // ä¿¡ + 0x4FB5, KANJI_LEVEL4, // 䟵 + 0x5507, KANJI_LEVEL4, // 唇 + 0x5A20, KANJI_LEVEL4, // åš  + 0x5BDD, KANJI_LEVEL4, // 寝 + 0x5BE9, KANJI_LEVEL4, // 審 + 0x5FC3, KANJI_LEVEL4, // 心 + 0x614E, KANJI_LEVEL4, // 慎 + 0x632F, KANJI_LEVEL4, // 振 + 0x65B0, KANJI_LEVEL4, // 新 + 0x664B, KANJI_LEVEL4, // 晋 + 0x68EE, KANJI_LEVEL4, // 森 + 0x699B, KANJI_LEVEL4, // 抛 + 0x6D78, KANJI_LEVEL4, // 浞 + 0x6DF1, KANJI_LEVEL4, // æ·± + 0x7533, KANJI_LEVEL4, // 申 + 0x75B9, KANJI_LEVEL4, // 疹 + 0x771F, KANJI_LEVEL4, // 真 + 0x795E, KANJI_LEVEL4, // 神 + 0x79E6, KANJI_LEVEL4, // ç§Š + 0x7D33, KANJI_LEVEL4, // 玳 + 0x81E3, KANJI_LEVEL4, // 臣 + 0x82AF, KANJI_LEVEL4, // 芯 + 0x85AA, KANJI_LEVEL4, // 薪 + 0x89AA, KANJI_LEVEL4, // 芪 + 0x8A3A, KANJI_LEVEL4, // 蚺 + 0x8EAB, KANJI_LEVEL4, // 身 + 0x8F9B, KANJI_LEVEL4, // 蟛 + 0x9032, KANJI_LEVEL4, // 進 + 0x91DD, KANJI_LEVEL4, // 針 + 0x9707, KANJI_LEVEL4, // 震 + 0x4EBA, KANJI_LEVEL4, // 人 + 0x4EC1, KANJI_LEVEL4, // 仁 + 0x5203, KANJI_LEVEL4, // 刃 + 0x5875, KANJI_LEVEL4, // 塵 + 0x58EC, KANJI_LEVEL4, // 壬 + 0x5C0B, KANJI_LEVEL4, // 尋 + 0x751A, KANJI_LEVEL4, // 甚 + 0x5C3D, KANJI_LEVEL4, // å°œ + 0x814E, KANJI_LEVEL4, // 腎 + 0x8A0A, KANJI_LEVEL4, // 蚊 + 0x8FC5, KANJI_LEVEL4, // 迅 + 0x9663, KANJI_LEVEL4, // 陣 + 0x976D, KANJI_LEVEL4, // 靭 + 0x7B25, KANJI_LEVEL4, // 笥 + 0x8ACF, KANJI_LEVEL4, // 諏 + 0x9808, KANJI_LEVEL4, // 須 + 0x9162, KANJI_LEVEL4, // 酢 + 0x56F3, KANJI_LEVEL4, // 図 + 0x53A8, KANJI_LEVEL4, // 厚 + 0x9017, KANJI_LEVEL4, // 逗 + 0x5439, KANJI_LEVEL4, // 吹 + 0x5782, KANJI_LEVEL4, // 垂 + 0x5E25, KANJI_LEVEL4, // 垥 + 0x63A8, KANJI_LEVEL4, // 掚 + 0x6C34, KANJI_LEVEL4, // æ°Ž + 0x708A, KANJI_LEVEL4, // 炊 + 0x7761, KANJI_LEVEL4, // 睡 + 0x7C8B, KANJI_LEVEL4, // 粋 + 0x7FE0, KANJI_LEVEL4, // ç¿  + 0x8870, KANJI_LEVEL4, // è¡° + 0x9042, KANJI_LEVEL4, // 遂 + 0x9154, KANJI_LEVEL4, // 酔 + 0x9310, KANJI_LEVEL4, // 錐 + 0x9318, KANJI_LEVEL4, // 錘 + 0x968F, KANJI_LEVEL4, // 随 + 0x745E, KANJI_LEVEL4, // 瑞 + 0x9AC4, KANJI_LEVEL4, // 髄 + 0x5D07, KANJI_LEVEL4, // 厇 + 0x5D69, KANJI_LEVEL4, // 嵩 + 0x6570, KANJI_LEVEL4, // 数 + 0x67A2, KANJI_LEVEL4, // 枢 + 0x8DA8, KANJI_LEVEL4, // è¶š + 0x96DB, KANJI_LEVEL4, // 雛 + 0x636E, KANJI_LEVEL4, // 据 + 0x6749, KANJI_LEVEL4, // 杉 + 0x6919, KANJI_LEVEL4, // 怙 + 0x83C5, KANJI_LEVEL4, // 菅 + 0x9817, KANJI_LEVEL4, // 頗 + 0x96C0, KANJI_LEVEL4, // 雀 + 0x88FE, KANJI_LEVEL4, // 裟 + 0x6F84, KANJI_LEVEL4, // 柄 + 0x647A, KANJI_LEVEL4, // 摺 + 0x5BF8, KANJI_LEVEL4, // 寞 + 0x4E16, KANJI_LEVEL4, // 侖 + 0x702C, KANJI_LEVEL4, // 瀬 + 0x755D, KANJI_LEVEL4, // 畝 + 0x662F, KANJI_LEVEL4, // 是 + 0x51C4, KANJI_LEVEL4, // 凄 + 0x5236, KANJI_LEVEL4, // 制 + 0x52E2, KANJI_LEVEL4, // 勢 + 0x59D3, KANJI_LEVEL4, // 姓 + 0x5F81, KANJI_LEVEL4, // 埁 + 0x6027, KANJI_LEVEL4, // 性 + 0x6210, KANJI_LEVEL4, // 成 + 0x653F, KANJI_LEVEL4, // 政 + 0x6574, KANJI_LEVEL4, // 敎 + 0x661F, KANJI_LEVEL4, // 星 + 0x6674, KANJI_LEVEL4, // 晎 + 0x68F2, KANJI_LEVEL4, // 棲 + 0x6816, KANJI_LEVEL4, // 栖 + 0x6B63, KANJI_LEVEL4, // æ­£ + 0x6E05, KANJI_LEVEL4, // æž… + 0x7272, KANJI_LEVEL4, // 牲 + 0x751F, KANJI_LEVEL4, // 生 + 0x76DB, KANJI_LEVEL4, // 盛 + 0x7CBE, KANJI_LEVEL4, // 粟 + 0x8056, KANJI_LEVEL4, // 聖 + 0x58F0, KANJI_LEVEL4, // 声 + 0x88FD, KANJI_LEVEL4, // 補 + 0x897F, KANJI_LEVEL4, // 西 + 0x8AA0, KANJI_LEVEL4, // 誠 + 0x8A93, KANJI_LEVEL4, // 誓 + 0x8ACB, KANJI_LEVEL4, // 請 + 0x901D, KANJI_LEVEL4, // 逝 + 0x9192, KANJI_LEVEL4, // 醒 + 0x9752, KANJI_LEVEL4, // 青 + 0x9759, KANJI_LEVEL4, // 静 + 0x6589, KANJI_LEVEL4, // 斉 + 0x7A0E, KANJI_LEVEL4, // 皎 + 0x8106, KANJI_LEVEL4, // 脆 + 0x96BB, KANJI_LEVEL4, // 隻 + 0x5E2D, KANJI_LEVEL4, // åž­ + 0x60DC, KANJI_LEVEL4, // 惜 + 0x621A, KANJI_LEVEL4, // 戚 + 0x65A5, KANJI_LEVEL4, // 斥 + 0x6614, KANJI_LEVEL4, // 昔 + 0x6790, KANJI_LEVEL4, // 析 + 0x77F3, KANJI_LEVEL4, // 石 + 0x7A4D, KANJI_LEVEL4, // 積 + 0x7C4D, KANJI_LEVEL4, // 籍 + 0x7E3E, KANJI_LEVEL4, // 瞟 + 0x810A, KANJI_LEVEL4, // 脊 + 0x8CAC, KANJI_LEVEL4, // 責 + 0x8D64, KANJI_LEVEL4, // èµ€ + 0x8DE1, KANJI_LEVEL4, // è·¡ + 0x8E5F, KANJI_LEVEL4, // 蹟 + 0x78A9, KANJI_LEVEL4, // 碩 + 0x5207, KANJI_LEVEL4, // 切 + 0x62D9, KANJI_LEVEL4, // 拙 + 0x63A5, KANJI_LEVEL4, // 接 + 0x6442, KANJI_LEVEL4, // 摂 + 0x6298, KANJI_LEVEL4, // 折 + 0x8A2D, KANJI_LEVEL4, // èš­ + 0x7A83, KANJI_LEVEL4, // 窃 + 0x7BC0, KANJI_LEVEL4, // 節 + 0x8AAC, KANJI_LEVEL4, // 説 + 0x96EA, KANJI_LEVEL4, // 雪 + 0x7D76, KANJI_LEVEL4, // çµ¶ + 0x820C, KANJI_LEVEL4, // 舌 + 0x8749, KANJI_LEVEL4, // 蝉 + 0x4ED9, KANJI_LEVEL4, // 仙 + 0x5148, KANJI_LEVEL4, // 先 + 0x5343, KANJI_LEVEL4, // 千 + 0x5360, KANJI_LEVEL4, // 占 + 0x5BA3, KANJI_LEVEL4, // 宣 + 0x5C02, KANJI_LEVEL4, // 専 + 0x5C16, KANJI_LEVEL4, // 尖 + 0x5DDD, KANJI_LEVEL4, // 川 + 0x6226, KANJI_LEVEL4, // 戊 + 0x6247, KANJI_LEVEL4, // 扇 + 0x64B0, KANJI_LEVEL4, // 撰 + 0x6813, KANJI_LEVEL4, // 栓 + 0x6834, KANJI_LEVEL4, // æ Ž + 0x6CC9, KANJI_LEVEL4, // 泉 + 0x6D45, KANJI_LEVEL4, // 浅 + 0x6D17, KANJI_LEVEL4, // 掗 + 0x67D3, KANJI_LEVEL4, // 染 + 0x6F5C, KANJI_LEVEL4, // 朜 + 0x714E, KANJI_LEVEL4, // 煎 + 0x717D, KANJI_LEVEL4, // ç…œ + 0x65CB, KANJI_LEVEL4, // 旋 + 0x7A7F, KANJI_LEVEL4, // ç©¿ + 0x7BAD, KANJI_LEVEL4, // ç®­ + 0x7DDA, KANJI_LEVEL4, // 線 + 0x7E4A, KANJI_LEVEL4, // 繊 + 0x7FA8, KANJI_LEVEL4, // 矚 + 0x817A, KANJI_LEVEL4, // 腺 + 0x821B, KANJI_LEVEL4, // 舛 + 0x8239, KANJI_LEVEL4, // 船 + 0x85A6, KANJI_LEVEL4, // è–Š + 0x8A6E, KANJI_LEVEL4, // è©® + 0x8CCE, KANJI_LEVEL4, // 賎 + 0x8DF5, KANJI_LEVEL4, // è·µ + 0x9078, KANJI_LEVEL4, // 遞 + 0x9077, KANJI_LEVEL4, // 遷 + 0x92AD, KANJI_LEVEL4, // 銭 + 0x9291, KANJI_LEVEL4, // 銑 + 0x9583, KANJI_LEVEL4, // 閃 + 0x9BAE, KANJI_LEVEL4, // é®® + 0x524D, KANJI_LEVEL4, // 前 + 0x5584, KANJI_LEVEL4, // 善 + 0x6F38, KANJI_LEVEL4, // 挞 + 0x7136, KANJI_LEVEL4, // 然 + 0x5168, KANJI_LEVEL4, // å…š + 0x7985, KANJI_LEVEL4, // 穅 + 0x7E55, KANJI_LEVEL4, // 繕 + 0x81B3, KANJI_LEVEL4, // 膳 + 0x7CCE, KANJI_LEVEL4, // 糎 + 0x564C, KANJI_LEVEL4, // 噌 + 0x5851, KANJI_LEVEL4, // 塑 + 0x5CA8, KANJI_LEVEL4, // 岚 + 0x63AA, KANJI_LEVEL4, // 措 + 0x66FE, KANJI_LEVEL4, // 曟 + 0x66FD, KANJI_LEVEL4, // 曜 + 0x695A, KANJI_LEVEL4, // 楚 + 0x72D9, KANJI_LEVEL4, // 狙 + 0x758F, KANJI_LEVEL4, // 疏 + 0x758E, KANJI_LEVEL4, // 疎 + 0x790E, KANJI_LEVEL4, // 瀎 + 0x7956, KANJI_LEVEL4, // 祖 + 0x79DF, KANJI_LEVEL4, // 租 + 0x7C97, KANJI_LEVEL4, // 粗 + 0x7D20, KANJI_LEVEL4, // 玠 + 0x7D44, KANJI_LEVEL4, // 組 + 0x8607, KANJI_LEVEL4, // 蘇 + 0x8A34, KANJI_LEVEL4, // 蚎 + 0x963B, KANJI_LEVEL4, // 阻 + 0x9061, KANJI_LEVEL4, // 遡 + 0x9F20, KANJI_LEVEL4, // 錠 + 0x50E7, KANJI_LEVEL4, // 僧 + 0x5275, KANJI_LEVEL4, // 創 + 0x53CC, KANJI_LEVEL4, // 双 + 0x53E2, KANJI_LEVEL4, // 叢 + 0x5009, KANJI_LEVEL4, // 倉 + 0x55AA, KANJI_LEVEL4, // 喪 + 0x58EE, KANJI_LEVEL4, // 壮 + 0x594F, KANJI_LEVEL4, // 奏 + 0x723D, KANJI_LEVEL4, // 爜 + 0x5B8B, KANJI_LEVEL4, // 宋 + 0x5C64, KANJI_LEVEL4, // å±€ + 0x531D, KANJI_LEVEL4, // 匝 + 0x60E3, KANJI_LEVEL4, // 惣 + 0x60F3, KANJI_LEVEL4, // 想 + 0x635C, KANJI_LEVEL4, // 捜 + 0x6383, KANJI_LEVEL4, // 掃 + 0x633F, KANJI_LEVEL4, // 挿 + 0x63BB, KANJI_LEVEL4, // 掻 + 0x64CD, KANJI_LEVEL4, // 操 + 0x65E9, KANJI_LEVEL4, // 早 + 0x66F9, KANJI_LEVEL4, // 曹 + 0x5DE3, KANJI_LEVEL4, // å·£ + 0x69CD, KANJI_LEVEL4, // 槍 + 0x69FD, KANJI_LEVEL4, // æ§œ + 0x6F15, KANJI_LEVEL4, // 挕 + 0x71E5, KANJI_LEVEL4, // 燥 + 0x4E89, KANJI_LEVEL4, // 争 + 0x75E9, KANJI_LEVEL4, // 痩 + 0x76F8, KANJI_LEVEL4, // 盾 + 0x7A93, KANJI_LEVEL4, // 窓 + 0x7CDF, KANJI_LEVEL4, // 糟 + 0x7DCF, KANJI_LEVEL4, // 総 + 0x7D9C, KANJI_LEVEL4, // 綜 + 0x8061, KANJI_LEVEL4, // 聡 + 0x8349, KANJI_LEVEL4, // 草 + 0x8358, KANJI_LEVEL4, // 荘 + 0x846C, KANJI_LEVEL4, // 葬 + 0x84BC, KANJI_LEVEL4, // è’Œ + 0x85FB, KANJI_LEVEL4, // 藻 + 0x88C5, KANJI_LEVEL4, // 装 + 0x8D70, KANJI_LEVEL4, // èµ° + 0x9001, KANJI_LEVEL4, // 送 + 0x906D, KANJI_LEVEL4, // 遭 + 0x9397, KANJI_LEVEL4, // 鎗 + 0x971C, KANJI_LEVEL4, // 霜 + 0x9A12, KANJI_LEVEL4, // 鹒 + 0x50CF, KANJI_LEVEL4, // 像 + 0x5897, KANJI_LEVEL4, // 増 + 0x618E, KANJI_LEVEL4, // 憎 + 0x81D3, KANJI_LEVEL4, // 臓 + 0x8535, KANJI_LEVEL4, // 蔵 + 0x8D08, KANJI_LEVEL4, // 莈 + 0x9020, KANJI_LEVEL4, // 造 + 0x4FC3, KANJI_LEVEL4, // 促 + 0x5074, KANJI_LEVEL4, // 偎 + 0x5247, KANJI_LEVEL4, // 則 + 0x5373, KANJI_LEVEL4, // 即 + 0x606F, KANJI_LEVEL4, // 息 + 0x6349, KANJI_LEVEL4, // 捉 + 0x675F, KANJI_LEVEL4, // 束 + 0x6E2C, KANJI_LEVEL4, // 枬 + 0x8DB3, KANJI_LEVEL4, // è¶³ + 0x901F, KANJI_LEVEL4, // 速 + 0x4FD7, KANJI_LEVEL4, // 俗 + 0x5C5E, KANJI_LEVEL4, // 属 + 0x8CCA, KANJI_LEVEL4, // 賊 + 0x65CF, KANJI_LEVEL4, // 族 + 0x7D9A, KANJI_LEVEL4, // 続 + 0x5352, KANJI_LEVEL4, // 卒 + 0x8896, KANJI_LEVEL4, // 袖 + 0x5176, KANJI_LEVEL4, // 其 + 0x63C3, KANJI_LEVEL4, // 揃 + 0x5B58, KANJI_LEVEL4, // 存 + 0x5B6B, KANJI_LEVEL4, // å­« + 0x5C0A, KANJI_LEVEL4, // 尊 + 0x640D, KANJI_LEVEL4, // 損 + 0x6751, KANJI_LEVEL4, // 村 + 0x905C, KANJI_LEVEL4, // 遜 + 0x4ED6, KANJI_LEVEL4, // 他 + 0x591A, KANJI_LEVEL4, // 倚 + 0x592A, KANJI_LEVEL4, // 倪 + 0x6C70, KANJI_LEVEL4, // æ±° + 0x8A51, KANJI_LEVEL4, // 詑 + 0x553E, KANJI_LEVEL4, // 唟 + 0x5815, KANJI_LEVEL4, // 堕 + 0x59A5, KANJI_LEVEL4, // 劥 + 0x60F0, KANJI_LEVEL4, // 惰 + 0x6253, KANJI_LEVEL4, // 打 + 0x67C1, KANJI_LEVEL4, // 柁 + 0x8235, KANJI_LEVEL4, // 舵 + 0x6955, KANJI_LEVEL4, // 楕 + 0x9640, KANJI_LEVEL4, // 陀 + 0x99C4, KANJI_LEVEL4, // 駄 + 0x9A28, KANJI_LEVEL4, // éšš + 0x4F53, KANJI_LEVEL4, // 䜓 + 0x5806, KANJI_LEVEL4, // 堆 + 0x5BFE, KANJI_LEVEL4, // 察 + 0x8010, KANJI_LEVEL4, // 耐 + 0x5CB1, KANJI_LEVEL4, // å²± + 0x5E2F, KANJI_LEVEL4, // 垯 + 0x5F85, KANJI_LEVEL4, // 埅 + 0x6020, KANJI_LEVEL4, // 怠 + 0x614B, KANJI_LEVEL4, // 態 + 0x6234, KANJI_LEVEL4, // 戎 + 0x66FF, KANJI_LEVEL4, // 替 + 0x6CF0, KANJI_LEVEL4, // æ³° + 0x6EDE, KANJI_LEVEL4, // 滞 + 0x80CE, KANJI_LEVEL4, // 胎 + 0x817F, KANJI_LEVEL4, // 腿 + 0x82D4, KANJI_LEVEL4, // 苔 + 0x888B, KANJI_LEVEL4, // 袋 + 0x8CB8, KANJI_LEVEL4, // 貞 + 0x9000, KANJI_LEVEL4, // 退 + 0x902E, KANJI_LEVEL4, // 逮 + 0x968A, KANJI_LEVEL4, // 隊 + 0x9EDB, KANJI_LEVEL4, // 黛 + 0x9BDB, KANJI_LEVEL4, // 鯛 + 0x4EE3, KANJI_LEVEL4, // 代 + 0x53F0, KANJI_LEVEL4, // 台 + 0x5927, KANJI_LEVEL4, // 倧 + 0x7B2C, KANJI_LEVEL4, // 第 + 0x918D, KANJI_LEVEL4, // 醍 + 0x984C, KANJI_LEVEL4, // 題 + 0x9DF9, KANJI_LEVEL4, // é·¹ + 0x6EDD, KANJI_LEVEL4, // 滝 + 0x7027, KANJI_LEVEL4, // 瀧 + 0x5353, KANJI_LEVEL4, // 卓 + 0x5544, KANJI_LEVEL4, // 啄 + 0x5B85, KANJI_LEVEL4, // 宅 + 0x6258, KANJI_LEVEL4, // 托 + 0x629E, KANJI_LEVEL4, // 択 + 0x62D3, KANJI_LEVEL4, // 拓 + 0x6CA2, KANJI_LEVEL4, // æ²¢ + 0x6FEF, KANJI_LEVEL4, // 濯 + 0x7422, KANJI_LEVEL4, // 琢 + 0x8A17, KANJI_LEVEL4, // èš— + 0x9438, KANJI_LEVEL4, // 鐞 + 0x6FC1, KANJI_LEVEL4, // 濁 + 0x8AFE, KANJI_LEVEL4, // 諟 + 0x8338, KANJI_LEVEL4, // 茞 + 0x51E7, KANJI_LEVEL4, // 凧 + 0x86F8, KANJI_LEVEL4, // 蛞 + 0x53EA, KANJI_LEVEL4, // 只 + 0x53E9, KANJI_LEVEL4, // 叩 + 0x4F46, KANJI_LEVEL4, // 䜆 + 0x9054, KANJI_LEVEL4, // 達 + 0x8FB0, KANJI_LEVEL4, // 蟰 + 0x596A, KANJI_LEVEL4, // 奪 + 0x8131, KANJI_LEVEL4, // 脱 + 0x5DFD, KANJI_LEVEL4, // å·œ + 0x7AEA, KANJI_LEVEL4, // 竪 + 0x8FBF, KANJI_LEVEL4, // 蟿 + 0x68DA, KANJI_LEVEL4, // 棚 + 0x8C37, KANJI_LEVEL4, // è°· + 0x72F8, KANJI_LEVEL4, // 狾 + 0x9C48, KANJI_LEVEL4, // 鱈 + 0x6A3D, KANJI_LEVEL4, // æšœ + 0x8AB0, KANJI_LEVEL4, // 誰 + 0x4E39, KANJI_LEVEL4, // äž¹ + 0x5358, KANJI_LEVEL4, // 単 + 0x5606, KANJI_LEVEL4, // 嘆 + 0x5766, KANJI_LEVEL4, // 坊 + 0x62C5, KANJI_LEVEL4, // 担 + 0x63A2, KANJI_LEVEL4, // 探 + 0x65E6, KANJI_LEVEL4, // æ—Š + 0x6B4E, KANJI_LEVEL4, // 歎 + 0x6DE1, KANJI_LEVEL4, // æ·¡ + 0x6E5B, KANJI_LEVEL4, // 湛 + 0x70AD, KANJI_LEVEL4, // 炭 + 0x77ED, KANJI_LEVEL4, // 短 + 0x7AEF, KANJI_LEVEL4, // 端 + 0x7BAA, KANJI_LEVEL4, // 箪 + 0x7DBB, KANJI_LEVEL4, // ç¶» + 0x803D, KANJI_LEVEL4, // 耜 + 0x80C6, KANJI_LEVEL4, // 胆 + 0x86CB, KANJI_LEVEL4, // 蛋 + 0x8A95, KANJI_LEVEL4, // 誕 + 0x935B, KANJI_LEVEL4, // 鍛 + 0x56E3, KANJI_LEVEL4, // 団 + 0x58C7, KANJI_LEVEL4, // 壇 + 0x5F3E, KANJI_LEVEL4, // 匟 + 0x65AD, KANJI_LEVEL4, // 断 + 0x6696, KANJI_LEVEL4, // 暖 + 0x6A80, KANJI_LEVEL4, // 檀 + 0x6BB5, KANJI_LEVEL4, // 段 + 0x7537, KANJI_LEVEL4, // 男 + 0x8AC7, KANJI_LEVEL4, // 談 + 0x5024, KANJI_LEVEL4, // 倀 + 0x77E5, KANJI_LEVEL4, // 知 + 0x5730, KANJI_LEVEL4, // 地 + 0x5F1B, KANJI_LEVEL4, // 匛 + 0x6065, KANJI_LEVEL4, // 恥 + 0x667A, KANJI_LEVEL4, // 智 + 0x6C60, KANJI_LEVEL4, // æ±  + 0x75F4, KANJI_LEVEL4, // 痮 + 0x7A1A, KANJI_LEVEL4, // 繚 + 0x7F6E, KANJI_LEVEL4, // 眮 + 0x81F4, KANJI_LEVEL4, // 臎 + 0x8718, KANJI_LEVEL4, // 蜘 + 0x9045, KANJI_LEVEL4, // 遅 + 0x99B3, KANJI_LEVEL4, // 銳 + 0x7BC9, KANJI_LEVEL4, // 築 + 0x755C, KANJI_LEVEL4, // 畜 + 0x7AF9, KANJI_LEVEL4, // 竹 + 0x7B51, KANJI_LEVEL4, // 筑 + 0x84C4, KANJI_LEVEL4, // 蓄 + 0x9010, KANJI_LEVEL4, // 逐 + 0x79E9, KANJI_LEVEL4, // ç§© + 0x7A92, KANJI_LEVEL4, // 窒 + 0x8336, KANJI_LEVEL4, // 茶 + 0x5AE1, KANJI_LEVEL4, // å«¡ + 0x7740, KANJI_LEVEL4, // 着 + 0x4E2D, KANJI_LEVEL4, // äž­ + 0x4EF2, KANJI_LEVEL4, // 仲 + 0x5B99, KANJI_LEVEL4, // 宙 + 0x5FE0, KANJI_LEVEL4, // å¿  + 0x62BD, KANJI_LEVEL4, // 抜 + 0x663C, KANJI_LEVEL4, // 昌 + 0x67F1, KANJI_LEVEL4, // 柱 + 0x6CE8, KANJI_LEVEL4, // 泚 + 0x866B, KANJI_LEVEL4, // 虫 + 0x8877, KANJI_LEVEL4, // è¡· + 0x8A3B, KANJI_LEVEL4, // èš» + 0x914E, KANJI_LEVEL4, // 酎 + 0x92F3, KANJI_LEVEL4, // 鋳 + 0x99D0, KANJI_LEVEL4, // 駐 + 0x6A17, KANJI_LEVEL4, // æš— + 0x7026, KANJI_LEVEL4, // 瀩 + 0x732A, KANJI_LEVEL4, // 猪 + 0x82E7, KANJI_LEVEL4, // 苧 + 0x8457, KANJI_LEVEL4, // 著 + 0x8CAF, KANJI_LEVEL4, // 貯 + 0x4E01, KANJI_LEVEL4, // 䞁 + 0x5146, KANJI_LEVEL4, // 兆 + 0x51CB, KANJI_LEVEL4, // 凋 + 0x558B, KANJI_LEVEL4, // 喋 + 0x5BF5, KANJI_LEVEL4, // 寵 + 0x5E16, KANJI_LEVEL4, // åž– + 0x5E33, KANJI_LEVEL4, // åž³ + 0x5E81, KANJI_LEVEL4, // 庁 + 0x5F14, KANJI_LEVEL4, // 匔 + 0x5F35, KANJI_LEVEL4, // 匵 + 0x5F6B, KANJI_LEVEL4, // 圫 + 0x5FB4, KANJI_LEVEL4, // 城 + 0x61F2, KANJI_LEVEL4, // 懲 + 0x6311, KANJI_LEVEL4, // 挑 + 0x66A2, KANJI_LEVEL4, // 暢 + 0x671D, KANJI_LEVEL4, // 朝 + 0x6F6E, KANJI_LEVEL4, // 朮 + 0x7252, KANJI_LEVEL4, // 牒 + 0x753A, KANJI_LEVEL4, // 町 + 0x773A, KANJI_LEVEL4, // 眺 + 0x8074, KANJI_LEVEL4, // 聎 + 0x8139, KANJI_LEVEL4, // 脹 + 0x8178, KANJI_LEVEL4, // è…ž + 0x8776, KANJI_LEVEL4, // 蝶 + 0x8ABF, KANJI_LEVEL4, // 調 + 0x8ADC, KANJI_LEVEL4, // 諜 + 0x8D85, KANJI_LEVEL4, // 超 + 0x8DF3, KANJI_LEVEL4, // è·³ + 0x929A, KANJI_LEVEL4, // 銚 + 0x9577, KANJI_LEVEL4, // 長 + 0x9802, KANJI_LEVEL4, // 頂 + 0x9CE5, KANJI_LEVEL4, // é³¥ + 0x52C5, KANJI_LEVEL4, // 勅 + 0x6357, KANJI_LEVEL4, // 捗 + 0x76F4, KANJI_LEVEL4, // 目 + 0x6715, KANJI_LEVEL4, // 朕 + 0x6C88, KANJI_LEVEL4, // 沈 + 0x73CD, KANJI_LEVEL4, // 珍 + 0x8CC3, KANJI_LEVEL4, // 賃 + 0x93AE, KANJI_LEVEL4, // 鎮 + 0x9673, KANJI_LEVEL4, // 陳 + 0x6D25, KANJI_LEVEL4, // 接 + 0x589C, KANJI_LEVEL4, // 墜 + 0x690E, KANJI_LEVEL4, // 怎 + 0x69CC, KANJI_LEVEL4, // 槌 + 0x8FFD, KANJI_LEVEL4, // 远 + 0x939A, KANJI_LEVEL4, // 鎚 + 0x75DB, KANJI_LEVEL4, // 痛 + 0x901A, KANJI_LEVEL4, // 通 + 0x585A, KANJI_LEVEL4, // 塚 + 0x6802, KANJI_LEVEL4, // 栂 + 0x63B4, KANJI_LEVEL4, // 掎 + 0x69FB, KANJI_LEVEL4, // æ§» + 0x4F43, KANJI_LEVEL4, // 䜃 + 0x6F2C, KANJI_LEVEL4, // 挬 + 0x67D8, KANJI_LEVEL4, // 柘 + 0x8FBB, KANJI_LEVEL4, // 蟻 + 0x8526, KANJI_LEVEL4, // 蔊 + 0x7DB4, KANJI_LEVEL4, // ç¶Ž + 0x9354, KANJI_LEVEL4, // 鍔 + 0x693F, KANJI_LEVEL4, // 怿 + 0x6F70, KANJI_LEVEL4, // 朰 + 0x576A, KANJI_LEVEL4, // 坪 + 0x58F7, KANJI_LEVEL4, // 壷 + 0x5B2C, KANJI_LEVEL4, // 嬬 + 0x7D2C, KANJI_LEVEL4, // 玬 + 0x722A, KANJI_LEVEL4, // 爪 + 0x540A, KANJI_LEVEL4, // 吊 + 0x91E3, KANJI_LEVEL4, // 釣 + 0x9DB4, KANJI_LEVEL4, // é¶Ž + 0x4EAD, KANJI_LEVEL4, // 亭 + 0x4F4E, KANJI_LEVEL4, // 䜎 + 0x505C, KANJI_LEVEL4, // 停 + 0x5075, KANJI_LEVEL4, // 偵 + 0x5243, KANJI_LEVEL4, // 剃 + 0x8C9E, KANJI_LEVEL4, // 貞 + 0x5448, KANJI_LEVEL4, // 呈 + 0x5824, KANJI_LEVEL4, // å € + 0x5B9A, KANJI_LEVEL4, // 定 + 0x5E1D, KANJI_LEVEL4, // 垝 + 0x5E95, KANJI_LEVEL4, // 底 + 0x5EAD, KANJI_LEVEL4, // 庭 + 0x5EF7, KANJI_LEVEL4, // å»· + 0x5F1F, KANJI_LEVEL4, // 匟 + 0x608C, KANJI_LEVEL4, // 悌 + 0x62B5, KANJI_LEVEL4, // 抵 + 0x633A, KANJI_LEVEL4, // 挺 + 0x63D0, KANJI_LEVEL4, // 提 + 0x68AF, KANJI_LEVEL4, // 梯 + 0x6C40, KANJI_LEVEL4, // 汀 + 0x7887, KANJI_LEVEL4, // 碇 + 0x798E, KANJI_LEVEL4, // 犎 + 0x7A0B, KANJI_LEVEL4, // 繋 + 0x7DE0, KANJI_LEVEL4, // ç·  + 0x8247, KANJI_LEVEL4, // 艇 + 0x8A02, KANJI_LEVEL4, // èš‚ + 0x8AE6, KANJI_LEVEL4, // 諊 + 0x8E44, KANJI_LEVEL4, // 蹄 + 0x9013, KANJI_LEVEL4, // 逓 + 0x90B8, KANJI_LEVEL4, // 邾 + 0x912D, KANJI_LEVEL4, // 鄭 + 0x91D8, KANJI_LEVEL4, // 釘 + 0x9F0E, KANJI_LEVEL4, // 錎 + 0x6CE5, KANJI_LEVEL4, // æ³¥ + 0x6458, KANJI_LEVEL4, // 摘 + 0x64E2, KANJI_LEVEL4, // 擢 + 0x6575, KANJI_LEVEL4, // 敵 + 0x6EF4, KANJI_LEVEL4, // 滎 + 0x7684, KANJI_LEVEL4, // 的 + 0x7B1B, KANJI_LEVEL4, // 笛 + 0x9069, KANJI_LEVEL4, // 適 + 0x93D1, KANJI_LEVEL4, // 鏑 + 0x6EBA, KANJI_LEVEL4, // 溺 + 0x54F2, KANJI_LEVEL4, // 哲 + 0x5FB9, KANJI_LEVEL4, // 培 + 0x64A4, KANJI_LEVEL4, // æ’€ + 0x8F4D, KANJI_LEVEL4, // 蜍 + 0x8FED, KANJI_LEVEL4, // è¿­ + 0x9244, KANJI_LEVEL4, // 鉄 + 0x5178, KANJI_LEVEL4, // å…ž + 0x586B, KANJI_LEVEL4, // å¡« + 0x5929, KANJI_LEVEL4, // 倩 + 0x5C55, KANJI_LEVEL4, // 展 + 0x5E97, KANJI_LEVEL4, // 店 + 0x6DFB, KANJI_LEVEL4, // æ·» + 0x7E8F, KANJI_LEVEL4, // 纏 + 0x751C, KANJI_LEVEL4, // 甜 + 0x8CBC, KANJI_LEVEL4, // 貌 + 0x8EE2, KANJI_LEVEL4, // 転 + 0x985B, KANJI_LEVEL4, // 顛 + 0x70B9, KANJI_LEVEL4, // 点 + 0x4F1D, KANJI_LEVEL4, // 䌝 + 0x6BBF, KANJI_LEVEL4, // 殿 + 0x6FB1, KANJI_LEVEL4, // 柱 + 0x7530, KANJI_LEVEL4, // 田 + 0x96FB, KANJI_LEVEL4, // 電 + 0x514E, KANJI_LEVEL4, // 兎 + 0x5410, KANJI_LEVEL4, // 吐 + 0x5835, KANJI_LEVEL4, // å µ + 0x5857, KANJI_LEVEL4, // 塗 + 0x59AC, KANJI_LEVEL4, // 劬 + 0x5C60, KANJI_LEVEL4, // å±  + 0x5F92, KANJI_LEVEL4, // 埒 + 0x6597, KANJI_LEVEL4, // 斗 + 0x675C, KANJI_LEVEL4, // 杜 + 0x6E21, KANJI_LEVEL4, // æž¡ + 0x767B, KANJI_LEVEL4, // 登 + 0x83DF, KANJI_LEVEL4, // 菟 + 0x8CED, KANJI_LEVEL4, // è³­ + 0x9014, KANJI_LEVEL4, // 途 + 0x90FD, KANJI_LEVEL4, // 郜 + 0x934D, KANJI_LEVEL4, // 鍍 + 0x7825, KANJI_LEVEL4, // ç ¥ + 0x783A, KANJI_LEVEL4, // ç º + 0x52AA, KANJI_LEVEL4, // 努 + 0x5EA6, KANJI_LEVEL4, // 床 + 0x571F, KANJI_LEVEL4, // 土 + 0x5974, KANJI_LEVEL4, // 奎 + 0x6012, KANJI_LEVEL4, // 怒 + 0x5012, KANJI_LEVEL4, // 倒 + 0x515A, KANJI_LEVEL4, // 党 + 0x51AC, KANJI_LEVEL4, // 冬 + 0x51CD, KANJI_LEVEL4, // 凍 + 0x5200, KANJI_LEVEL4, // 刀 + 0x5510, KANJI_LEVEL4, // 唐 + 0x5854, KANJI_LEVEL4, // 塔 + 0x5858, KANJI_LEVEL4, // 塘 + 0x5957, KANJI_LEVEL4, // 套 + 0x5B95, KANJI_LEVEL4, // 宕 + 0x5CF6, KANJI_LEVEL4, // å³¶ + 0x5D8B, KANJI_LEVEL4, // 嶋 + 0x60BC, KANJI_LEVEL4, // 悌 + 0x6295, KANJI_LEVEL4, // 投 + 0x642D, KANJI_LEVEL4, // 搭 + 0x6771, KANJI_LEVEL4, // 東 + 0x6843, KANJI_LEVEL4, // 桃 + 0x68BC, KANJI_LEVEL4, // 梌 + 0x68DF, KANJI_LEVEL4, // 棟 + 0x76D7, KANJI_LEVEL4, // 盗 + 0x6DD8, KANJI_LEVEL4, // 淘 + 0x6E6F, KANJI_LEVEL4, // 湯 + 0x6D9B, KANJI_LEVEL4, // 涛 + 0x706F, KANJI_LEVEL4, // 灯 + 0x71C8, KANJI_LEVEL4, // 燈 + 0x5F53, KANJI_LEVEL4, // 圓 + 0x75D8, KANJI_LEVEL4, // 痘 + 0x7977, KANJI_LEVEL4, // 祷 + 0x7B49, KANJI_LEVEL4, // 等 + 0x7B54, KANJI_LEVEL4, // 答 + 0x7B52, KANJI_LEVEL4, // 筒 + 0x7CD6, KANJI_LEVEL4, // 糖 + 0x7D71, KANJI_LEVEL4, // çµ± + 0x5230, KANJI_LEVEL4, // 到 + 0x8463, KANJI_LEVEL4, // 董 + 0x8569, KANJI_LEVEL4, // 蕩 + 0x85E4, KANJI_LEVEL4, // è—€ + 0x8A0E, KANJI_LEVEL4, // 蚎 + 0x8B04, KANJI_LEVEL4, // 謄 + 0x8C46, KANJI_LEVEL4, // 豆 + 0x8E0F, KANJI_LEVEL4, // 螏 + 0x9003, KANJI_LEVEL4, // 逃 + 0x900F, KANJI_LEVEL4, // 透 + 0x9419, KANJI_LEVEL4, // 鐙 + 0x9676, KANJI_LEVEL4, // 陶 + 0x982D, KANJI_LEVEL4, // é ­ + 0x9A30, KANJI_LEVEL4, // éš° + 0x95D8, KANJI_LEVEL4, // 闘 + 0x50CD, KANJI_LEVEL4, // 働 + 0x52D5, KANJI_LEVEL4, // 動 + 0x540C, KANJI_LEVEL4, // 同 + 0x5802, KANJI_LEVEL4, // 堂 + 0x5C0E, KANJI_LEVEL4, // 導 + 0x61A7, KANJI_LEVEL4, // 憧 + 0x649E, KANJI_LEVEL4, // 撞 + 0x6D1E, KANJI_LEVEL4, // 掞 + 0x77B3, KANJI_LEVEL4, // 瞳 + 0x7AE5, KANJI_LEVEL4, // ç«¥ + 0x80F4, KANJI_LEVEL4, // 胎 + 0x8404, KANJI_LEVEL4, // 萄 + 0x9053, KANJI_LEVEL4, // 道 + 0x9285, KANJI_LEVEL4, // 銅 + 0x5CE0, KANJI_LEVEL4, // å³  + 0x9D07, KANJI_LEVEL4, // 鮇 + 0x533F, KANJI_LEVEL4, // 匿 + 0x5F97, KANJI_LEVEL4, // 埗 + 0x5FB3, KANJI_LEVEL4, // 埳 + 0x6D9C, KANJI_LEVEL4, // 涜 + 0x7279, KANJI_LEVEL4, // 特 + 0x7763, KANJI_LEVEL4, // 督 + 0x79BF, KANJI_LEVEL4, // 犿 + 0x7BE4, KANJI_LEVEL4, // 節 + 0x6BD2, KANJI_LEVEL4, // 毒 + 0x72EC, KANJI_LEVEL4, // 独 + 0x8AAD, KANJI_LEVEL4, // 読 + 0x6803, KANJI_LEVEL4, // 栃 + 0x6A61, KANJI_LEVEL4, // æ©¡ + 0x51F8, KANJI_LEVEL4, // 凞 + 0x7A81, KANJI_LEVEL4, // 突 + 0x6934, KANJI_LEVEL4, // 怎 + 0x5C4A, KANJI_LEVEL4, // 届 + 0x9CF6, KANJI_LEVEL4, // é³¶ + 0x82EB, KANJI_LEVEL4, // 苫 + 0x5BC5, KANJI_LEVEL4, // 寅 + 0x9149, KANJI_LEVEL4, // 酉 + 0x701E, KANJI_LEVEL4, // 瀞 + 0x5678, KANJI_LEVEL4, // 噞 + 0x5C6F, KANJI_LEVEL4, // 屯 + 0x60C7, KANJI_LEVEL4, // 惇 + 0x6566, KANJI_LEVEL4, // 敊 + 0x6C8C, KANJI_LEVEL4, // 沌 + 0x8C5A, KANJI_LEVEL4, // 豚 + 0x9041, KANJI_LEVEL4, // 遁 + 0x9813, KANJI_LEVEL4, // 頓 + 0x5451, KANJI_LEVEL4, // 呑 + 0x66C7, KANJI_LEVEL4, // 曇 + 0x920D, KANJI_LEVEL4, // 鈍 + 0x5948, KANJI_LEVEL4, // 奈 + 0x90A3, KANJI_LEVEL4, // 那 + 0x5185, KANJI_LEVEL4, // 内 + 0x4E4D, KANJI_LEVEL4, // 乍 + 0x51EA, KANJI_LEVEL4, // 凪 + 0x8599, KANJI_LEVEL4, // 薙 + 0x8B0E, KANJI_LEVEL4, // 謎 + 0x7058, KANJI_LEVEL4, // 灘 + 0x637A, KANJI_LEVEL4, // 捺 + 0x934B, KANJI_LEVEL4, // 鍋 + 0x6962, KANJI_LEVEL4, // 楢 + 0x99B4, KANJI_LEVEL4, // 銎 + 0x7E04, KANJI_LEVEL4, // 羄 + 0x7577, KANJI_LEVEL4, // 畷 + 0x5357, KANJI_LEVEL4, // 南 + 0x6960, KANJI_LEVEL4, // 楠 + 0x8EDF, KANJI_LEVEL4, // 軟 + 0x96E3, KANJI_LEVEL4, // 難 + 0x6C5D, KANJI_LEVEL4, // 汝 + 0x4E8C, KANJI_LEVEL4, // 二 + 0x5C3C, KANJI_LEVEL4, // å°Œ + 0x5F10, KANJI_LEVEL4, // 匐 + 0x8FE9, KANJI_LEVEL4, // è¿© + 0x5302, KANJI_LEVEL4, // 匂 + 0x8CD1, KANJI_LEVEL4, // 賑 + 0x8089, KANJI_LEVEL4, // 肉 + 0x8679, KANJI_LEVEL4, // 虹 + 0x5EFF, KANJI_LEVEL4, // 廿 + 0x65E5, KANJI_LEVEL4, // 日 + 0x4E73, KANJI_LEVEL4, // ä¹³ + 0x5165, KANJI_LEVEL4, // 入 + 0x5982, KANJI_LEVEL4, // 劂 + 0x5C3F, KANJI_LEVEL4, // å°¿ + 0x97EE, KANJI_LEVEL4, // 韮 + 0x4EFB, KANJI_LEVEL4, // ä»» + 0x598A, KANJI_LEVEL4, // 劊 + 0x5FCD, KANJI_LEVEL4, // 忍 + 0x8A8D, KANJI_LEVEL4, // 認 + 0x6FE1, KANJI_LEVEL4, // æ¿¡ + 0x79B0, KANJI_LEVEL4, // 犰 + 0x7962, KANJI_LEVEL4, // 祢 + 0x5BE7, KANJI_LEVEL4, // 寧 + 0x8471, KANJI_LEVEL4, // 葱 + 0x732B, KANJI_LEVEL4, // 猫 + 0x71B1, KANJI_LEVEL4, // 熱 + 0x5E74, KANJI_LEVEL4, // 幎 + 0x5FF5, KANJI_LEVEL4, // 念 + 0x637B, KANJI_LEVEL4, // 捻 + 0x649A, KANJI_LEVEL4, // 撚 + 0x71C3, KANJI_LEVEL4, // 燃 + 0x7C98, KANJI_LEVEL4, // 粘 + 0x4E43, KANJI_LEVEL4, // 乃 + 0x5EFC, KANJI_LEVEL4, // 廌 + 0x4E4B, KANJI_LEVEL4, // 之 + 0x57DC, KANJI_LEVEL4, // 埜 + 0x56A2, KANJI_LEVEL4, // 嚢 + 0x60A9, KANJI_LEVEL4, // 悩 + 0x6FC3, KANJI_LEVEL4, // 濃 + 0x7D0D, KANJI_LEVEL4, // 玍 + 0x80FD, KANJI_LEVEL4, // 胜 + 0x8133, KANJI_LEVEL4, // 脳 + 0x81BF, KANJI_LEVEL4, // 膿 + 0x8FB2, KANJI_LEVEL4, // 蟲 + 0x8997, KANJI_LEVEL4, // 芗 + 0x86A4, KANJI_LEVEL4, // 蚀 + 0x5DF4, KANJI_LEVEL4, // å·Ž + 0x628A, KANJI_LEVEL4, // 把 + 0x64AD, KANJI_LEVEL4, // 播 + 0x8987, KANJI_LEVEL4, // 芇 + 0x6777, KANJI_LEVEL4, // 杷 + 0x6CE2, KANJI_LEVEL4, // æ³¢ + 0x6D3E, KANJI_LEVEL4, // 掟 + 0x7436, KANJI_LEVEL4, // 琶 + 0x7834, KANJI_LEVEL4, // ç Ž + 0x5A46, KANJI_LEVEL4, // 婆 + 0x7F75, KANJI_LEVEL4, // 眵 + 0x82AD, KANJI_LEVEL4, // 芭 + 0x99AC, KANJI_LEVEL4, // 銬 + 0x4FF3, KANJI_LEVEL4, // 俳 + 0x5EC3, KANJI_LEVEL4, // 廃 + 0x62DD, KANJI_LEVEL4, // 拝 + 0x6392, KANJI_LEVEL4, // 排 + 0x6557, KANJI_LEVEL4, // 敗 + 0x676F, KANJI_LEVEL4, // 杯 + 0x76C3, KANJI_LEVEL4, // 盃 + 0x724C, KANJI_LEVEL4, // 牌 + 0x80CC, KANJI_LEVEL4, // 背 + 0x80BA, KANJI_LEVEL4, // 肺 + 0x8F29, KANJI_LEVEL4, // 茩 + 0x914D, KANJI_LEVEL4, // 配 + 0x500D, KANJI_LEVEL4, // 倍 + 0x57F9, KANJI_LEVEL4, // 培 + 0x5A92, KANJI_LEVEL4, // 媒 + 0x6885, KANJI_LEVEL4, // 梅 + 0x6973, KANJI_LEVEL4, // 楳 + 0x7164, KANJI_LEVEL4, // ç…€ + 0x72FD, KANJI_LEVEL4, // 狜 + 0x8CB7, KANJI_LEVEL4, // è²· + 0x58F2, KANJI_LEVEL4, // 売 + 0x8CE0, KANJI_LEVEL4, // è³  + 0x966A, KANJI_LEVEL4, // 陪 + 0x9019, KANJI_LEVEL4, // 這 + 0x877F, KANJI_LEVEL4, // 蝿 + 0x79E4, KANJI_LEVEL4, // ç§€ + 0x77E7, KANJI_LEVEL4, // 矧 + 0x8429, KANJI_LEVEL4, // 萩 + 0x4F2F, KANJI_LEVEL4, // 䌯 + 0x5265, KANJI_LEVEL4, // 剥 + 0x535A, KANJI_LEVEL4, // 博 + 0x62CD, KANJI_LEVEL4, // 拍 + 0x67CF, KANJI_LEVEL4, // 柏 + 0x6CCA, KANJI_LEVEL4, // 泊 + 0x767D, KANJI_LEVEL4, // 癜 + 0x7B94, KANJI_LEVEL4, // 箔 + 0x7C95, KANJI_LEVEL4, // 粕 + 0x8236, KANJI_LEVEL4, // 舶 + 0x8584, KANJI_LEVEL4, // 薄 + 0x8FEB, KANJI_LEVEL4, // è¿« + 0x66DD, KANJI_LEVEL4, // 曝 + 0x6F20, KANJI_LEVEL4, // 挠 + 0x7206, KANJI_LEVEL4, // 爆 + 0x7E1B, KANJI_LEVEL4, // 羛 + 0x83AB, KANJI_LEVEL4, // 莫 + 0x99C1, KANJI_LEVEL4, // 駁 + 0x9EA6, KANJI_LEVEL4, // 麊 + 0x51FD, KANJI_LEVEL4, // 凜 + 0x7BB1, KANJI_LEVEL4, // ç®± + 0x7872, KANJI_LEVEL4, // 硲 + 0x7BB8, KANJI_LEVEL4, // 箞 + 0x8087, KANJI_LEVEL4, // 肇 + 0x7B48, KANJI_LEVEL4, // 筈 + 0x6AE8, KANJI_LEVEL4, // 櫚 + 0x5E61, KANJI_LEVEL4, // 幡 + 0x808C, KANJI_LEVEL4, // 肌 + 0x7551, KANJI_LEVEL4, // 畑 + 0x7560, KANJI_LEVEL4, // 畠 + 0x516B, KANJI_LEVEL4, // 八 + 0x9262, KANJI_LEVEL4, // 鉢 + 0x6E8C, KANJI_LEVEL4, // 溌 + 0x767A, KANJI_LEVEL4, // 発 + 0x9197, KANJI_LEVEL4, // 醗 + 0x9AEA, KANJI_LEVEL4, // 髪 + 0x4F10, KANJI_LEVEL4, // 䌐 + 0x7F70, KANJI_LEVEL4, // 眰 + 0x629C, KANJI_LEVEL4, // 抜 + 0x7B4F, KANJI_LEVEL4, // 筏 + 0x95A5, KANJI_LEVEL4, // 閥 + 0x9CE9, KANJI_LEVEL4, // 鳩 + 0x567A, KANJI_LEVEL4, // 噺 + 0x5859, KANJI_LEVEL4, // 塙 + 0x86E4, KANJI_LEVEL4, // 蛀 + 0x96BC, KANJI_LEVEL4, // 隌 + 0x4F34, KANJI_LEVEL4, // 䌎 + 0x5224, KANJI_LEVEL4, // 刀 + 0x534A, KANJI_LEVEL4, // 半 + 0x53CD, KANJI_LEVEL4, // 反 + 0x53DB, KANJI_LEVEL4, // 叛 + 0x5E06, KANJI_LEVEL4, // 垆 + 0x642C, KANJI_LEVEL4, // 搬 + 0x6591, KANJI_LEVEL4, // 斑 + 0x677F, KANJI_LEVEL4, // 板 + 0x6C3E, KANJI_LEVEL4, // æ°Ÿ + 0x6C4E, KANJI_LEVEL4, // 汎 + 0x7248, KANJI_LEVEL4, // 版 + 0x72AF, KANJI_LEVEL4, // 犯 + 0x73ED, KANJI_LEVEL4, // 班 + 0x7554, KANJI_LEVEL4, // 畔 + 0x7E41, KANJI_LEVEL4, // 繁 + 0x822C, KANJI_LEVEL4, // 般 + 0x85E9, KANJI_LEVEL4, // 藩 + 0x8CA9, KANJI_LEVEL4, // 販 + 0x7BC4, KANJI_LEVEL4, // 範 + 0x91C6, KANJI_LEVEL4, // 釆 + 0x7169, KANJI_LEVEL4, // 煩 + 0x9812, KANJI_LEVEL4, // 頒 + 0x98EF, KANJI_LEVEL4, // 飯 + 0x633D, KANJI_LEVEL4, // 挜 + 0x6669, KANJI_LEVEL4, // 晩 + 0x756A, KANJI_LEVEL4, // 番 + 0x76E4, KANJI_LEVEL4, // 盀 + 0x78D0, KANJI_LEVEL4, // 磐 + 0x8543, KANJI_LEVEL4, // 蕃 + 0x86EE, KANJI_LEVEL4, // 蛮 + 0x532A, KANJI_LEVEL4, // 匪 + 0x5351, KANJI_LEVEL4, // 卑 + 0x5426, KANJI_LEVEL4, // 吊 + 0x5983, KANJI_LEVEL4, // 劃 + 0x5E87, KANJI_LEVEL4, // 庇 + 0x5F7C, KANJI_LEVEL4, // 圌 + 0x60B2, KANJI_LEVEL4, // 悲 + 0x6249, KANJI_LEVEL4, // 扉 + 0x6279, KANJI_LEVEL4, // 批 + 0x62AB, KANJI_LEVEL4, // 披 + 0x6590, KANJI_LEVEL4, // 斐 + 0x6BD4, KANJI_LEVEL4, // 比 + 0x6CCC, KANJI_LEVEL4, // 泌 + 0x75B2, KANJI_LEVEL4, // 疲 + 0x76AE, KANJI_LEVEL4, // 皮 + 0x7891, KANJI_LEVEL4, // 碑 + 0x79D8, KANJI_LEVEL4, // 秘 + 0x7DCB, KANJI_LEVEL4, // 緋 + 0x7F77, KANJI_LEVEL4, // 眷 + 0x80A5, KANJI_LEVEL4, // 肥 + 0x88AB, KANJI_LEVEL4, // 被 + 0x8AB9, KANJI_LEVEL4, // 誹 + 0x8CBB, KANJI_LEVEL4, // è²» + 0x907F, KANJI_LEVEL4, // 避 + 0x975E, KANJI_LEVEL4, // 非 + 0x98DB, KANJI_LEVEL4, // 飛 + 0x6A0B, KANJI_LEVEL4, // æš‹ + 0x7C38, KANJI_LEVEL4, // ç°ž + 0x5099, KANJI_LEVEL4, // 備 + 0x5C3E, KANJI_LEVEL4, // å°Ÿ + 0x5FAE, KANJI_LEVEL4, // 埮 + 0x6787, KANJI_LEVEL4, // 枇 + 0x6BD8, KANJI_LEVEL4, // 毘 + 0x7435, KANJI_LEVEL4, // 琵 + 0x7709, KANJI_LEVEL4, // 眉 + 0x7F8E, KANJI_LEVEL4, // 矎 + 0x9F3B, KANJI_LEVEL4, // 錻 + 0x67CA, KANJI_LEVEL4, // 柊 + 0x7A17, KANJI_LEVEL4, // 繗 + 0x5339, KANJI_LEVEL4, // 匹 + 0x758B, KANJI_LEVEL4, // 疋 + 0x9AED, KANJI_LEVEL4, // é«­ + 0x5F66, KANJI_LEVEL4, // 圊 + 0x819D, KANJI_LEVEL4, // 膝 + 0x83F1, KANJI_LEVEL4, // 菱 + 0x8098, KANJI_LEVEL4, // 肘 + 0x5F3C, KANJI_LEVEL4, // 匌 + 0x5FC5, KANJI_LEVEL4, // 必 + 0x7562, KANJI_LEVEL4, // 畢 + 0x7B46, KANJI_LEVEL4, // 筆 + 0x903C, KANJI_LEVEL4, // 逌 + 0x6867, KANJI_LEVEL4, // æ¡§ + 0x59EB, KANJI_LEVEL4, // å§« + 0x5A9B, KANJI_LEVEL4, // 媛 + 0x7D10, KANJI_LEVEL4, // 玐 + 0x767E, KANJI_LEVEL4, // 癟 + 0x8B2C, KANJI_LEVEL4, // 謬 + 0x4FF5, KANJI_LEVEL4, // 俵 + 0x5F6A, KANJI_LEVEL4, // 圪 + 0x6A19, KANJI_LEVEL4, // æš™ + 0x6C37, KANJI_LEVEL4, // æ°· + 0x6F02, KANJI_LEVEL4, // 挂 + 0x74E2, KANJI_LEVEL4, // 瓢 + 0x7968, KANJI_LEVEL4, // 祚 + 0x8868, KANJI_LEVEL4, // 衚 + 0x8A55, KANJI_LEVEL4, // 評 + 0x8C79, KANJI_LEVEL4, // è±¹ + 0x5EDF, KANJI_LEVEL4, // 廟 + 0x63CF, KANJI_LEVEL4, // 描 + 0x75C5, KANJI_LEVEL4, // 病 + 0x79D2, KANJI_LEVEL4, // 秒 + 0x82D7, KANJI_LEVEL4, // 苗 + 0x9328, KANJI_LEVEL4, // 錹 + 0x92F2, KANJI_LEVEL4, // 鋲 + 0x849C, KANJI_LEVEL4, // 蒜 + 0x86ED, KANJI_LEVEL4, // 蛭 + 0x9C2D, KANJI_LEVEL4, // é°­ + 0x54C1, KANJI_LEVEL4, // 品 + 0x5F6C, KANJI_LEVEL4, // 圬 + 0x658C, KANJI_LEVEL4, // 斌 + 0x6D5C, KANJI_LEVEL4, // 浜 + 0x7015, KANJI_LEVEL4, // 瀕 + 0x8CA7, KANJI_LEVEL4, // è²§ + 0x8CD3, KANJI_LEVEL4, // 賓 + 0x983B, KANJI_LEVEL4, // é » + 0x654F, KANJI_LEVEL4, // 敏 + 0x74F6, KANJI_LEVEL4, // 瓶 + 0x4E0D, KANJI_LEVEL4, // 䞍 + 0x4ED8, KANJI_LEVEL4, // 付 + 0x57E0, KANJI_LEVEL4, // 埠 + 0x592B, KANJI_LEVEL4, // 倫 + 0x5A66, KANJI_LEVEL4, // 婊 + 0x5BCC, KANJI_LEVEL4, // 富 + 0x51A8, KANJI_LEVEL4, // 冚 + 0x5E03, KANJI_LEVEL4, // 垃 + 0x5E9C, KANJI_LEVEL4, // 府 + 0x6016, KANJI_LEVEL4, // 怖 + 0x6276, KANJI_LEVEL4, // 扶 + 0x6577, KANJI_LEVEL4, // 敷 + 0x65A7, KANJI_LEVEL4, // 斧 + 0x666E, KANJI_LEVEL4, // 普 + 0x6D6E, KANJI_LEVEL4, // æµ® + 0x7236, KANJI_LEVEL4, // 父 + 0x7B26, KANJI_LEVEL4, // 笊 + 0x8150, KANJI_LEVEL4, // 腐 + 0x819A, KANJI_LEVEL4, // 膚 + 0x8299, KANJI_LEVEL4, // 芙 + 0x8B5C, KANJI_LEVEL4, // 譜 + 0x8CA0, KANJI_LEVEL4, // è²  + 0x8CE6, KANJI_LEVEL4, // 賊 + 0x8D74, KANJI_LEVEL4, // 赎 + 0x961C, KANJI_LEVEL4, // 阜 + 0x9644, KANJI_LEVEL4, // 附 + 0x4FAE, KANJI_LEVEL4, // 䟮 + 0x64AB, KANJI_LEVEL4, // 撫 + 0x6B66, KANJI_LEVEL4, // æ­Š + 0x821E, KANJI_LEVEL4, // 舞 + 0x8461, KANJI_LEVEL4, // 葡 + 0x856A, KANJI_LEVEL4, // 蕪 + 0x90E8, KANJI_LEVEL4, // 郚 + 0x5C01, KANJI_LEVEL4, // 封 + 0x6953, KANJI_LEVEL4, // 楓 + 0x98A8, KANJI_LEVEL4, // 颚 + 0x847A, KANJI_LEVEL4, // 葺 + 0x8557, KANJI_LEVEL4, // 蕗 + 0x4F0F, KANJI_LEVEL4, // 䌏 + 0x526F, KANJI_LEVEL4, // 副 + 0x5FA9, KANJI_LEVEL4, // 埩 + 0x5E45, KANJI_LEVEL4, // 幅 + 0x670D, KANJI_LEVEL4, // 服 + 0x798F, KANJI_LEVEL4, // 犏 + 0x8179, KANJI_LEVEL4, // 腹 + 0x8907, KANJI_LEVEL4, // 耇 + 0x8986, KANJI_LEVEL4, // 芆 + 0x6DF5, KANJI_LEVEL4, // æ·µ + 0x5F17, KANJI_LEVEL4, // 北 + 0x6255, KANJI_LEVEL4, // 払 + 0x6CB8, KANJI_LEVEL4, // 沞 + 0x4ECF, KANJI_LEVEL4, // 仏 + 0x7269, KANJI_LEVEL4, // 物 + 0x9B92, KANJI_LEVEL4, // 鮒 + 0x5206, KANJI_LEVEL4, // 分 + 0x543B, KANJI_LEVEL4, // 吻 + 0x5674, KANJI_LEVEL4, // 噎 + 0x58B3, KANJI_LEVEL4, // 墳 + 0x61A4, KANJI_LEVEL4, // 憀 + 0x626E, KANJI_LEVEL4, // 扮 + 0x711A, KANJI_LEVEL4, // 焚 + 0x596E, KANJI_LEVEL4, // 奮 + 0x7C89, KANJI_LEVEL4, // 粉 + 0x7CDE, KANJI_LEVEL4, // 糞 + 0x7D1B, KANJI_LEVEL4, // 箛 + 0x96F0, KANJI_LEVEL4, // 雰 + 0x6587, KANJI_LEVEL4, // 文 + 0x805E, KANJI_LEVEL4, // 聞 + 0x4E19, KANJI_LEVEL4, // 侙 + 0x4F75, KANJI_LEVEL4, // 䜵 + 0x5175, KANJI_LEVEL4, // 兵 + 0x5840, KANJI_LEVEL4, // 塀 + 0x5E63, KANJI_LEVEL4, // å¹£ + 0x5E73, KANJI_LEVEL4, // å¹³ + 0x5F0A, KANJI_LEVEL4, // 匊 + 0x67C4, KANJI_LEVEL4, // 柄 + 0x4E26, KANJI_LEVEL4, // 䞊 + 0x853D, KANJI_LEVEL4, // 蔜 + 0x9589, KANJI_LEVEL4, // 閉 + 0x965B, KANJI_LEVEL4, // 陛 + 0x7C73, KANJI_LEVEL4, // ç±³ + 0x9801, KANJI_LEVEL4, // 頁 + 0x50FB, KANJI_LEVEL4, // 僻 + 0x58C1, KANJI_LEVEL4, // 壁 + 0x7656, KANJI_LEVEL4, // 癖 + 0x78A7, KANJI_LEVEL4, // 碧 + 0x5225, KANJI_LEVEL4, // 別 + 0x77A5, KANJI_LEVEL4, // 瞥 + 0x8511, KANJI_LEVEL4, // 蔑 + 0x7B86, KANJI_LEVEL4, // 箆 + 0x504F, KANJI_LEVEL4, // 偏 + 0x5909, KANJI_LEVEL4, // 倉 + 0x7247, KANJI_LEVEL4, // 片 + 0x7BC7, KANJI_LEVEL4, // 篇 + 0x7DE8, KANJI_LEVEL4, // ç·š + 0x8FBA, KANJI_LEVEL4, // 蟺 + 0x8FD4, KANJI_LEVEL4, // 返 + 0x904D, KANJI_LEVEL4, // 遍 + 0x4FBF, KANJI_LEVEL4, // 䟿 + 0x52C9, KANJI_LEVEL4, // 勉 + 0x5A29, KANJI_LEVEL4, // åš© + 0x5F01, KANJI_LEVEL4, // 匁 + 0x97AD, KANJI_LEVEL4, // 鞭 + 0x4FDD, KANJI_LEVEL4, // 保 + 0x8217, KANJI_LEVEL4, // 舗 + 0x92EA, KANJI_LEVEL4, // 鋪 + 0x5703, KANJI_LEVEL4, // 圃 + 0x6355, KANJI_LEVEL4, // 捕 + 0x6B69, KANJI_LEVEL4, // æ­© + 0x752B, KANJI_LEVEL4, // 甫 + 0x88DC, KANJI_LEVEL4, // 補 + 0x8F14, KANJI_LEVEL4, // 茔 + 0x7A42, KANJI_LEVEL4, // 穂 + 0x52DF, KANJI_LEVEL4, // 募 + 0x5893, KANJI_LEVEL4, // 墓 + 0x6155, KANJI_LEVEL4, // 慕 + 0x620A, KANJI_LEVEL4, // 戊 + 0x66AE, KANJI_LEVEL4, // 暮 + 0x6BCD, KANJI_LEVEL4, // 母 + 0x7C3F, KANJI_LEVEL4, // ç°¿ + 0x83E9, KANJI_LEVEL4, // 菩 + 0x5023, KANJI_LEVEL4, // 倣 + 0x4FF8, KANJI_LEVEL4, // 俞 + 0x5305, KANJI_LEVEL4, // 包 + 0x5446, KANJI_LEVEL4, // 呆 + 0x5831, KANJI_LEVEL4, // å ± + 0x5949, KANJI_LEVEL4, // 奉 + 0x5B9D, KANJI_LEVEL4, // 宝 + 0x5CF0, KANJI_LEVEL4, // å³° + 0x5CEF, KANJI_LEVEL4, // 峯 + 0x5D29, KANJI_LEVEL4, // 厩 + 0x5E96, KANJI_LEVEL4, // 庖 + 0x62B1, KANJI_LEVEL4, // 抱 + 0x6367, KANJI_LEVEL4, // 捧 + 0x653E, KANJI_LEVEL4, // 攟 + 0x65B9, KANJI_LEVEL4, // 方 + 0x670B, KANJI_LEVEL4, // 朋 + 0x6CD5, KANJI_LEVEL4, // 法 + 0x6CE1, KANJI_LEVEL4, // 泡 + 0x70F9, KANJI_LEVEL4, // 烹 + 0x7832, KANJI_LEVEL4, // ç ² + 0x7E2B, KANJI_LEVEL4, // çž« + 0x80DE, KANJI_LEVEL4, // 胞 + 0x82B3, KANJI_LEVEL4, // 芳 + 0x840C, KANJI_LEVEL4, // 萌 + 0x84EC, KANJI_LEVEL4, // 蓬 + 0x8702, KANJI_LEVEL4, // 蜂 + 0x8912, KANJI_LEVEL4, // 耒 + 0x8A2A, KANJI_LEVEL4, // 蚪 + 0x8C4A, KANJI_LEVEL4, // 豊 + 0x90A6, KANJI_LEVEL4, // 邩 + 0x92D2, KANJI_LEVEL4, // 鋒 + 0x98FD, KANJI_LEVEL4, // 飜 + 0x9CF3, KANJI_LEVEL4, // é³³ + 0x9D6C, KANJI_LEVEL4, // 鵬 + 0x4E4F, KANJI_LEVEL4, // 乏 + 0x4EA1, KANJI_LEVEL4, // 亡 + 0x508D, KANJI_LEVEL4, // 傍 + 0x5256, KANJI_LEVEL4, // 剖 + 0x574A, KANJI_LEVEL4, // 坊 + 0x59A8, KANJI_LEVEL4, // 劚 + 0x5E3D, KANJI_LEVEL4, // åžœ + 0x5FD8, KANJI_LEVEL4, // 忘 + 0x5FD9, KANJI_LEVEL4, // 忙 + 0x623F, KANJI_LEVEL4, // 房 + 0x66B4, KANJI_LEVEL4, // 暎 + 0x671B, KANJI_LEVEL4, // 望 + 0x67D0, KANJI_LEVEL4, // 某 + 0x68D2, KANJI_LEVEL4, // 棒 + 0x5192, KANJI_LEVEL4, // 冒 + 0x7D21, KANJI_LEVEL4, // 玡 + 0x80AA, KANJI_LEVEL4, // 肪 + 0x81A8, KANJI_LEVEL4, // 膚 + 0x8B00, KANJI_LEVEL4, // 謀 + 0x8C8C, KANJI_LEVEL4, // 貌 + 0x8CBF, KANJI_LEVEL4, // 貿 + 0x927E, KANJI_LEVEL4, // 鉟 + 0x9632, KANJI_LEVEL4, // 防 + 0x5420, KANJI_LEVEL4, // 吠 + 0x982C, KANJI_LEVEL4, // é ¬ + 0x5317, KANJI_LEVEL4, // 北 + 0x50D5, KANJI_LEVEL4, // 僕 + 0x535C, KANJI_LEVEL4, // 卜 + 0x58A8, KANJI_LEVEL4, // 墚 + 0x64B2, KANJI_LEVEL4, // 撲 + 0x6734, KANJI_LEVEL4, // 朎 + 0x7267, KANJI_LEVEL4, // 牧 + 0x7766, KANJI_LEVEL4, // 睊 + 0x7A46, KANJI_LEVEL4, // 穆 + 0x91E6, KANJI_LEVEL4, // 釩 + 0x52C3, KANJI_LEVEL4, // 勃 + 0x6CA1, KANJI_LEVEL4, // 没 + 0x6B86, KANJI_LEVEL4, // 殆 + 0x5800, KANJI_LEVEL4, // 堀 + 0x5E4C, KANJI_LEVEL4, // 幌 + 0x5954, KANJI_LEVEL4, // 奔 + 0x672C, KANJI_LEVEL4, // 本 + 0x7FFB, KANJI_LEVEL4, // ç¿» + 0x51E1, KANJI_LEVEL4, // 凡 + 0x76C6, KANJI_LEVEL4, // 盆 + 0x6469, KANJI_LEVEL4, // 摩 + 0x78E8, KANJI_LEVEL4, // 磚 + 0x9B54, KANJI_LEVEL4, // 魔 + 0x9EBB, KANJI_LEVEL4, // 麻 + 0x57CB, KANJI_LEVEL4, // 埋 + 0x59B9, KANJI_LEVEL4, // 効 + 0x6627, KANJI_LEVEL4, // 昧 + 0x679A, KANJI_LEVEL4, // 枚 + 0x6BCE, KANJI_LEVEL4, // 毎 + 0x54E9, KANJI_LEVEL4, // 哩 + 0x69D9, KANJI_LEVEL4, // 槙 + 0x5E55, KANJI_LEVEL4, // 幕 + 0x819C, KANJI_LEVEL4, // 膜 + 0x6795, KANJI_LEVEL4, // 枕 + 0x9BAA, KANJI_LEVEL4, // 鮪 + 0x67FE, KANJI_LEVEL4, // 柟 + 0x9C52, KANJI_LEVEL4, // 鱒 + 0x685D, KANJI_LEVEL4, // 桝 + 0x4EA6, KANJI_LEVEL4, // 亊 + 0x4FE3, KANJI_LEVEL4, // ä¿£ + 0x53C8, KANJI_LEVEL4, // 又 + 0x62B9, KANJI_LEVEL4, // 抹 + 0x672B, KANJI_LEVEL4, // 末 + 0x6CAB, KANJI_LEVEL4, // 沫 + 0x8FC4, KANJI_LEVEL4, // 迄 + 0x4FAD, KANJI_LEVEL4, // 䟭 + 0x7E6D, KANJI_LEVEL4, // ç¹­ + 0x9EBF, KANJI_LEVEL4, // 麿 + 0x4E07, KANJI_LEVEL4, // 侇 + 0x6162, KANJI_LEVEL4, // 慢 + 0x6E80, KANJI_LEVEL4, // 満 + 0x6F2B, KANJI_LEVEL4, // 挫 + 0x8513, KANJI_LEVEL4, // 蔓 + 0x5473, KANJI_LEVEL4, // 味 + 0x672A, KANJI_LEVEL4, // 未 + 0x9B45, KANJI_LEVEL4, // 魅 + 0x5DF3, KANJI_LEVEL4, // å·³ + 0x7B95, KANJI_LEVEL4, // 箕 + 0x5CAC, KANJI_LEVEL4, // 岬 + 0x5BC6, KANJI_LEVEL4, // 密 + 0x871C, KANJI_LEVEL4, // 蜜 + 0x6E4A, KANJI_LEVEL4, // 湊 + 0x84D1, KANJI_LEVEL4, // 蓑 + 0x7A14, KANJI_LEVEL4, // 織 + 0x8108, KANJI_LEVEL4, // 脈 + 0x5999, KANJI_LEVEL4, // 劙 + 0x7C8D, KANJI_LEVEL4, // 粍 + 0x6C11, KANJI_LEVEL4, // 民 + 0x7720, KANJI_LEVEL4, // 眠 + 0x52D9, KANJI_LEVEL4, // 務 + 0x5922, KANJI_LEVEL4, // 倢 + 0x7121, KANJI_LEVEL4, // 無 + 0x725F, KANJI_LEVEL4, // 牟 + 0x77DB, KANJI_LEVEL4, // 矛 + 0x9727, KANJI_LEVEL4, // 霧 + 0x9D61, KANJI_LEVEL4, // 鵡 + 0x690B, KANJI_LEVEL4, // 怋 + 0x5A7F, KANJI_LEVEL4, // å©¿ + 0x5A18, KANJI_LEVEL4, // 嚘 + 0x51A5, KANJI_LEVEL4, // 冥 + 0x540D, KANJI_LEVEL4, // 名 + 0x547D, KANJI_LEVEL4, // 呜 + 0x660E, KANJI_LEVEL4, // 明 + 0x76DF, KANJI_LEVEL4, // 盟 + 0x8FF7, KANJI_LEVEL4, // è¿· + 0x9298, KANJI_LEVEL4, // 銘 + 0x9CF4, KANJI_LEVEL4, // 鳎 + 0x59EA, KANJI_LEVEL4, // 姪 + 0x725D, KANJI_LEVEL4, // 牝 + 0x6EC5, KANJI_LEVEL4, // 滅 + 0x514D, KANJI_LEVEL4, // 免 + 0x68C9, KANJI_LEVEL4, // 棉 + 0x7DBF, KANJI_LEVEL4, // ç¶¿ + 0x7DEC, KANJI_LEVEL4, // ç·¬ + 0x9762, KANJI_LEVEL4, // 面 + 0x9EBA, KANJI_LEVEL4, // 麺 + 0x6478, KANJI_LEVEL4, // 摞 + 0x6A21, KANJI_LEVEL4, // æš¡ + 0x8302, KANJI_LEVEL4, // 茂 + 0x5984, KANJI_LEVEL4, // 劄 + 0x5B5F, KANJI_LEVEL4, // 孟 + 0x6BDB, KANJI_LEVEL4, // 毛 + 0x731B, KANJI_LEVEL4, // 猛 + 0x76F2, KANJI_LEVEL4, // 盲 + 0x7DB2, KANJI_LEVEL4, // ç¶² + 0x8017, KANJI_LEVEL4, // 耗 + 0x8499, KANJI_LEVEL4, // 蒙 + 0x5132, KANJI_LEVEL4, // 儲 + 0x6728, KANJI_LEVEL4, // 朚 + 0x9ED9, KANJI_LEVEL4, // 黙 + 0x76EE, KANJI_LEVEL4, // 目 + 0x6762, KANJI_LEVEL4, // 杢 + 0x52FF, KANJI_LEVEL4, // 勿 + 0x9905, KANJI_LEVEL4, // 逅 + 0x5C24, KANJI_LEVEL4, // å°€ + 0x623B, KANJI_LEVEL4, // 戻 + 0x7C7E, KANJI_LEVEL4, // 籟 + 0x8CB0, KANJI_LEVEL4, // è²° + 0x554F, KANJI_LEVEL4, // 問 + 0x60B6, KANJI_LEVEL4, // 悶 + 0x7D0B, KANJI_LEVEL4, // 箋 + 0x9580, KANJI_LEVEL4, // 門 + 0x5301, KANJI_LEVEL4, // 匁 + 0x4E5F, KANJI_LEVEL4, // 也 + 0x51B6, KANJI_LEVEL4, // 冶 + 0x591C, KANJI_LEVEL4, // 倜 + 0x723A, KANJI_LEVEL4, // 爺 + 0x8036, KANJI_LEVEL4, // 耶 + 0x91CE, KANJI_LEVEL4, // 野 + 0x5F25, KANJI_LEVEL4, // 匥 + 0x77E2, KANJI_LEVEL4, // 矢 + 0x5384, KANJI_LEVEL4, // 厄 + 0x5F79, KANJI_LEVEL4, // 圹 + 0x7D04, KANJI_LEVEL4, // 箄 + 0x85AC, KANJI_LEVEL4, // 薬 + 0x8A33, KANJI_LEVEL4, // èš³ + 0x8E8D, KANJI_LEVEL4, // 躍 + 0x9756, KANJI_LEVEL4, // 靖 + 0x67F3, KANJI_LEVEL4, // 柳 + 0x85AE, KANJI_LEVEL4, // 薮 + 0x9453, KANJI_LEVEL4, // 鑓 + 0x6109, KANJI_LEVEL4, // 愉 + 0x6108, KANJI_LEVEL4, // 愈 + 0x6CB9, KANJI_LEVEL4, // æ²¹ + 0x7652, KANJI_LEVEL4, // 癒 + 0x8AED, KANJI_LEVEL4, // è«­ + 0x8F38, KANJI_LEVEL4, // 茞 + 0x552F, KANJI_LEVEL4, // 唯 + 0x4F51, KANJI_LEVEL4, // 䜑 + 0x512A, KANJI_LEVEL4, // 優 + 0x52C7, KANJI_LEVEL4, // 勇 + 0x53CB, KANJI_LEVEL4, // 友 + 0x5BA5, KANJI_LEVEL4, // 宥 + 0x5E7D, KANJI_LEVEL4, // 幜 + 0x60A0, KANJI_LEVEL4, // 悠 + 0x6182, KANJI_LEVEL4, // 憂 + 0x63D6, KANJI_LEVEL4, // 揖 + 0x6709, KANJI_LEVEL4, // 有 + 0x67DA, KANJI_LEVEL4, // 柚 + 0x6E67, KANJI_LEVEL4, // æ¹§ + 0x6D8C, KANJI_LEVEL4, // 涌 + 0x7336, KANJI_LEVEL4, // 猶 + 0x7337, KANJI_LEVEL4, // 猷 + 0x7531, KANJI_LEVEL4, // 由 + 0x7950, KANJI_LEVEL4, // 祐 + 0x88D5, KANJI_LEVEL4, // 裕 + 0x8A98, KANJI_LEVEL4, // 誘 + 0x904A, KANJI_LEVEL4, // 遊 + 0x9091, KANJI_LEVEL4, // 邑 + 0x90F5, KANJI_LEVEL4, // 郵 + 0x96C4, KANJI_LEVEL4, // 雄 + 0x878D, KANJI_LEVEL4, // 融 + 0x5915, KANJI_LEVEL4, // 倕 + 0x4E88, KANJI_LEVEL4, // 予 + 0x4F59, KANJI_LEVEL4, // 䜙 + 0x4E0E, KANJI_LEVEL4, // 侎 + 0x8A89, KANJI_LEVEL4, // 誉 + 0x8F3F, KANJI_LEVEL4, // 茿 + 0x9810, KANJI_LEVEL4, // 預 + 0x50AD, KANJI_LEVEL4, // 傭 + 0x5E7C, KANJI_LEVEL4, // 幌 + 0x5996, KANJI_LEVEL4, // 劖 + 0x5BB9, KANJI_LEVEL4, // 容 + 0x5EB8, KANJI_LEVEL4, // 庞 + 0x63DA, KANJI_LEVEL4, // 揚 + 0x63FA, KANJI_LEVEL4, // 揺 + 0x64C1, KANJI_LEVEL4, // 擁 + 0x66DC, KANJI_LEVEL4, // 曜 + 0x694A, KANJI_LEVEL4, // 楊 + 0x69D8, KANJI_LEVEL4, // 様 + 0x6D0B, KANJI_LEVEL4, // 掋 + 0x6EB6, KANJI_LEVEL4, // 溶 + 0x7194, KANJI_LEVEL4, // 熔 + 0x7528, KANJI_LEVEL4, // 甹 + 0x7AAF, KANJI_LEVEL4, // 窯 + 0x7F8A, KANJI_LEVEL4, // 矊 + 0x8000, KANJI_LEVEL4, // 耀 + 0x8449, KANJI_LEVEL4, // 葉 + 0x84C9, KANJI_LEVEL4, // 蓉 + 0x8981, KANJI_LEVEL4, // 芁 + 0x8B21, KANJI_LEVEL4, // 謡 + 0x8E0A, KANJI_LEVEL4, // 螊 + 0x9065, KANJI_LEVEL4, // 遥 + 0x967D, KANJI_LEVEL4, // 陜 + 0x990A, KANJI_LEVEL4, // 逊 + 0x617E, KANJI_LEVEL4, // æ…Ÿ + 0x6291, KANJI_LEVEL4, // 抑 + 0x6B32, KANJI_LEVEL4, // 欲 + 0x6C83, KANJI_LEVEL4, // 沃 + 0x6D74, KANJI_LEVEL4, // 济 + 0x7FCC, KANJI_LEVEL4, // 翌 + 0x7FFC, KANJI_LEVEL4, // 翌 + 0x6DC0, KANJI_LEVEL4, // 淀 + 0x7F85, KANJI_LEVEL4, // 矅 + 0x87BA, KANJI_LEVEL4, // 螺 + 0x88F8, KANJI_LEVEL4, // 裞 + 0x6765, KANJI_LEVEL4, // 来 + 0x83B1, KANJI_LEVEL4, // 莱 + 0x983C, KANJI_LEVEL4, // é Œ + 0x96F7, KANJI_LEVEL4, // 雷 + 0x6D1B, KANJI_LEVEL4, // 掛 + 0x7D61, KANJI_LEVEL4, // 絡 + 0x843D, KANJI_LEVEL4, // 萜 + 0x916A, KANJI_LEVEL4, // 酪 + 0x4E71, KANJI_LEVEL4, // ä¹± + 0x5375, KANJI_LEVEL4, // 卵 + 0x5D50, KANJI_LEVEL4, // 嵐 + 0x6B04, KANJI_LEVEL4, // 欄 + 0x6FEB, KANJI_LEVEL4, // æ¿« + 0x85CD, KANJI_LEVEL4, // 藍 + 0x862D, KANJI_LEVEL4, // 蘭 + 0x89A7, KANJI_LEVEL4, // 芧 + 0x5229, KANJI_LEVEL4, // 利 + 0x540F, KANJI_LEVEL4, // 吏 + 0x5C65, KANJI_LEVEL4, // å±¥ + 0x674E, KANJI_LEVEL4, // 李 + 0x68A8, KANJI_LEVEL4, // 梚 + 0x7406, KANJI_LEVEL4, // 理 + 0x7483, KANJI_LEVEL4, // 璃 + 0x75E2, KANJI_LEVEL4, // 痢 + 0x88CF, KANJI_LEVEL4, // 裏 + 0x88E1, KANJI_LEVEL4, // 裡 + 0x91CC, KANJI_LEVEL4, // 里 + 0x96E2, KANJI_LEVEL4, // 離 + 0x9678, KANJI_LEVEL4, // 陾 + 0x5F8B, KANJI_LEVEL4, // 埋 + 0x7387, KANJI_LEVEL4, // 率 + 0x7ACB, KANJI_LEVEL4, // 立 + 0x844E, KANJI_LEVEL4, // 葎 + 0x63A0, KANJI_LEVEL4, // 掠 + 0x7565, KANJI_LEVEL4, // 略 + 0x5289, KANJI_LEVEL4, // 劉 + 0x6D41, KANJI_LEVEL4, // 流 + 0x6E9C, KANJI_LEVEL4, // 溜 + 0x7409, KANJI_LEVEL4, // 琉 + 0x7559, KANJI_LEVEL4, // 留 + 0x786B, KANJI_LEVEL4, // ç¡« + 0x7C92, KANJI_LEVEL4, // 粒 + 0x9686, KANJI_LEVEL4, // 隆 + 0x7ADC, KANJI_LEVEL4, // 竜 + 0x9F8D, KANJI_LEVEL4, // 韍 + 0x4FB6, KANJI_LEVEL4, // 䟶 + 0x616E, KANJI_LEVEL4, // 慮 + 0x65C5, KANJI_LEVEL4, // 旅 + 0x865C, KANJI_LEVEL4, // 虜 + 0x4E86, KANJI_LEVEL4, // 了 + 0x4EAE, KANJI_LEVEL4, // 亮 + 0x50DA, KANJI_LEVEL4, // 僚 + 0x4E21, KANJI_LEVEL4, // äž¡ + 0x51CC, KANJI_LEVEL4, // 凌 + 0x5BEE, KANJI_LEVEL4, // 寮 + 0x6599, KANJI_LEVEL4, // 料 + 0x6881, KANJI_LEVEL4, // 梁 + 0x6DBC, KANJI_LEVEL4, // æ¶Œ + 0x731F, KANJI_LEVEL4, // 猟 + 0x7642, KANJI_LEVEL4, // 療 + 0x77AD, KANJI_LEVEL4, // 瞭 + 0x7A1C, KANJI_LEVEL4, // 繜 + 0x7CE7, KANJI_LEVEL4, // ç³§ + 0x826F, KANJI_LEVEL4, // 良 + 0x8AD2, KANJI_LEVEL4, // 諒 + 0x907C, KANJI_LEVEL4, // 遌 + 0x91CF, KANJI_LEVEL4, // 量 + 0x9675, KANJI_LEVEL4, // 陵 + 0x9818, KANJI_LEVEL4, // 領 + 0x529B, KANJI_LEVEL4, // 力 + 0x7DD1, KANJI_LEVEL4, // 緑 + 0x502B, KANJI_LEVEL4, // 倫 + 0x5398, KANJI_LEVEL4, // 厘 + 0x6797, KANJI_LEVEL4, // 林 + 0x6DCB, KANJI_LEVEL4, // 淋 + 0x71D0, KANJI_LEVEL4, // 燐 + 0x7433, KANJI_LEVEL4, // 琳 + 0x81E8, KANJI_LEVEL4, // 臚 + 0x8F2A, KANJI_LEVEL4, // 茪 + 0x96A3, KANJI_LEVEL4, // 隣 + 0x9C57, KANJI_LEVEL4, // 鱗 + 0x9E9F, KANJI_LEVEL4, // 麟 + 0x7460, KANJI_LEVEL4, // 瑠 + 0x5841, KANJI_LEVEL4, // 塁 + 0x6D99, KANJI_LEVEL4, // 涙 + 0x7D2F, KANJI_LEVEL4, // 环 + 0x985E, KANJI_LEVEL4, // 類 + 0x4EE4, KANJI_LEVEL4, // 什 + 0x4F36, KANJI_LEVEL4, // 䌶 + 0x4F8B, KANJI_LEVEL4, // 䟋 + 0x51B7, KANJI_LEVEL4, // 冷 + 0x52B1, KANJI_LEVEL4, // 励 + 0x5DBA, KANJI_LEVEL4, // 嶺 + 0x601C, KANJI_LEVEL4, // 怜 + 0x73B2, KANJI_LEVEL4, // 玲 + 0x793C, KANJI_LEVEL4, // 瀌 + 0x82D3, KANJI_LEVEL4, // 苓 + 0x9234, KANJI_LEVEL4, // 鈎 + 0x96B7, KANJI_LEVEL4, // 隷 + 0x96F6, KANJI_LEVEL4, // 零 + 0x970A, KANJI_LEVEL4, // 霊 + 0x9E97, KANJI_LEVEL4, // 麗 + 0x9F62, KANJI_LEVEL4, // 霢 + 0x66A6, KANJI_LEVEL4, // 暊 + 0x6B74, KANJI_LEVEL4, // æ­Ž + 0x5217, KANJI_LEVEL4, // 列 + 0x52A3, KANJI_LEVEL4, // 劣 + 0x70C8, KANJI_LEVEL4, // 烈 + 0x88C2, KANJI_LEVEL4, // 裂 + 0x5EC9, KANJI_LEVEL4, // 廉 + 0x604B, KANJI_LEVEL4, // 恋 + 0x6190, KANJI_LEVEL4, // 憐 + 0x6F23, KANJI_LEVEL4, // 挣 + 0x7149, KANJI_LEVEL4, // 煉 + 0x7C3E, KANJI_LEVEL4, // ç°Ÿ + 0x7DF4, KANJI_LEVEL4, // ç·Ž + 0x806F, KANJI_LEVEL4, // 聯 + 0x84EE, KANJI_LEVEL4, // 蓮 + 0x9023, KANJI_LEVEL4, // 連 + 0x932C, KANJI_LEVEL4, // 錬 + 0x5442, KANJI_LEVEL4, // 呂 + 0x9B6F, KANJI_LEVEL4, // é­¯ + 0x6AD3, KANJI_LEVEL4, // 櫓 + 0x7089, KANJI_LEVEL4, // 炉 + 0x8CC2, KANJI_LEVEL4, // 賂 + 0x8DEF, KANJI_LEVEL4, // è·¯ + 0x9732, KANJI_LEVEL4, // 露 + 0x52B4, KANJI_LEVEL4, // 劎 + 0x5A41, KANJI_LEVEL4, // 婁 + 0x5ECA, KANJI_LEVEL4, // 廊 + 0x5F04, KANJI_LEVEL4, // 匄 + 0x6717, KANJI_LEVEL4, // 朗 + 0x697C, KANJI_LEVEL4, // 楌 + 0x6994, KANJI_LEVEL4, // 抔 + 0x6D6A, KANJI_LEVEL4, // 浪 + 0x6F0F, KANJI_LEVEL4, // 挏 + 0x7262, KANJI_LEVEL4, // 牢 + 0x72FC, KANJI_LEVEL4, // 狌 + 0x7BED, KANJI_LEVEL4, // 篭 + 0x8001, KANJI_LEVEL4, // 老 + 0x807E, KANJI_LEVEL4, // 聟 + 0x874B, KANJI_LEVEL4, // 蝋 + 0x90CE, KANJI_LEVEL4, // 郎 + 0x516D, KANJI_LEVEL4, // 六 + 0x9E93, KANJI_LEVEL4, // 麓 + 0x7984, KANJI_LEVEL4, // 穄 + 0x808B, KANJI_LEVEL4, // 肋 + 0x9332, KANJI_LEVEL4, // 録 + 0x8AD6, KANJI_LEVEL4, // 論 + 0x502D, KANJI_LEVEL4, // 倭 + 0x548C, KANJI_LEVEL4, // 和 + 0x8A71, KANJI_LEVEL4, // 話 + 0x6B6A, KANJI_LEVEL4, // æ­ª + 0x8CC4, KANJI_LEVEL4, // 賄 + 0x8107, KANJI_LEVEL4, // 脇 + 0x60D1, KANJI_LEVEL4, // 惑 + 0x67A0, KANJI_LEVEL4, // 枠 + 0x9DF2, KANJI_LEVEL4, // é·² + 0x4E99, KANJI_LEVEL4, // 亙 + 0x4E98, KANJI_LEVEL4, // 亘 + 0x9C10, KANJI_LEVEL4, // 鰐 + 0x8A6B, KANJI_LEVEL4, // è©« + 0x85C1, KANJI_LEVEL4, // 藁 + 0x8568, KANJI_LEVEL4, // 蕚 + 0x6900, KANJI_LEVEL4, // 怀 + 0x6E7E, KANJI_LEVEL4, // 湟 + 0x7897, KANJI_LEVEL4, // 碗 + 0x8155, KANJI_LEVEL4, // 腕 + 0xD842, KANJI_LEVEL4, // ᅵ + 0xDF9F, KANJI_LEVEL4, // ᅵ + 0x5B41, KANJI_LEVEL4, // 孁 + 0x5B56, KANJI_LEVEL4, // 孖 + 0x5B7D, KANJI_LEVEL4, // å­œ + 0x5B93, KANJI_LEVEL4, // 宓 + 0x5BD8, KANJI_LEVEL4, // 寘 + 0x5BEC, KANJI_LEVEL4, // 寬 + 0x5C12, KANJI_LEVEL4, // 尒 + 0x5C1E, KANJI_LEVEL4, // 尞 + 0x5C23, KANJI_LEVEL4, // å°£ + 0x5C2B, KANJI_LEVEL4, // å°« + 0x378D, KANJI_LEVEL4, // 㞍 + 0x5C62, KANJI_LEVEL4, // å±¢ + 0xFA3B, KANJI_LEVEL4, // ïš» + 0xFA3C, KANJI_LEVEL4, //  + 0xD845, KANJI_LEVEL4, // ᅵ + 0xDEB4, KANJI_LEVEL4, // ᅵ + 0x5C7A, KANJI_LEVEL4, // 屺 + 0x5C8F, KANJI_LEVEL4, // 岏 + 0x5C9F, KANJI_LEVEL4, // 岟 + 0x5CA3, KANJI_LEVEL4, // å²£ + 0x5CAA, KANJI_LEVEL4, // 岪 + 0x5CBA, KANJI_LEVEL4, // 岺 + 0x5CCB, KANJI_LEVEL4, // 峋 + 0x5CD0, KANJI_LEVEL4, // 峐 + 0x5CD2, KANJI_LEVEL4, // 峒 + 0x5CF4, KANJI_LEVEL4, // 峎 + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDE34, KANJI_LEVEL4, // ᅵ + 0x37E2, KANJI_LEVEL4, // 㟢 + 0x5D0D, KANJI_LEVEL4, // 厍 + 0x5D27, KANJI_LEVEL4, // 厧 + 0xFA11, KANJI_LEVEL4, // ïš‘ + 0x5D46, KANJI_LEVEL4, // 嵆 + 0x5D47, KANJI_LEVEL4, // 嵇 + 0x5D53, KANJI_LEVEL4, // 嵓 + 0x5D4A, KANJI_LEVEL4, // 嵊 + 0x5D6D, KANJI_LEVEL4, // åµ­ + 0x5D81, KANJI_LEVEL4, // 嶁 + 0x5DA0, KANJI_LEVEL4, // å¶  + 0x5DA4, KANJI_LEVEL4, // å¶€ + 0x5DA7, KANJI_LEVEL4, // å¶§ + 0x5DB8, KANJI_LEVEL4, // å¶ž + 0x5DCB, KANJI_LEVEL4, // 巋 + 0x541E, KANJI_LEVEL4, // 吞 + 0x5F0C, KANJI_LEVEL4, // 匌 + 0x4E10, KANJI_LEVEL4, // 䞐 + 0x4E15, KANJI_LEVEL4, // 侕 + 0x4E2A, KANJI_LEVEL4, // 䞪 + 0x4E31, KANJI_LEVEL4, // äž± + 0x4E36, KANJI_LEVEL4, // äž¶ + 0x4E3C, KANJI_LEVEL4, // 䞌 + 0x4E3F, KANJI_LEVEL4, // äž¿ + 0x4E42, KANJI_LEVEL4, // 乂 + 0x4E56, KANJI_LEVEL4, // 乖 + 0x4E58, KANJI_LEVEL4, // 乘 + 0x4E82, KANJI_LEVEL4, // 亂 + 0x4E85, KANJI_LEVEL4, // 亅 + 0x8C6B, KANJI_LEVEL4, // 豫 + 0x4E8A, KANJI_LEVEL4, // 亊 + 0x8212, KANJI_LEVEL4, // 舒 + 0x5F0D, KANJI_LEVEL4, // 匍 + 0x4E8E, KANJI_LEVEL4, // 于 + 0x4E9E, KANJI_LEVEL4, // 亞 + 0x4E9F, KANJI_LEVEL4, // 亟 + 0x4EA0, KANJI_LEVEL4, // 亠 + 0x4EA2, KANJI_LEVEL4, // 亢 + 0x4EB0, KANJI_LEVEL4, // 亰 + 0x4EB3, KANJI_LEVEL4, // 亳 + 0x4EB6, KANJI_LEVEL4, // 亶 + 0x4ECE, KANJI_LEVEL4, // 从 + 0x4ECD, KANJI_LEVEL4, // 仍 + 0x4EC4, KANJI_LEVEL4, // 仄 + 0x4EC6, KANJI_LEVEL4, // 仆 + 0x4EC2, KANJI_LEVEL4, // 仂 + 0x4ED7, KANJI_LEVEL4, // 仗 + 0x4EDE, KANJI_LEVEL4, // 仞 + 0x4EED, KANJI_LEVEL4, // ä»­ + 0x4EDF, KANJI_LEVEL4, // 仟 + 0x4EF7, KANJI_LEVEL4, // ä»· + 0x4F09, KANJI_LEVEL4, // 䌉 + 0x4F5A, KANJI_LEVEL4, // 䜚 + 0x4F30, KANJI_LEVEL4, // 䌰 + 0x4F5B, KANJI_LEVEL4, // 䜛 + 0x4F5D, KANJI_LEVEL4, // 䜝 + 0x4F57, KANJI_LEVEL4, // 䜗 + 0x4F47, KANJI_LEVEL4, // 䜇 + 0x4F76, KANJI_LEVEL4, // 䜶 + 0x4F88, KANJI_LEVEL4, // 䟈 + 0x4F8F, KANJI_LEVEL4, // 䟏 + 0x4F98, KANJI_LEVEL4, // 䟘 + 0x4F7B, KANJI_LEVEL4, // 䜻 + 0x4F69, KANJI_LEVEL4, // 䜩 + 0x4F70, KANJI_LEVEL4, // 䜰 + 0x4F91, KANJI_LEVEL4, // 䟑 + 0x4F6F, KANJI_LEVEL4, // 䜯 + 0x4F86, KANJI_LEVEL4, // 䟆 + 0x4F96, KANJI_LEVEL4, // 䟖 + 0x5118, KANJI_LEVEL4, // 儘 + 0x4FD4, KANJI_LEVEL4, // 俔 + 0x4FDF, KANJI_LEVEL4, // 俟 + 0x4FCE, KANJI_LEVEL4, // 俎 + 0x4FD8, KANJI_LEVEL4, // 俘 + 0x4FDB, KANJI_LEVEL4, // 俛 + 0x4FD1, KANJI_LEVEL4, // 俑 + 0x4FDA, KANJI_LEVEL4, // 俚 + 0x4FD0, KANJI_LEVEL4, // 俐 + 0x4FE4, KANJI_LEVEL4, // ä¿€ + 0x4FE5, KANJI_LEVEL4, // ä¿¥ + 0x501A, KANJI_LEVEL4, // 倚 + 0x5028, KANJI_LEVEL4, // 倚 + 0x5014, KANJI_LEVEL4, // 倔 + 0x502A, KANJI_LEVEL4, // 倪 + 0x5025, KANJI_LEVEL4, // 倥 + 0x5005, KANJI_LEVEL4, // 倅 + 0x4F1C, KANJI_LEVEL4, // 䌜 + 0x4FF6, KANJI_LEVEL4, // ä¿¶ + 0x5021, KANJI_LEVEL4, // 倡 + 0x5029, KANJI_LEVEL4, // 倩 + 0x502C, KANJI_LEVEL4, // 倬 + 0x4FFE, KANJI_LEVEL4, // 俟 + 0x4FEF, KANJI_LEVEL4, // 俯 + 0x5011, KANJI_LEVEL4, // 們 + 0x5006, KANJI_LEVEL4, // 倆 + 0x5043, KANJI_LEVEL4, // 偃 + 0x5047, KANJI_LEVEL4, // 假 + 0x6703, KANJI_LEVEL4, // 會 + 0x5055, KANJI_LEVEL4, // 偕 + 0x5050, KANJI_LEVEL4, // 偐 + 0x5048, KANJI_LEVEL4, // 偈 + 0x505A, KANJI_LEVEL4, // 做 + 0x5056, KANJI_LEVEL4, // 偖 + 0x506C, KANJI_LEVEL4, // 偬 + 0x5078, KANJI_LEVEL4, // 偞 + 0x5080, KANJI_LEVEL4, // 傀 + 0x509A, KANJI_LEVEL4, // 傚 + 0x5085, KANJI_LEVEL4, // 傅 + 0x50B4, KANJI_LEVEL4, // 傎 + 0x50B2, KANJI_LEVEL4, // 傲 + 0x50C9, KANJI_LEVEL4, // 僉 + 0x50CA, KANJI_LEVEL4, // 僊 + 0x50B3, KANJI_LEVEL4, // 傳 + 0x50C2, KANJI_LEVEL4, // 僂 + 0x50D6, KANJI_LEVEL4, // 僖 + 0x50DE, KANJI_LEVEL4, // 僞 + 0x50E5, KANJI_LEVEL4, // 僥 + 0x50ED, KANJI_LEVEL4, // 僭 + 0x50E3, KANJI_LEVEL4, // 僣 + 0x50EE, KANJI_LEVEL4, // 僮 + 0x50F9, KANJI_LEVEL4, // 價 + 0x50F5, KANJI_LEVEL4, // 僵 + 0x5109, KANJI_LEVEL4, // 儉 + 0x5101, KANJI_LEVEL4, // 儁 + 0x5102, KANJI_LEVEL4, // 儂 + 0x5116, KANJI_LEVEL4, // 儖 + 0x5115, KANJI_LEVEL4, // 儕 + 0x5114, KANJI_LEVEL4, // 儔 + 0x511A, KANJI_LEVEL4, // 儚 + 0x5121, KANJI_LEVEL4, // 儡 + 0x513A, KANJI_LEVEL4, // 儺 + 0x5137, KANJI_LEVEL4, // 儷 + 0x513C, KANJI_LEVEL4, // 儌 + 0x513B, KANJI_LEVEL4, // 儻 + 0x513F, KANJI_LEVEL4, // 儿 + 0x5140, KANJI_LEVEL4, // 兀 + 0x5152, KANJI_LEVEL4, // 兒 + 0x514C, KANJI_LEVEL4, // 兌 + 0x5154, KANJI_LEVEL4, // 兔 + 0x5162, KANJI_LEVEL4, // 兢 + 0x7AF8, KANJI_LEVEL4, // 竞 + 0x5169, KANJI_LEVEL4, // 兩 + 0x516A, KANJI_LEVEL4, // 兪 + 0x516E, KANJI_LEVEL4, // 兮 + 0x5180, KANJI_LEVEL4, // 冀 + 0x5182, KANJI_LEVEL4, // 冂 + 0x56D8, KANJI_LEVEL4, // 囘 + 0x518C, KANJI_LEVEL4, // 册 + 0x5189, KANJI_LEVEL4, // 冉 + 0x518F, KANJI_LEVEL4, // 冏 + 0x5191, KANJI_LEVEL4, // 冑 + 0x5193, KANJI_LEVEL4, // 冓 + 0x5195, KANJI_LEVEL4, // 冕 + 0x5196, KANJI_LEVEL4, // 冖 + 0x51A4, KANJI_LEVEL4, // 冀 + 0x51A6, KANJI_LEVEL4, // 冊 + 0x51A2, KANJI_LEVEL4, // 冢 + 0x51A9, KANJI_LEVEL4, // 冩 + 0x51AA, KANJI_LEVEL4, // 冪 + 0x51AB, KANJI_LEVEL4, // 冫 + 0x51B3, KANJI_LEVEL4, // 决 + 0x51B1, KANJI_LEVEL4, // 冱 + 0x51B2, KANJI_LEVEL4, // 冲 + 0x51B0, KANJI_LEVEL4, // 冰 + 0x51B5, KANJI_LEVEL4, // 况 + 0x51BD, KANJI_LEVEL4, // 农 + 0x51C5, KANJI_LEVEL4, // 凅 + 0x51C9, KANJI_LEVEL4, // 凉 + 0x51DB, KANJI_LEVEL4, // 凛 + 0x51E0, KANJI_LEVEL4, // 几 + 0x8655, KANJI_LEVEL4, // 處 + 0x51E9, KANJI_LEVEL4, // 凩 + 0x51ED, KANJI_LEVEL4, // 凭 + 0x51F0, KANJI_LEVEL4, // 凰 + 0x51F5, KANJI_LEVEL4, // 凵 + 0x51FE, KANJI_LEVEL4, // 凟 + 0x5204, KANJI_LEVEL4, // 刄 + 0x520B, KANJI_LEVEL4, // 刋 + 0x5214, KANJI_LEVEL4, // 刔 + 0x520E, KANJI_LEVEL4, // 刎 + 0x5227, KANJI_LEVEL4, // 刧 + 0x522A, KANJI_LEVEL4, // 刪 + 0x522E, KANJI_LEVEL4, // 刮 + 0x5233, KANJI_LEVEL4, // 刳 + 0x5239, KANJI_LEVEL4, // 刹 + 0x524F, KANJI_LEVEL4, // 剏 + 0x5244, KANJI_LEVEL4, // 剄 + 0x524B, KANJI_LEVEL4, // 剋 + 0x524C, KANJI_LEVEL4, // 剌 + 0x525E, KANJI_LEVEL4, // 剞 + 0x5254, KANJI_LEVEL4, // 剔 + 0x526A, KANJI_LEVEL4, // 剪 + 0x5274, KANJI_LEVEL4, // 剎 + 0x5269, KANJI_LEVEL4, // 剩 + 0x5273, KANJI_LEVEL4, // 剳 + 0x527F, KANJI_LEVEL4, // 剿 + 0x527D, KANJI_LEVEL4, // 剜 + 0x528D, KANJI_LEVEL4, // 劍 + 0x5294, KANJI_LEVEL4, // 劔 + 0x5292, KANJI_LEVEL4, // 劒 + 0x5271, KANJI_LEVEL4, // 剱 + 0x5288, KANJI_LEVEL4, // 劈 + 0x5291, KANJI_LEVEL4, // 劑 + 0x8FA8, KANJI_LEVEL4, // 蟚 + 0x8FA7, KANJI_LEVEL4, // 蟧 + 0x52AC, KANJI_LEVEL4, // 劬 + 0x52AD, KANJI_LEVEL4, // 劭 + 0x52BC, KANJI_LEVEL4, // 劌 + 0x52B5, KANJI_LEVEL4, // 劵 + 0x52C1, KANJI_LEVEL4, // 勁 + 0x52CD, KANJI_LEVEL4, // 勍 + 0x52D7, KANJI_LEVEL4, // 勗 + 0x52DE, KANJI_LEVEL4, // 勞 + 0x52E3, KANJI_LEVEL4, // 勣 + 0x52E6, KANJI_LEVEL4, // 勊 + 0x98ED, KANJI_LEVEL4, // 飭 + 0x52E0, KANJI_LEVEL4, // 勠 + 0x52F3, KANJI_LEVEL4, // 勳 + 0x52F5, KANJI_LEVEL4, // 勵 + 0x52F8, KANJI_LEVEL4, // 勞 + 0x52F9, KANJI_LEVEL4, // 勹 + 0x5306, KANJI_LEVEL4, // 匆 + 0x5308, KANJI_LEVEL4, // 匈 + 0x7538, KANJI_LEVEL4, // 甾 + 0x530D, KANJI_LEVEL4, // 匍 + 0x5310, KANJI_LEVEL4, // 匐 + 0x530F, KANJI_LEVEL4, // 匏 + 0x5315, KANJI_LEVEL4, // 匕 + 0x531A, KANJI_LEVEL4, // 匚 + 0x5323, KANJI_LEVEL4, // 匣 + 0x532F, KANJI_LEVEL4, // 匯 + 0x5331, KANJI_LEVEL4, // 匱 + 0x5333, KANJI_LEVEL4, // 匳 + 0x5338, KANJI_LEVEL4, // 匞 + 0x5340, KANJI_LEVEL4, // 區 + 0x5346, KANJI_LEVEL4, // 卆 + 0x5345, KANJI_LEVEL4, // 卅 + 0x4E17, KANJI_LEVEL4, // 侗 + 0x5349, KANJI_LEVEL4, // 卉 + 0x534D, KANJI_LEVEL4, // 卍 + 0x51D6, KANJI_LEVEL4, // 凖 + 0x535E, KANJI_LEVEL4, // 卞 + 0x5369, KANJI_LEVEL4, // 卩 + 0x536E, KANJI_LEVEL4, // 卮 + 0x5918, KANJI_LEVEL4, // 倘 + 0x537B, KANJI_LEVEL4, // 卻 + 0x5377, KANJI_LEVEL4, // 卷 + 0x5382, KANJI_LEVEL4, // 厂 + 0x5396, KANJI_LEVEL4, // 厖 + 0x53A0, KANJI_LEVEL4, // 厠 + 0x53A6, KANJI_LEVEL4, // 厊 + 0x53A5, KANJI_LEVEL4, // 厥 + 0x53AE, KANJI_LEVEL4, // 厮 + 0x53B0, KANJI_LEVEL4, // 厰 + 0x53B6, KANJI_LEVEL4, // 厶 + 0x53C3, KANJI_LEVEL4, // 參 + 0x7C12, KANJI_LEVEL4, // 簒 + 0x96D9, KANJI_LEVEL4, // 雙 + 0x53DF, KANJI_LEVEL4, // 叟 + 0x66FC, KANJI_LEVEL4, // 曌 + 0x71EE, KANJI_LEVEL4, // 燮 + 0x53EE, KANJI_LEVEL4, // 叮 + 0x53E8, KANJI_LEVEL4, // 叚 + 0x53ED, KANJI_LEVEL4, // 叭 + 0x53FA, KANJI_LEVEL4, // 叺 + 0x5401, KANJI_LEVEL4, // 吁 + 0x543D, KANJI_LEVEL4, // 吜 + 0x5440, KANJI_LEVEL4, // 呀 + 0x542C, KANJI_LEVEL4, // 听 + 0x542D, KANJI_LEVEL4, // 吭 + 0x543C, KANJI_LEVEL4, // 同 + 0x542E, KANJI_LEVEL4, // 吮 + 0x5436, KANJI_LEVEL4, // 吶 + 0x5429, KANJI_LEVEL4, // 吩 + 0x541D, KANJI_LEVEL4, // 吝 + 0x544E, KANJI_LEVEL4, // 呎 + 0x548F, KANJI_LEVEL4, // 咏 + 0x5475, KANJI_LEVEL4, // 呵 + 0x548E, KANJI_LEVEL4, // 咎 + 0x545F, KANJI_LEVEL4, // 呟 + 0x5471, KANJI_LEVEL4, // 呱 + 0x5477, KANJI_LEVEL4, // 呷 + 0x5470, KANJI_LEVEL4, // 呰 + 0x5492, KANJI_LEVEL4, // 咒 + 0x547B, KANJI_LEVEL4, // 呻 + 0x5480, KANJI_LEVEL4, // 咀 + 0x5476, KANJI_LEVEL4, // 呶 + 0x5484, KANJI_LEVEL4, // 咄 + 0x5490, KANJI_LEVEL4, // 咐 + 0x5486, KANJI_LEVEL4, // 咆 + 0x54C7, KANJI_LEVEL4, // 哇 + 0x54A2, KANJI_LEVEL4, // 咢 + 0x54B8, KANJI_LEVEL4, // å’ž + 0x54A5, KANJI_LEVEL4, // 咥 + 0x54AC, KANJI_LEVEL4, // 咬 + 0x54C4, KANJI_LEVEL4, // 哄 + 0x54C8, KANJI_LEVEL4, // 哈 + 0x54A8, KANJI_LEVEL4, // å’š + 0x54AB, KANJI_LEVEL4, // 咫 + 0x54C2, KANJI_LEVEL4, // 哂 + 0x54A4, KANJI_LEVEL4, // å’€ + 0x54BE, KANJI_LEVEL4, // å’Ÿ + 0x54BC, KANJI_LEVEL4, // å’Œ + 0x54D8, KANJI_LEVEL4, // 哘 + 0x54E5, KANJI_LEVEL4, // 哥 + 0x54E6, KANJI_LEVEL4, // 哊 + 0x550F, KANJI_LEVEL4, // 唏 + 0x5514, KANJI_LEVEL4, // 唔 + 0x54FD, KANJI_LEVEL4, // 哜 + 0x54EE, KANJI_LEVEL4, // 哮 + 0x54ED, KANJI_LEVEL4, // 哭 + 0x54FA, KANJI_LEVEL4, // 哺 + 0x54E2, KANJI_LEVEL4, // 哢 + 0x5539, KANJI_LEVEL4, // 唹 + 0x5540, KANJI_LEVEL4, // 啀 + 0x5563, KANJI_LEVEL4, // 啣 + 0x554C, KANJI_LEVEL4, // 啌 + 0x552E, KANJI_LEVEL4, // 售 + 0x555C, KANJI_LEVEL4, // 啜 + 0x5545, KANJI_LEVEL4, // 啅 + 0x5556, KANJI_LEVEL4, // 啖 + 0x5557, KANJI_LEVEL4, // 啗 + 0x5538, KANJI_LEVEL4, // 唞 + 0x5533, KANJI_LEVEL4, // 唳 + 0x555D, KANJI_LEVEL4, // 啝 + 0x5599, KANJI_LEVEL4, // 喙 + 0x5580, KANJI_LEVEL4, // 喀 + 0x54AF, KANJI_LEVEL4, // 咯 + 0x558A, KANJI_LEVEL4, // 喊 + 0x559F, KANJI_LEVEL4, // 喟 + 0x557B, KANJI_LEVEL4, // 啻 + 0x557E, KANJI_LEVEL4, // 啟 + 0x5598, KANJI_LEVEL4, // 喘 + 0x559E, KANJI_LEVEL4, // 喞 + 0x55AE, KANJI_LEVEL4, // 單 + 0x557C, KANJI_LEVEL4, // 啌 + 0x5583, KANJI_LEVEL4, // 喃 + 0x55A9, KANJI_LEVEL4, // 喩 + 0x5587, KANJI_LEVEL4, // 喇 + 0x55A8, KANJI_LEVEL4, // å–š + 0x55DA, KANJI_LEVEL4, // 嗚 + 0x55C5, KANJI_LEVEL4, // 嗅 + 0x55DF, KANJI_LEVEL4, // 嗟 + 0x55C4, KANJI_LEVEL4, // 嗄 + 0x55DC, KANJI_LEVEL4, // 嗜 + 0x55E4, KANJI_LEVEL4, // å—€ + 0x55D4, KANJI_LEVEL4, // 嗔 + 0x5614, KANJI_LEVEL4, // 嘔 + 0x55F7, KANJI_LEVEL4, // 嗷 + 0x5616, KANJI_LEVEL4, // 嘖 + 0x55FE, KANJI_LEVEL4, // å—Ÿ + 0x55FD, KANJI_LEVEL4, // å—œ + 0x561B, KANJI_LEVEL4, // 嘛 + 0x55F9, KANJI_LEVEL4, // 嗹 + 0x564E, KANJI_LEVEL4, // 噎 + 0x5650, KANJI_LEVEL4, // 噐 + 0x71DF, KANJI_LEVEL4, // 營 + 0x5634, KANJI_LEVEL4, // 嘎 + 0x5636, KANJI_LEVEL4, // 嘶 + 0x5632, KANJI_LEVEL4, // 嘲 + 0x5638, KANJI_LEVEL4, // 嘞 + 0x566B, KANJI_LEVEL4, // 噫 + 0x5664, KANJI_LEVEL4, // 噀 + 0x562F, KANJI_LEVEL4, // 嘯 + 0x566C, KANJI_LEVEL4, // 噬 + 0x566A, KANJI_LEVEL4, // 噪 + 0x5686, KANJI_LEVEL4, // 嚆 + 0x5680, KANJI_LEVEL4, // 嚀 + 0x568A, KANJI_LEVEL4, // 嚊 + 0x56A0, KANJI_LEVEL4, // 嚠 + 0x5694, KANJI_LEVEL4, // 嚔 + 0x568F, KANJI_LEVEL4, // 嚏 + 0x56A5, KANJI_LEVEL4, // 嚥 + 0x56AE, KANJI_LEVEL4, // 嚮 + 0x56B6, KANJI_LEVEL4, // 嚶 + 0x56B4, KANJI_LEVEL4, // 嚎 + 0x56C2, KANJI_LEVEL4, // 囂 + 0x56BC, KANJI_LEVEL4, // 嚌 + 0x56C1, KANJI_LEVEL4, // 囁 + 0x56C3, KANJI_LEVEL4, // 囃 + 0x56C0, KANJI_LEVEL4, // 囀 + 0x56C8, KANJI_LEVEL4, // 囈 + 0x56CE, KANJI_LEVEL4, // 囎 + 0x56D1, KANJI_LEVEL4, // 囑 + 0x56D3, KANJI_LEVEL4, // 囓 + 0x56D7, KANJI_LEVEL4, // 囗 + 0x56EE, KANJI_LEVEL4, // 囮 + 0x56F9, KANJI_LEVEL4, // 囹 + 0x5700, KANJI_LEVEL4, // 圀 + 0x56FF, KANJI_LEVEL4, // 囿 + 0x5704, KANJI_LEVEL4, // 圄 + 0x5709, KANJI_LEVEL4, // 圉 + 0x5708, KANJI_LEVEL4, // 圈 + 0x570B, KANJI_LEVEL4, // 國 + 0x570D, KANJI_LEVEL4, // 圍 + 0x5713, KANJI_LEVEL4, // 圓 + 0x5718, KANJI_LEVEL4, // 團 + 0x5716, KANJI_LEVEL4, // 圖 + 0x55C7, KANJI_LEVEL4, // 嗇 + 0x571C, KANJI_LEVEL4, // 圜 + 0x5726, KANJI_LEVEL4, // 圊 + 0x5737, KANJI_LEVEL4, // 圷 + 0x5738, KANJI_LEVEL4, // 圞 + 0x574E, KANJI_LEVEL4, // 坎 + 0x573B, KANJI_LEVEL4, // 圻 + 0x5740, KANJI_LEVEL4, // 址 + 0x574F, KANJI_LEVEL4, // 坏 + 0x5769, KANJI_LEVEL4, // 坩 + 0x57C0, KANJI_LEVEL4, // 埀 + 0x5788, KANJI_LEVEL4, // 垈 + 0x5761, KANJI_LEVEL4, // 坡 + 0x577F, KANJI_LEVEL4, // 坿 + 0x5789, KANJI_LEVEL4, // 垉 + 0x5793, KANJI_LEVEL4, // 垓 + 0x57A0, KANJI_LEVEL4, // 垠 + 0x57B3, KANJI_LEVEL4, // 垳 + 0x57A4, KANJI_LEVEL4, // 垀 + 0x57AA, KANJI_LEVEL4, // 垪 + 0x57B0, KANJI_LEVEL4, // 垰 + 0x57C3, KANJI_LEVEL4, // 埃 + 0x57C6, KANJI_LEVEL4, // 埆 + 0x57D4, KANJI_LEVEL4, // 埔 + 0x57D2, KANJI_LEVEL4, // 埒 + 0x57D3, KANJI_LEVEL4, // 埓 + 0x580A, KANJI_LEVEL4, // 堊 + 0x57D6, KANJI_LEVEL4, // 埖 + 0x57E3, KANJI_LEVEL4, // 埣 + 0x580B, KANJI_LEVEL4, // 堋 + 0x5819, KANJI_LEVEL4, // 堙 + 0x581D, KANJI_LEVEL4, // 堝 + 0x5872, KANJI_LEVEL4, // 塲 + 0x5821, KANJI_LEVEL4, // å ¡ + 0x5862, KANJI_LEVEL4, // å¡¢ + 0x584B, KANJI_LEVEL4, // 塋 + 0x5870, KANJI_LEVEL4, // å¡° + 0x6BC0, KANJI_LEVEL4, // 毀 + 0x5852, KANJI_LEVEL4, // 塒 + 0x583D, KANJI_LEVEL4, // å œ + 0x5879, KANJI_LEVEL4, // 塹 + 0x5885, KANJI_LEVEL4, // 墅 + 0x58B9, KANJI_LEVEL4, // 墹 + 0x589F, KANJI_LEVEL4, // 墟 + 0x58AB, KANJI_LEVEL4, // 墫 + 0x58BA, KANJI_LEVEL4, // 墺 + 0x58DE, KANJI_LEVEL4, // 壞 + 0x58BB, KANJI_LEVEL4, // 墻 + 0x58B8, KANJI_LEVEL4, // 增 + 0x58AE, KANJI_LEVEL4, // 墮 + 0x58C5, KANJI_LEVEL4, // 壅 + 0x58D3, KANJI_LEVEL4, // 壓 + 0x58D1, KANJI_LEVEL4, // 壑 + 0x58D7, KANJI_LEVEL4, // 壗 + 0x58D9, KANJI_LEVEL4, // 壙 + 0x58D8, KANJI_LEVEL4, // 壘 + 0x58E5, KANJI_LEVEL4, // 壥 + 0x58DC, KANJI_LEVEL4, // 壜 + 0x58E4, KANJI_LEVEL4, // 壀 + 0x58DF, KANJI_LEVEL4, // 壟 + 0x58EF, KANJI_LEVEL4, // 壯 + 0x58FA, KANJI_LEVEL4, // 壺 + 0x58F9, KANJI_LEVEL4, // 壹 + 0x58FB, KANJI_LEVEL4, // 壻 + 0x58FC, KANJI_LEVEL4, // 壌 + 0x58FD, KANJI_LEVEL4, // 壜 + 0x5902, KANJI_LEVEL4, // 倂 + 0x590A, KANJI_LEVEL4, // 倊 + 0x5910, KANJI_LEVEL4, // 倐 + 0x591B, KANJI_LEVEL4, // 倛 + 0x68A6, KANJI_LEVEL4, // 梊 + 0x5925, KANJI_LEVEL4, // 倥 + 0x592C, KANJI_LEVEL4, // 倬 + 0x592D, KANJI_LEVEL4, // 倭 + 0x5932, KANJI_LEVEL4, // 倲 + 0x5938, KANJI_LEVEL4, // 倞 + 0x593E, KANJI_LEVEL4, // 借 + 0x7AD2, KANJI_LEVEL4, // 竒 + 0x5955, KANJI_LEVEL4, // 奕 + 0x5950, KANJI_LEVEL4, // 奐 + 0x594E, KANJI_LEVEL4, // 奎 + 0x595A, KANJI_LEVEL4, // 奚 + 0x5958, KANJI_LEVEL4, // 奘 + 0x5962, KANJI_LEVEL4, // 奢 + 0x5960, KANJI_LEVEL4, // 奠 + 0x5967, KANJI_LEVEL4, // 奧 + 0x596C, KANJI_LEVEL4, // 奬 + 0x5969, KANJI_LEVEL4, // 奩 + 0x5978, KANJI_LEVEL4, // 奞 + 0x5981, KANJI_LEVEL4, // 劁 + 0x599D, KANJI_LEVEL4, // 劝 + 0x4F5E, KANJI_LEVEL4, // 䜞 + 0x4FAB, KANJI_LEVEL4, // 䟫 + 0x59A3, KANJI_LEVEL4, // 劣 + 0x59B2, KANJI_LEVEL4, // 劲 + 0x59C6, KANJI_LEVEL4, // 姆 + 0x59E8, KANJI_LEVEL4, // å§š + 0x59DC, KANJI_LEVEL4, // 姜 + 0x598D, KANJI_LEVEL4, // 劍 + 0x59D9, KANJI_LEVEL4, // 姙 + 0x59DA, KANJI_LEVEL4, // 姚 + 0x5A25, KANJI_LEVEL4, // 嚥 + 0x5A1F, KANJI_LEVEL4, // 嚟 + 0x5A11, KANJI_LEVEL4, // åš‘ + 0x5A1C, KANJI_LEVEL4, // åšœ + 0x5A09, KANJI_LEVEL4, // 嚉 + 0x5A1A, KANJI_LEVEL4, // åšš + 0x5A40, KANJI_LEVEL4, // 婀 + 0x5A6C, KANJI_LEVEL4, // 婬 + 0x5A49, KANJI_LEVEL4, // 婉 + 0x5A35, KANJI_LEVEL4, // åšµ + 0x5A36, KANJI_LEVEL4, // åš¶ + 0x5A62, KANJI_LEVEL4, // å©¢ + 0x5A6A, KANJI_LEVEL4, // 婪 + 0x5A9A, KANJI_LEVEL4, // 媚 + 0x5ABC, KANJI_LEVEL4, // 媌 + 0x5ABE, KANJI_LEVEL4, // 媟 + 0x5ACB, KANJI_LEVEL4, // 嫋 + 0x5AC2, KANJI_LEVEL4, // 嫂 + 0x5ABD, KANJI_LEVEL4, // 媜 + 0x5AE3, KANJI_LEVEL4, // å«£ + 0x5AD7, KANJI_LEVEL4, // 嫗 + 0x5AE6, KANJI_LEVEL4, // 嫊 + 0x5AE9, KANJI_LEVEL4, // å«© + 0x5AD6, KANJI_LEVEL4, // 嫖 + 0x5AFA, KANJI_LEVEL4, // 嫺 + 0x5AFB, KANJI_LEVEL4, // å«» + 0x5B0C, KANJI_LEVEL4, // 嬌 + 0x5B0B, KANJI_LEVEL4, // 嬋 + 0x5B16, KANJI_LEVEL4, // 嬖 + 0x5B32, KANJI_LEVEL4, // 嬲 + 0x5AD0, KANJI_LEVEL4, // 嫐 + 0x5B2A, KANJI_LEVEL4, // 嬪 + 0x5B36, KANJI_LEVEL4, // 嬶 + 0x5B3E, KANJI_LEVEL4, // 嬟 + 0x5B43, KANJI_LEVEL4, // 孃 + 0x5B45, KANJI_LEVEL4, // 孅 + 0x5B40, KANJI_LEVEL4, // 孀 + 0x5B51, KANJI_LEVEL4, // 孑 + 0x5B55, KANJI_LEVEL4, // 孕 + 0x5B5A, KANJI_LEVEL4, // 孚 + 0x5B5B, KANJI_LEVEL4, // 孛 + 0x5B65, KANJI_LEVEL4, // å­¥ + 0x5B69, KANJI_LEVEL4, // å­© + 0x5B70, KANJI_LEVEL4, // å­° + 0x5B73, KANJI_LEVEL4, // å­³ + 0x5B75, KANJI_LEVEL4, // å­µ + 0x5B78, KANJI_LEVEL4, // å­ž + 0x6588, KANJI_LEVEL4, // 斈 + 0x5B7A, KANJI_LEVEL4, // å­º + 0x5B80, KANJI_LEVEL4, // 宀 + 0x5B83, KANJI_LEVEL4, // 它 + 0x5BA6, KANJI_LEVEL4, // 宊 + 0x5BB8, KANJI_LEVEL4, // 实 + 0x5BC3, KANJI_LEVEL4, // 寃 + 0x5BC7, KANJI_LEVEL4, // 寇 + 0x5BC9, KANJI_LEVEL4, // 寉 + 0x5BD4, KANJI_LEVEL4, // 寔 + 0x5BD0, KANJI_LEVEL4, // 寐 + 0x5BE4, KANJI_LEVEL4, // 寀 + 0x5BE6, KANJI_LEVEL4, // 寊 + 0x5BE2, KANJI_LEVEL4, // 寢 + 0x5BDE, KANJI_LEVEL4, // 寞 + 0x5BE5, KANJI_LEVEL4, // 寥 + 0x5BEB, KANJI_LEVEL4, // 寫 + 0x5BF0, KANJI_LEVEL4, // 寰 + 0x5BF6, KANJI_LEVEL4, // 寶 + 0x5BF3, KANJI_LEVEL4, // 寳 + 0x5C05, KANJI_LEVEL4, // 尅 + 0x5C07, KANJI_LEVEL4, // 將 + 0x5C08, KANJI_LEVEL4, // 專 + 0x5C0D, KANJI_LEVEL4, // 對 + 0x5C13, KANJI_LEVEL4, // 尓 + 0x5C20, KANJI_LEVEL4, // å°  + 0x5C22, KANJI_LEVEL4, // å°¢ + 0x5C28, KANJI_LEVEL4, // å°š + 0x5C38, KANJI_LEVEL4, // å°ž + 0x5C39, KANJI_LEVEL4, // å°¹ + 0x5C41, KANJI_LEVEL4, // 屁 + 0x5C46, KANJI_LEVEL4, // 屆 + 0x5C4E, KANJI_LEVEL4, // 屎 + 0x5C53, KANJI_LEVEL4, // 屓 + 0x5C50, KANJI_LEVEL4, // 屐 + 0x5C4F, KANJI_LEVEL4, // 屏 + 0x5B71, KANJI_LEVEL4, // å­± + 0x5C6C, KANJI_LEVEL4, // 屬 + 0x5C6E, KANJI_LEVEL4, // å±® + 0x4E62, KANJI_LEVEL4, // ä¹¢ + 0x5C76, KANJI_LEVEL4, // å±¶ + 0x5C79, KANJI_LEVEL4, // å±¹ + 0x5C8C, KANJI_LEVEL4, // 岌 + 0x5C91, KANJI_LEVEL4, // 岑 + 0x5C94, KANJI_LEVEL4, // 岔 + 0x599B, KANJI_LEVEL4, // 力 + 0x5CAB, KANJI_LEVEL4, // 岫 + 0x5CBB, KANJI_LEVEL4, // å²» + 0x5CB6, KANJI_LEVEL4, // å²¶ + 0x5CBC, KANJI_LEVEL4, // 岌 + 0x5CB7, KANJI_LEVEL4, // å²· + 0x5CC5, KANJI_LEVEL4, // 峅 + 0x5CBE, KANJI_LEVEL4, // 岟 + 0x5CC7, KANJI_LEVEL4, // 峇 + 0x5CD9, KANJI_LEVEL4, // 峙 + 0x5CE9, KANJI_LEVEL4, // 峩 + 0x5CFD, KANJI_LEVEL4, // 峜 + 0x5CFA, KANJI_LEVEL4, // 峺 + 0x5CED, KANJI_LEVEL4, // å³­ + 0x5D8C, KANJI_LEVEL4, // 嶌 + 0x5CEA, KANJI_LEVEL4, // 峪 + 0x5D0B, KANJI_LEVEL4, // 压 + 0x5D15, KANJI_LEVEL4, // 厕 + 0x5D17, KANJI_LEVEL4, // 厗 + 0x5D5C, KANJI_LEVEL4, // 嵜 + 0x5D1F, KANJI_LEVEL4, // 原 + 0x5D1B, KANJI_LEVEL4, // 厛 + 0x5D11, KANJI_LEVEL4, // 厑 + 0x5D14, KANJI_LEVEL4, // 厔 + 0x5D22, KANJI_LEVEL4, // 厢 + 0x5D1A, KANJI_LEVEL4, // 厚 + 0x5D19, KANJI_LEVEL4, // 厙 + 0x5D18, KANJI_LEVEL4, // 厘 + 0x5D4C, KANJI_LEVEL4, // 嵌 + 0x5D52, KANJI_LEVEL4, // 嵒 + 0x5D4E, KANJI_LEVEL4, // 嵎 + 0x5D4B, KANJI_LEVEL4, // 嵋 + 0x5D6C, KANJI_LEVEL4, // 嵬 + 0x5D73, KANJI_LEVEL4, // åµ³ + 0x5D76, KANJI_LEVEL4, // åµ¶ + 0x5D87, KANJI_LEVEL4, // 嶇 + 0x5D84, KANJI_LEVEL4, // 嶄 + 0x5D82, KANJI_LEVEL4, // 嶂 + 0x5DA2, KANJI_LEVEL4, // å¶¢ + 0x5D9D, KANJI_LEVEL4, // 嶝 + 0x5DAC, KANJI_LEVEL4, // 嶬 + 0x5DAE, KANJI_LEVEL4, // å¶® + 0x5DBD, KANJI_LEVEL4, // å¶œ + 0x5D90, KANJI_LEVEL4, // 嶐 + 0x5DB7, KANJI_LEVEL4, // å¶· + 0x5DBC, KANJI_LEVEL4, // å¶Œ + 0x5DC9, KANJI_LEVEL4, // 巉 + 0x5DCD, KANJI_LEVEL4, // 巍 + 0x5DD3, KANJI_LEVEL4, // 巓 + 0x5DD2, KANJI_LEVEL4, // 巒 + 0x5DD6, KANJI_LEVEL4, // 巖 + 0x5DDB, KANJI_LEVEL4, // 巛 + 0x5DEB, KANJI_LEVEL4, // å·« + 0x5DF2, KANJI_LEVEL4, // å·² + 0x5DF5, KANJI_LEVEL4, // å·µ + 0x5E0B, KANJI_LEVEL4, // åž‹ + 0x5E1A, KANJI_LEVEL4, // åžš + 0x5E19, KANJI_LEVEL4, // åž™ + 0x5E11, KANJI_LEVEL4, // åž‘ + 0x5E1B, KANJI_LEVEL4, // åž› + 0x5E36, KANJI_LEVEL4, // åž¶ + 0x5E37, KANJI_LEVEL4, // åž· + 0x5E44, KANJI_LEVEL4, // 幄 + 0x5E43, KANJI_LEVEL4, // 幃 + 0x5E40, KANJI_LEVEL4, // 幀 + 0x5E4E, KANJI_LEVEL4, // 幎 + 0x5E57, KANJI_LEVEL4, // 幗 + 0x5E54, KANJI_LEVEL4, // 幔 + 0x5E5F, KANJI_LEVEL4, // 幟 + 0x5E62, KANJI_LEVEL4, // å¹¢ + 0x5E64, KANJI_LEVEL4, // å¹€ + 0x5E47, KANJI_LEVEL4, // 幇 + 0x5E75, KANJI_LEVEL4, // å¹µ + 0x5E76, KANJI_LEVEL4, // å¹¶ + 0x5E7A, KANJI_LEVEL4, // 幺 + 0x9EBC, KANJI_LEVEL4, // 麌 + 0x5E7F, KANJI_LEVEL4, // 广 + 0x5EA0, KANJI_LEVEL4, // 庠 + 0x5EC1, KANJI_LEVEL4, // 廁 + 0x5EC2, KANJI_LEVEL4, // 廂 + 0x5EC8, KANJI_LEVEL4, // 廈 + 0x5ED0, KANJI_LEVEL4, // 廐 + 0x5ECF, KANJI_LEVEL4, // 廏 + 0x5ED6, KANJI_LEVEL4, // 廖 + 0x5EE3, KANJI_LEVEL4, // 廣 + 0x5EDD, KANJI_LEVEL4, // 廝 + 0x5EDA, KANJI_LEVEL4, // 廚 + 0x5EDB, KANJI_LEVEL4, // 廛 + 0x5EE2, KANJI_LEVEL4, // 廢 + 0x5EE1, KANJI_LEVEL4, // 廡 + 0x5EE8, KANJI_LEVEL4, // 廚 + 0x5EE9, KANJI_LEVEL4, // 廩 + 0x5EEC, KANJI_LEVEL4, // 廬 + 0x5EF1, KANJI_LEVEL4, // å»± + 0x5EF3, KANJI_LEVEL4, // 廳 + 0x5EF0, KANJI_LEVEL4, // å»° + 0x5EF4, KANJI_LEVEL4, // 廎 + 0x5EF8, KANJI_LEVEL4, // 廞 + 0x5EFE, KANJI_LEVEL4, // 廟 + 0x5F03, KANJI_LEVEL4, // 匃 + 0x5F09, KANJI_LEVEL4, // 匉 + 0x5F5D, KANJI_LEVEL4, // 圝 + 0x5F5C, KANJI_LEVEL4, // 圜 + 0x5F0B, KANJI_LEVEL4, // 匋 + 0x5F11, KANJI_LEVEL4, // 匑 + 0x5F16, KANJI_LEVEL4, // 化 + 0x5F29, KANJI_LEVEL4, // 匩 + 0x5F2D, KANJI_LEVEL4, // 匭 + 0x5F38, KANJI_LEVEL4, // 匞 + 0x5F41, KANJI_LEVEL4, // 圁 + 0x5F48, KANJI_LEVEL4, // 圈 + 0x5F4C, KANJI_LEVEL4, // 圌 + 0x5F4E, KANJI_LEVEL4, // 圎 + 0x5F2F, KANJI_LEVEL4, // 匯 + 0x5F51, KANJI_LEVEL4, // 圑 + 0x5F56, KANJI_LEVEL4, // 圖 + 0x5F57, KANJI_LEVEL4, // 圗 + 0x5F59, KANJI_LEVEL4, // 圙 + 0x5F61, KANJI_LEVEL4, // 圡 + 0x5F6D, KANJI_LEVEL4, // 圭 + 0x5F73, KANJI_LEVEL4, // 圳 + 0x5F77, KANJI_LEVEL4, // 圷 + 0x5F83, KANJI_LEVEL4, // 埃 + 0x5F82, KANJI_LEVEL4, // 埂 + 0x5F7F, KANJI_LEVEL4, // 圿 + 0x5F8A, KANJI_LEVEL4, // 埊 + 0x5F88, KANJI_LEVEL4, // 埈 + 0x5F91, KANJI_LEVEL4, // 埑 + 0x5F87, KANJI_LEVEL4, // 埇 + 0x5F9E, KANJI_LEVEL4, // 埞 + 0x5F99, KANJI_LEVEL4, // 埙 + 0x5F98, KANJI_LEVEL4, // 埘 + 0x5FA0, KANJI_LEVEL4, // 埠 + 0x5FA8, KANJI_LEVEL4, // 埚 + 0x5FAD, KANJI_LEVEL4, // 埭 + 0x5FBC, KANJI_LEVEL4, // 埌 + 0x5FD6, KANJI_LEVEL4, // 忖 + 0x5FFB, KANJI_LEVEL4, // å¿» + 0x5FE4, KANJI_LEVEL4, // å¿€ + 0x5FF8, KANJI_LEVEL4, // 忞 + 0x5FF1, KANJI_LEVEL4, // 忱 + 0x5FDD, KANJI_LEVEL4, // 忝 + 0x60B3, KANJI_LEVEL4, // 悳 + 0x5FFF, KANJI_LEVEL4, // å¿¿ + 0x6021, KANJI_LEVEL4, // 怡 + 0x6060, KANJI_LEVEL4, // 恠 + 0x6019, KANJI_LEVEL4, // 怙 + 0x6010, KANJI_LEVEL4, // 怐 + 0x6029, KANJI_LEVEL4, // 怩 + 0x600E, KANJI_LEVEL4, // 怎 + 0x6031, KANJI_LEVEL4, // 怱 + 0x601B, KANJI_LEVEL4, // 怛 + 0x6015, KANJI_LEVEL4, // 怕 + 0x602B, KANJI_LEVEL4, // 怫 + 0x6026, KANJI_LEVEL4, // 怊 + 0x600F, KANJI_LEVEL4, // 怏 + 0x603A, KANJI_LEVEL4, // 怺 + 0x605A, KANJI_LEVEL4, // 恚 + 0x6041, KANJI_LEVEL4, // 恁 + 0x606A, KANJI_LEVEL4, // 恪 + 0x6077, KANJI_LEVEL4, // 恷 + 0x605F, KANJI_LEVEL4, // 恟 + 0x604A, KANJI_LEVEL4, // 恊 + 0x6046, KANJI_LEVEL4, // 恆 + 0x604D, KANJI_LEVEL4, // 恍 + 0x6063, KANJI_LEVEL4, // 恣 + 0x6043, KANJI_LEVEL4, // 恃 + 0x6064, KANJI_LEVEL4, // 恀 + 0x6042, KANJI_LEVEL4, // 恂 + 0x606C, KANJI_LEVEL4, // 恬 + 0x606B, KANJI_LEVEL4, // 恫 + 0x6059, KANJI_LEVEL4, // 恙 + 0x6081, KANJI_LEVEL4, // 悁 + 0x608D, KANJI_LEVEL4, // 悍 + 0x60E7, KANJI_LEVEL4, // 惧 + 0x6083, KANJI_LEVEL4, // 悃 + 0x609A, KANJI_LEVEL4, // 悚 + 0x6084, KANJI_LEVEL4, // 悄 + 0x609B, KANJI_LEVEL4, // 悛 + 0x6096, KANJI_LEVEL4, // 悖 + 0x6097, KANJI_LEVEL4, // 悗 + 0x6092, KANJI_LEVEL4, // 悒 + 0x60A7, KANJI_LEVEL4, // 悧 + 0x608B, KANJI_LEVEL4, // 悋 + 0x60E1, KANJI_LEVEL4, // 惡 + 0x60B8, KANJI_LEVEL4, // 悞 + 0x60E0, KANJI_LEVEL4, // 惠 + 0x60D3, KANJI_LEVEL4, // 惓 + 0x60B4, KANJI_LEVEL4, // 悎 + 0x5FF0, KANJI_LEVEL4, // å¿° + 0x60BD, KANJI_LEVEL4, // 悜 + 0x60C6, KANJI_LEVEL4, // 惆 + 0x60B5, KANJI_LEVEL4, // 悵 + 0x60D8, KANJI_LEVEL4, // 惘 + 0x614D, KANJI_LEVEL4, // 慍 + 0x6115, KANJI_LEVEL4, // 愕 + 0x6106, KANJI_LEVEL4, // 愆 + 0x60F6, KANJI_LEVEL4, // 惶 + 0x60F7, KANJI_LEVEL4, // 惷 + 0x6100, KANJI_LEVEL4, // 愀 + 0x60F4, KANJI_LEVEL4, // 惎 + 0x60FA, KANJI_LEVEL4, // 惺 + 0x6103, KANJI_LEVEL4, // 愃 + 0x6121, KANJI_LEVEL4, // 愡 + 0x60FB, KANJI_LEVEL4, // 惻 + 0x60F1, KANJI_LEVEL4, // 惱 + 0x610D, KANJI_LEVEL4, // 愍 + 0x610E, KANJI_LEVEL4, // 愎 + 0x6147, KANJI_LEVEL4, // 慇 + 0x613E, KANJI_LEVEL4, // 感 + 0x6128, KANJI_LEVEL4, // 愚 + 0x6127, KANJI_LEVEL4, // 愧 + 0x614A, KANJI_LEVEL4, // 慊 + 0x613F, KANJI_LEVEL4, // 愿 + 0x613C, KANJI_LEVEL4, // 愌 + 0x612C, KANJI_LEVEL4, // 愬 + 0x6134, KANJI_LEVEL4, // 愎 + 0x613D, KANJI_LEVEL4, // 愜 + 0x6142, KANJI_LEVEL4, // 慂 + 0x6144, KANJI_LEVEL4, // 慄 + 0x6173, KANJI_LEVEL4, // 慳 + 0x6177, KANJI_LEVEL4, // 慷 + 0x6158, KANJI_LEVEL4, // 慘 + 0x6159, KANJI_LEVEL4, // 慙 + 0x615A, KANJI_LEVEL4, // 慚 + 0x616B, KANJI_LEVEL4, // 慫 + 0x6174, KANJI_LEVEL4, // æ…Ž + 0x616F, KANJI_LEVEL4, // 慯 + 0x6165, KANJI_LEVEL4, // 慥 + 0x6171, KANJI_LEVEL4, // 慱 + 0x615F, KANJI_LEVEL4, // 慟 + 0x615D, KANJI_LEVEL4, // 慝 + 0x6153, KANJI_LEVEL4, // 慓 + 0x6175, KANJI_LEVEL4, // 慵 + 0x6199, KANJI_LEVEL4, // 憙 + 0x6196, KANJI_LEVEL4, // 憖 + 0x6187, KANJI_LEVEL4, // 憇 + 0x61AC, KANJI_LEVEL4, // 憬 + 0x6194, KANJI_LEVEL4, // 憔 + 0x619A, KANJI_LEVEL4, // 憚 + 0x618A, KANJI_LEVEL4, // 憊 + 0x6191, KANJI_LEVEL4, // 憑 + 0x61AB, KANJI_LEVEL4, // 憫 + 0x61AE, KANJI_LEVEL4, // 憮 + 0x61CC, KANJI_LEVEL4, // 懌 + 0x61CA, KANJI_LEVEL4, // 懊 + 0x61C9, KANJI_LEVEL4, // 應 + 0x61F7, KANJI_LEVEL4, // 懷 + 0x61C8, KANJI_LEVEL4, // 懈 + 0x61C3, KANJI_LEVEL4, // 懃 + 0x61C6, KANJI_LEVEL4, // 懆 + 0x61BA, KANJI_LEVEL4, // 憺 + 0x61CB, KANJI_LEVEL4, // 懋 + 0x7F79, KANJI_LEVEL4, // 眹 + 0x61CD, KANJI_LEVEL4, // 懍 + 0x61E6, KANJI_LEVEL4, // 懊 + 0x61E3, KANJI_LEVEL4, // 懣 + 0x61F6, KANJI_LEVEL4, // 懶 + 0x61FA, KANJI_LEVEL4, // 懺 + 0x61F4, KANJI_LEVEL4, // 懎 + 0x61FF, KANJI_LEVEL4, // 懿 + 0x61FD, KANJI_LEVEL4, // 懜 + 0x61FC, KANJI_LEVEL4, // 懌 + 0x61FE, KANJI_LEVEL4, // 懟 + 0x6200, KANJI_LEVEL4, // 戀 + 0x6208, KANJI_LEVEL4, // 戈 + 0x6209, KANJI_LEVEL4, // 戉 + 0x620D, KANJI_LEVEL4, // 戍 + 0x620C, KANJI_LEVEL4, // 戌 + 0x6214, KANJI_LEVEL4, // 戔 + 0x621B, KANJI_LEVEL4, // 戛 + 0x621E, KANJI_LEVEL4, // 戞 + 0x6221, KANJI_LEVEL4, // 戡 + 0x622A, KANJI_LEVEL4, // 截 + 0x622E, KANJI_LEVEL4, // 戮 + 0x6230, KANJI_LEVEL4, // 戰 + 0x6232, KANJI_LEVEL4, // 戲 + 0x6233, KANJI_LEVEL4, // 戳 + 0x6241, KANJI_LEVEL4, // 扁 + 0x624E, KANJI_LEVEL4, // 扎 + 0x625E, KANJI_LEVEL4, // 扞 + 0x6263, KANJI_LEVEL4, // 扣 + 0x625B, KANJI_LEVEL4, // 扛 + 0x6260, KANJI_LEVEL4, // 扠 + 0x6268, KANJI_LEVEL4, // 扚 + 0x627C, KANJI_LEVEL4, // 扌 + 0x6282, KANJI_LEVEL4, // 抂 + 0x6289, KANJI_LEVEL4, // 抉 + 0x627E, KANJI_LEVEL4, // 扟 + 0x6292, KANJI_LEVEL4, // 抒 + 0x6293, KANJI_LEVEL4, // 抓 + 0x6296, KANJI_LEVEL4, // 抖 + 0x62D4, KANJI_LEVEL4, // 拔 + 0x6283, KANJI_LEVEL4, // 抃 + 0x6294, KANJI_LEVEL4, // 抔 + 0x62D7, KANJI_LEVEL4, // 拗 + 0x62D1, KANJI_LEVEL4, // 拑 + 0x62BB, KANJI_LEVEL4, // 抻 + 0x62CF, KANJI_LEVEL4, // 拏 + 0x62FF, KANJI_LEVEL4, // 拿 + 0x62C6, KANJI_LEVEL4, // 拆 + 0x64D4, KANJI_LEVEL4, // 擔 + 0x62C8, KANJI_LEVEL4, // 拈 + 0x62DC, KANJI_LEVEL4, // 拜 + 0x62CC, KANJI_LEVEL4, // 拌 + 0x62CA, KANJI_LEVEL4, // 拊 + 0x62C2, KANJI_LEVEL4, // 拂 + 0x62C7, KANJI_LEVEL4, // 拇 + 0x629B, KANJI_LEVEL4, // 抛 + 0x62C9, KANJI_LEVEL4, // 拉 + 0x630C, KANJI_LEVEL4, // 挌 + 0x62EE, KANJI_LEVEL4, // 拮 + 0x62F1, KANJI_LEVEL4, // 拱 + 0x6327, KANJI_LEVEL4, // 挧 + 0x6302, KANJI_LEVEL4, // 挂 + 0x6308, KANJI_LEVEL4, // 挈 + 0x62EF, KANJI_LEVEL4, // 拯 + 0x62F5, KANJI_LEVEL4, // 拵 + 0x6350, KANJI_LEVEL4, // 捐 + 0x633E, KANJI_LEVEL4, // 挟 + 0x634D, KANJI_LEVEL4, // 捍 + 0x641C, KANJI_LEVEL4, // 搜 + 0x634F, KANJI_LEVEL4, // 捏 + 0x6396, KANJI_LEVEL4, // 掖 + 0x638E, KANJI_LEVEL4, // 掎 + 0x6380, KANJI_LEVEL4, // 掀 + 0x63AB, KANJI_LEVEL4, // 掫 + 0x6376, KANJI_LEVEL4, // 捶 + 0x63A3, KANJI_LEVEL4, // 掣 + 0x638F, KANJI_LEVEL4, // 掏 + 0x6389, KANJI_LEVEL4, // 掉 + 0x639F, KANJI_LEVEL4, // 掟 + 0x63B5, KANJI_LEVEL4, // 掵 + 0x636B, KANJI_LEVEL4, // 捫 + 0x6369, KANJI_LEVEL4, // 捩 + 0x63BE, KANJI_LEVEL4, // 掟 + 0x63E9, KANJI_LEVEL4, // 揩 + 0x63C0, KANJI_LEVEL4, // 揀 + 0x63C6, KANJI_LEVEL4, // 揆 + 0x63E3, KANJI_LEVEL4, // 揣 + 0x63C9, KANJI_LEVEL4, // 揉 + 0x63D2, KANJI_LEVEL4, // 插 + 0x63F6, KANJI_LEVEL4, // 揶 + 0x63C4, KANJI_LEVEL4, // 揄 + 0x6416, KANJI_LEVEL4, // 搖 + 0x6434, KANJI_LEVEL4, // 搎 + 0x6406, KANJI_LEVEL4, // 搆 + 0x6413, KANJI_LEVEL4, // 搓 + 0x6426, KANJI_LEVEL4, // 搊 + 0x6436, KANJI_LEVEL4, // 搶 + 0x651D, KANJI_LEVEL4, // 攝 + 0x6417, KANJI_LEVEL4, // 搗 + 0x6428, KANJI_LEVEL4, // 搚 + 0x640F, KANJI_LEVEL4, // 搏 + 0x6467, KANJI_LEVEL4, // 摧 + 0x646F, KANJI_LEVEL4, // 摯 + 0x6476, KANJI_LEVEL4, // 摶 + 0x644E, KANJI_LEVEL4, // 摎 + 0x652A, KANJI_LEVEL4, // 攪 + 0x6495, KANJI_LEVEL4, // 撕 + 0x6493, KANJI_LEVEL4, // 撓 + 0x64A5, KANJI_LEVEL4, // 撥 + 0x64A9, KANJI_LEVEL4, // 撩 + 0x6488, KANJI_LEVEL4, // 撈 + 0x64BC, KANJI_LEVEL4, // æ’Œ + 0x64DA, KANJI_LEVEL4, // 據 + 0x64D2, KANJI_LEVEL4, // 擒 + 0x64C5, KANJI_LEVEL4, // 擅 + 0x64C7, KANJI_LEVEL4, // 擇 + 0x64BB, KANJI_LEVEL4, // 撻 + 0x64D8, KANJI_LEVEL4, // 擘 + 0x64C2, KANJI_LEVEL4, // 擂 + 0x64F1, KANJI_LEVEL4, // 擱 + 0x64E7, KANJI_LEVEL4, // 擧 + 0x8209, KANJI_LEVEL4, // 舉 + 0x64E0, KANJI_LEVEL4, // 擠 + 0x64E1, KANJI_LEVEL4, // 擡 + 0x62AC, KANJI_LEVEL4, // 抬 + 0x64E3, KANJI_LEVEL4, // 擣 + 0x64EF, KANJI_LEVEL4, // 擯 + 0x652C, KANJI_LEVEL4, // 攬 + 0x64F6, KANJI_LEVEL4, // 擶 + 0x64F4, KANJI_LEVEL4, // 擎 + 0x64F2, KANJI_LEVEL4, // 擲 + 0x64FA, KANJI_LEVEL4, // 擺 + 0x6500, KANJI_LEVEL4, // 攀 + 0x64FD, KANJI_LEVEL4, // 擜 + 0x6518, KANJI_LEVEL4, // 攘 + 0x651C, KANJI_LEVEL4, // 攜 + 0x6505, KANJI_LEVEL4, // 攅 + 0x6524, KANJI_LEVEL4, // 攀 + 0x6523, KANJI_LEVEL4, // 攣 + 0x652B, KANJI_LEVEL4, // 攫 + 0x6534, KANJI_LEVEL4, // 攎 + 0x6535, KANJI_LEVEL4, // 攵 + 0x6537, KANJI_LEVEL4, // 攷 + 0x6536, KANJI_LEVEL4, // 收 + 0x6538, KANJI_LEVEL4, // 攞 + 0x754B, KANJI_LEVEL4, // 畋 + 0x6548, KANJI_LEVEL4, // 效 + 0x6556, KANJI_LEVEL4, // 敖 + 0x6555, KANJI_LEVEL4, // 敕 + 0x654D, KANJI_LEVEL4, // 敍 + 0x6558, KANJI_LEVEL4, // 敘 + 0x655E, KANJI_LEVEL4, // 敞 + 0x655D, KANJI_LEVEL4, // 敝 + 0x6572, KANJI_LEVEL4, // 敲 + 0x6578, KANJI_LEVEL4, // 敞 + 0x6582, KANJI_LEVEL4, // 斂 + 0x6583, KANJI_LEVEL4, // 斃 + 0x8B8A, KANJI_LEVEL4, // 變 + 0x659B, KANJI_LEVEL4, // 斛 + 0x659F, KANJI_LEVEL4, // 斟 + 0x65AB, KANJI_LEVEL4, // 斫 + 0x65B7, KANJI_LEVEL4, // 斷 + 0x65C3, KANJI_LEVEL4, // 旃 + 0x65C6, KANJI_LEVEL4, // 旆 + 0x65C1, KANJI_LEVEL4, // 旁 + 0x65C4, KANJI_LEVEL4, // 旄 + 0x65CC, KANJI_LEVEL4, // 旌 + 0x65D2, KANJI_LEVEL4, // 旒 + 0x65DB, KANJI_LEVEL4, // 旛 + 0x65D9, KANJI_LEVEL4, // 旙 + 0x65E0, KANJI_LEVEL4, // 无 + 0x65E1, KANJI_LEVEL4, // 旡 + 0x65F1, KANJI_LEVEL4, // 旱 + 0x6772, KANJI_LEVEL4, // 杲 + 0x660A, KANJI_LEVEL4, // 昊 + 0x6603, KANJI_LEVEL4, // 昃 + 0x65FB, KANJI_LEVEL4, // 旻 + 0x6773, KANJI_LEVEL4, // 杳 + 0x6635, KANJI_LEVEL4, // 昵 + 0x6636, KANJI_LEVEL4, // 昶 + 0x6634, KANJI_LEVEL4, // 明 + 0x661C, KANJI_LEVEL4, // 昜 + 0x664F, KANJI_LEVEL4, // 晏 + 0x6644, KANJI_LEVEL4, // 晄 + 0x6649, KANJI_LEVEL4, // 晉 + 0x6641, KANJI_LEVEL4, // 晁 + 0x665E, KANJI_LEVEL4, // 晞 + 0x665D, KANJI_LEVEL4, // 晝 + 0x6664, KANJI_LEVEL4, // 晀 + 0x6667, KANJI_LEVEL4, // 晧 + 0x6668, KANJI_LEVEL4, // 晚 + 0x665F, KANJI_LEVEL4, // 晟 + 0x6662, KANJI_LEVEL4, // 晢 + 0x6670, KANJI_LEVEL4, // 晰 + 0x6683, KANJI_LEVEL4, // 暃 + 0x6688, KANJI_LEVEL4, // 暈 + 0x668E, KANJI_LEVEL4, // 暎 + 0x6689, KANJI_LEVEL4, // 暉 + 0x6684, KANJI_LEVEL4, // 暄 + 0x6698, KANJI_LEVEL4, // 暘 + 0x669D, KANJI_LEVEL4, // 暝 + 0x66C1, KANJI_LEVEL4, // 曁 + 0x66B9, KANJI_LEVEL4, // 暹 + 0x66C9, KANJI_LEVEL4, // 曉 + 0x66BE, KANJI_LEVEL4, // 暟 + 0x66BC, KANJI_LEVEL4, // 暌 + 0x66C4, KANJI_LEVEL4, // 曄 + 0x66B8, KANJI_LEVEL4, // æšž + 0x66D6, KANJI_LEVEL4, // 曖 + 0x66DA, KANJI_LEVEL4, // 曚 + 0x66E0, KANJI_LEVEL4, // 曠 + 0x663F, KANJI_LEVEL4, // 昿 + 0x66E6, KANJI_LEVEL4, // 曊 + 0x66E9, KANJI_LEVEL4, // 曩 + 0x66F0, KANJI_LEVEL4, // 曰 + 0x66F5, KANJI_LEVEL4, // 曵 + 0x66F7, KANJI_LEVEL4, // 曷 + 0x670F, KANJI_LEVEL4, // 朏 + 0x6716, KANJI_LEVEL4, // 朖 + 0x671E, KANJI_LEVEL4, // 朞 + 0x6726, KANJI_LEVEL4, // 朊 + 0x6727, KANJI_LEVEL4, // 朧 + 0x9738, KANJI_LEVEL4, // 霾 + 0x672E, KANJI_LEVEL4, // 朮 + 0x673F, KANJI_LEVEL4, // 朿 + 0x6736, KANJI_LEVEL4, // 朶 + 0x6741, KANJI_LEVEL4, // 杁 + 0x6738, KANJI_LEVEL4, // 朞 + 0x6737, KANJI_LEVEL4, // 朷 + 0x6746, KANJI_LEVEL4, // 杆 + 0x675E, KANJI_LEVEL4, // 杞 + 0x6760, KANJI_LEVEL4, // 杠 + 0x6759, KANJI_LEVEL4, // 杙 + 0x6763, KANJI_LEVEL4, // 杣 + 0x6764, KANJI_LEVEL4, // 杀 + 0x6789, KANJI_LEVEL4, // 枉 + 0x6770, KANJI_LEVEL4, // 杰 + 0x67A9, KANJI_LEVEL4, // 枩 + 0x677C, KANJI_LEVEL4, // 杌 + 0x676A, KANJI_LEVEL4, // 杪 + 0x678C, KANJI_LEVEL4, // 枌 + 0x678B, KANJI_LEVEL4, // 枋 + 0x67A6, KANJI_LEVEL4, // 枊 + 0x67A1, KANJI_LEVEL4, // 枡 + 0x6785, KANJI_LEVEL4, // 枅 + 0x67B7, KANJI_LEVEL4, // 枷 + 0x67EF, KANJI_LEVEL4, // 柯 + 0x67B4, KANJI_LEVEL4, // 枎 + 0x67EC, KANJI_LEVEL4, // 柬 + 0x67B3, KANJI_LEVEL4, // 枳 + 0x67E9, KANJI_LEVEL4, // 柩 + 0x67B8, KANJI_LEVEL4, // æžž + 0x67E4, KANJI_LEVEL4, // 柀 + 0x67DE, KANJI_LEVEL4, // 柞 + 0x67DD, KANJI_LEVEL4, // 柝 + 0x67E2, KANJI_LEVEL4, // 柢 + 0x67EE, KANJI_LEVEL4, // 柮 + 0x67B9, KANJI_LEVEL4, // 枹 + 0x67CE, KANJI_LEVEL4, // 柎 + 0x67C6, KANJI_LEVEL4, // 柆 + 0x67E7, KANJI_LEVEL4, // 柧 + 0x6A9C, KANJI_LEVEL4, // 檜 + 0x681E, KANJI_LEVEL4, // 栞 + 0x6846, KANJI_LEVEL4, // 框 + 0x6829, KANJI_LEVEL4, // æ © + 0x6840, KANJI_LEVEL4, // 桀 + 0x684D, KANJI_LEVEL4, // 桍 + 0x6832, KANJI_LEVEL4, // æ ² + 0x684E, KANJI_LEVEL4, // 桎 + 0x68B3, KANJI_LEVEL4, // 梳 + 0x682B, KANJI_LEVEL4, // æ « + 0x6859, KANJI_LEVEL4, // 桙 + 0x6863, KANJI_LEVEL4, // æ¡£ + 0x6877, KANJI_LEVEL4, // æ¡· + 0x687F, KANJI_LEVEL4, // æ¡¿ + 0x689F, KANJI_LEVEL4, // 梟 + 0x688F, KANJI_LEVEL4, // 梏 + 0x68AD, KANJI_LEVEL4, // 梭 + 0x6894, KANJI_LEVEL4, // 梔 + 0x689D, KANJI_LEVEL4, // 條 + 0x689B, KANJI_LEVEL4, // 梛 + 0x6883, KANJI_LEVEL4, // 梃 + 0x6AAE, KANJI_LEVEL4, // 檮 + 0x68B9, KANJI_LEVEL4, // 梹 + 0x6874, KANJI_LEVEL4, // 桎 + 0x68B5, KANJI_LEVEL4, // 梵 + 0x68A0, KANJI_LEVEL4, // 梠 + 0x68BA, KANJI_LEVEL4, // 梺 + 0x690F, KANJI_LEVEL4, // 怏 + 0x688D, KANJI_LEVEL4, // 梍 + 0x687E, KANJI_LEVEL4, // 桟 + 0x6901, KANJI_LEVEL4, // 态 + 0x68CA, KANJI_LEVEL4, // 棊 + 0x6908, KANJI_LEVEL4, // 怈 + 0x68D8, KANJI_LEVEL4, // 棘 + 0x6922, KANJI_LEVEL4, // 怢 + 0x6926, KANJI_LEVEL4, // 怊 + 0x68E1, KANJI_LEVEL4, // 棡 + 0x690C, KANJI_LEVEL4, // 怌 + 0x68CD, KANJI_LEVEL4, // 棍 + 0x68D4, KANJI_LEVEL4, // 棔 + 0x68E7, KANJI_LEVEL4, // 棧 + 0x68D5, KANJI_LEVEL4, // 棕 + 0x6936, KANJI_LEVEL4, // 怶 + 0x6912, KANJI_LEVEL4, // 怒 + 0x6904, KANJI_LEVEL4, // 怄 + 0x68D7, KANJI_LEVEL4, // 棗 + 0x68E3, KANJI_LEVEL4, // 棣 + 0x6925, KANJI_LEVEL4, // 急 + 0x68F9, KANJI_LEVEL4, // 棹 + 0x68E0, KANJI_LEVEL4, // 棠 + 0x68EF, KANJI_LEVEL4, // 棯 + 0x6928, KANJI_LEVEL4, // 怚 + 0x692A, KANJI_LEVEL4, // 怪 + 0x691A, KANJI_LEVEL4, // 怚 + 0x6923, KANJI_LEVEL4, // 怣 + 0x6921, KANJI_LEVEL4, // 怡 + 0x68C6, KANJI_LEVEL4, // 棆 + 0x6979, KANJI_LEVEL4, // 楹 + 0x6977, KANJI_LEVEL4, // 楷 + 0x695C, KANJI_LEVEL4, // 楜 + 0x6978, KANJI_LEVEL4, // 楞 + 0x696B, KANJI_LEVEL4, // 楫 + 0x6954, KANJI_LEVEL4, // 楔 + 0x697E, KANJI_LEVEL4, // 楟 + 0x696E, KANJI_LEVEL4, // 楮 + 0x6939, KANJI_LEVEL4, // 怹 + 0x6974, KANJI_LEVEL4, // 楎 + 0x693D, KANJI_LEVEL4, // 怜 + 0x6959, KANJI_LEVEL4, // 楙 + 0x6930, KANJI_LEVEL4, // 怰 + 0x6961, KANJI_LEVEL4, // 楡 + 0x695E, KANJI_LEVEL4, // 楞 + 0x695D, KANJI_LEVEL4, // 楝 + 0x6981, KANJI_LEVEL4, // 抁 + 0x696A, KANJI_LEVEL4, // 楪 + 0x69B2, KANJI_LEVEL4, // 抲 + 0x69AE, KANJI_LEVEL4, // 抮 + 0x69D0, KANJI_LEVEL4, // 槐 + 0x69BF, KANJI_LEVEL4, // 抿 + 0x69C1, KANJI_LEVEL4, // 槁 + 0x69D3, KANJI_LEVEL4, // 槓 + 0x69BE, KANJI_LEVEL4, // 抟 + 0x69CE, KANJI_LEVEL4, // 槎 + 0x5BE8, KANJI_LEVEL4, // 寚 + 0x69CA, KANJI_LEVEL4, // 槊 + 0x69DD, KANJI_LEVEL4, // 槝 + 0x69BB, KANJI_LEVEL4, // 抻 + 0x69C3, KANJI_LEVEL4, // 槃 + 0x69A7, KANJI_LEVEL4, // 抧 + 0x6A2E, KANJI_LEVEL4, // æš® + 0x6991, KANJI_LEVEL4, // 抑 + 0x69A0, KANJI_LEVEL4, // 抠 + 0x699C, KANJI_LEVEL4, // 抜 + 0x6995, KANJI_LEVEL4, // 投 + 0x69B4, KANJI_LEVEL4, // 抎 + 0x69DE, KANJI_LEVEL4, // 槞 + 0x69E8, KANJI_LEVEL4, // æ§š + 0x6A02, KANJI_LEVEL4, // æš‚ + 0x6A1B, KANJI_LEVEL4, // æš› + 0x69FF, KANJI_LEVEL4, // æ§¿ + 0x6B0A, KANJI_LEVEL4, // 權 + 0x69F9, KANJI_LEVEL4, // æ§¹ + 0x69F2, KANJI_LEVEL4, // æ§² + 0x69E7, KANJI_LEVEL4, // æ§§ + 0x6A05, KANJI_LEVEL4, // æš… + 0x69B1, KANJI_LEVEL4, // 抱 + 0x6A1E, KANJI_LEVEL4, // 暞 + 0x69ED, KANJI_LEVEL4, // æ§­ + 0x6A14, KANJI_LEVEL4, // æš” + 0x69EB, KANJI_LEVEL4, // æ§« + 0x6A0A, KANJI_LEVEL4, // 暊 + 0x6A12, KANJI_LEVEL4, // æš’ + 0x6AC1, KANJI_LEVEL4, // 櫁 + 0x6A23, KANJI_LEVEL4, // 暣 + 0x6A13, KANJI_LEVEL4, // æš“ + 0x6A44, KANJI_LEVEL4, // 橄 + 0x6A0C, KANJI_LEVEL4, // 暌 + 0x6A72, KANJI_LEVEL4, // 橲 + 0x6A36, KANJI_LEVEL4, // æš¶ + 0x6A78, KANJI_LEVEL4, // 橞 + 0x6A47, KANJI_LEVEL4, // 橇 + 0x6A62, KANJI_LEVEL4, // æ©¢ + 0x6A59, KANJI_LEVEL4, // 橙 + 0x6A66, KANJI_LEVEL4, // 橊 + 0x6A48, KANJI_LEVEL4, // 橈 + 0x6A38, KANJI_LEVEL4, // æšž + 0x6A22, KANJI_LEVEL4, // 暢 + 0x6A90, KANJI_LEVEL4, // 檐 + 0x6A8D, KANJI_LEVEL4, // 檍 + 0x6AA0, KANJI_LEVEL4, // 檠 + 0x6A84, KANJI_LEVEL4, // 檄 + 0x6AA2, KANJI_LEVEL4, // 檢 + 0x6AA3, KANJI_LEVEL4, // 檣 + 0x6A97, KANJI_LEVEL4, // 檗 + 0x8617, KANJI_LEVEL4, // 蘗 + 0x6ABB, KANJI_LEVEL4, // 檻 + 0x6AC3, KANJI_LEVEL4, // 櫃 + 0x6AC2, KANJI_LEVEL4, // 櫂 + 0x6AB8, KANJI_LEVEL4, // 檞 + 0x6AB3, KANJI_LEVEL4, // 檳 + 0x6AAC, KANJI_LEVEL4, // 檬 + 0x6ADE, KANJI_LEVEL4, // 櫞 + 0x6AD1, KANJI_LEVEL4, // 櫑 + 0x6ADF, KANJI_LEVEL4, // 櫟 + 0x6AAA, KANJI_LEVEL4, // 檪 + 0x6ADA, KANJI_LEVEL4, // 櫚 + 0x6AEA, KANJI_LEVEL4, // 櫪 + 0x6AFB, KANJI_LEVEL4, // æ«» + 0x6B05, KANJI_LEVEL4, // 欅 + 0x8616, KANJI_LEVEL4, // 蘖 + 0x6AFA, KANJI_LEVEL4, // 櫺 + 0x6B12, KANJI_LEVEL4, // 欒 + 0x6B16, KANJI_LEVEL4, // 欖 + 0x9B31, KANJI_LEVEL4, // 鬱 + 0x6B1F, KANJI_LEVEL4, // 欟 + 0x6B38, KANJI_LEVEL4, // 欞 + 0x6B37, KANJI_LEVEL4, // 欷 + 0x76DC, KANJI_LEVEL4, // 盜 + 0x6B39, KANJI_LEVEL4, // 欹 + 0x98EE, KANJI_LEVEL4, // 飮 + 0x6B47, KANJI_LEVEL4, // 歇 + 0x6B43, KANJI_LEVEL4, // 歃 + 0x6B49, KANJI_LEVEL4, // 歉 + 0x6B50, KANJI_LEVEL4, // 歐 + 0x6B59, KANJI_LEVEL4, // 歙 + 0x6B54, KANJI_LEVEL4, // 歔 + 0x6B5B, KANJI_LEVEL4, // 歛 + 0x6B5F, KANJI_LEVEL4, // 歟 + 0x6B61, KANJI_LEVEL4, // æ­¡ + 0x6B78, KANJI_LEVEL4, // æ­ž + 0x6B79, KANJI_LEVEL4, // æ­¹ + 0x6B7F, KANJI_LEVEL4, // æ­¿ + 0x6B80, KANJI_LEVEL4, // 殀 + 0x6B84, KANJI_LEVEL4, // 殄 + 0x6B83, KANJI_LEVEL4, // 殃 + 0x6B8D, KANJI_LEVEL4, // 殍 + 0x6B98, KANJI_LEVEL4, // 殘 + 0x6B95, KANJI_LEVEL4, // 殕 + 0x6B9E, KANJI_LEVEL4, // 殞 + 0x6BA4, KANJI_LEVEL4, // 殀 + 0x6BAA, KANJI_LEVEL4, // 殪 + 0x6BAB, KANJI_LEVEL4, // 殫 + 0x6BAF, KANJI_LEVEL4, // 殯 + 0x6BB2, KANJI_LEVEL4, // 殲 + 0x6BB1, KANJI_LEVEL4, // æ®± + 0x6BB3, KANJI_LEVEL4, // 殳 + 0x6BB7, KANJI_LEVEL4, // æ®· + 0x6BBC, KANJI_LEVEL4, // 殌 + 0x6BC6, KANJI_LEVEL4, // 毆 + 0x6BCB, KANJI_LEVEL4, // 毋 + 0x6BD3, KANJI_LEVEL4, // 毓 + 0x6BDF, KANJI_LEVEL4, // 毟 + 0x6BEC, KANJI_LEVEL4, // 毬 + 0x6BEB, KANJI_LEVEL4, // 毫 + 0x6BF3, KANJI_LEVEL4, // 毳 + 0x6BEF, KANJI_LEVEL4, // 毯 + 0x9EBE, KANJI_LEVEL4, // 麟 + 0x6C08, KANJI_LEVEL4, // 氈 + 0x6C13, KANJI_LEVEL4, // 氓 + 0x6C14, KANJI_LEVEL4, // 气 + 0x6C1B, KANJI_LEVEL4, // 氛 + 0x6C24, KANJI_LEVEL4, // æ°€ + 0x6C23, KANJI_LEVEL4, // æ°£ + 0x6C5E, KANJI_LEVEL4, // 汞 + 0x6C55, KANJI_LEVEL4, // 汕 + 0x6C62, KANJI_LEVEL4, // æ±¢ + 0x6C6A, KANJI_LEVEL4, // 汪 + 0x6C82, KANJI_LEVEL4, // 沂 + 0x6C8D, KANJI_LEVEL4, // 沍 + 0x6C9A, KANJI_LEVEL4, // 沚 + 0x6C81, KANJI_LEVEL4, // 沁 + 0x6C9B, KANJI_LEVEL4, // 沛 + 0x6C7E, KANJI_LEVEL4, // 江 + 0x6C68, KANJI_LEVEL4, // 汚 + 0x6C73, KANJI_LEVEL4, // æ±³ + 0x6C92, KANJI_LEVEL4, // 沒 + 0x6C90, KANJI_LEVEL4, // 沐 + 0x6CC4, KANJI_LEVEL4, // 泄 + 0x6CF1, KANJI_LEVEL4, // æ³± + 0x6CD3, KANJI_LEVEL4, // 泓 + 0x6CBD, KANJI_LEVEL4, // 沜 + 0x6CD7, KANJI_LEVEL4, // 泗 + 0x6CC5, KANJI_LEVEL4, // 泅 + 0x6CDD, KANJI_LEVEL4, // 泝 + 0x6CAE, KANJI_LEVEL4, // æ²® + 0x6CB1, KANJI_LEVEL4, // æ²± + 0x6CBE, KANJI_LEVEL4, // 沟 + 0x6CBA, KANJI_LEVEL4, // 沺 + 0x6CDB, KANJI_LEVEL4, // 泛 + 0x6CEF, KANJI_LEVEL4, // 泯 + 0x6CD9, KANJI_LEVEL4, // 泙 + 0x6CEA, KANJI_LEVEL4, // 泪 + 0x6D1F, KANJI_LEVEL4, // 掟 + 0x884D, KANJI_LEVEL4, // 衍 + 0x6D36, KANJI_LEVEL4, // 掶 + 0x6D2B, KANJI_LEVEL4, // 掫 + 0x6D3D, KANJI_LEVEL4, // 掜 + 0x6D38, KANJI_LEVEL4, // 掞 + 0x6D19, KANJI_LEVEL4, // 掙 + 0x6D35, KANJI_LEVEL4, // 掵 + 0x6D33, KANJI_LEVEL4, // 掳 + 0x6D12, KANJI_LEVEL4, // 排 + 0x6D0C, KANJI_LEVEL4, // 掌 + 0x6D63, KANJI_LEVEL4, // æµ£ + 0x6D93, KANJI_LEVEL4, // 涓 + 0x6D64, KANJI_LEVEL4, // æµ€ + 0x6D5A, KANJI_LEVEL4, // 浚 + 0x6D79, KANJI_LEVEL4, // æµ¹ + 0x6D59, KANJI_LEVEL4, // 浙 + 0x6D8E, KANJI_LEVEL4, // 涎 + 0x6D95, KANJI_LEVEL4, // 涕 + 0x6FE4, KANJI_LEVEL4, // æ¿€ + 0x6D85, KANJI_LEVEL4, // 涅 + 0x6DF9, KANJI_LEVEL4, // æ·¹ + 0x6E15, KANJI_LEVEL4, // æž• + 0x6E0A, KANJI_LEVEL4, // 枊 + 0x6DB5, KANJI_LEVEL4, // æ¶µ + 0x6DC7, KANJI_LEVEL4, // 淇 + 0x6DE6, KANJI_LEVEL4, // æ·Š + 0x6DB8, KANJI_LEVEL4, // æ¶ž + 0x6DC6, KANJI_LEVEL4, // 淆 + 0x6DEC, KANJI_LEVEL4, // æ·¬ + 0x6DDE, KANJI_LEVEL4, // 淞 + 0x6DCC, KANJI_LEVEL4, // 淌 + 0x6DE8, KANJI_LEVEL4, // æ·š + 0x6DD2, KANJI_LEVEL4, // 淒 + 0x6DC5, KANJI_LEVEL4, // 淅 + 0x6DFA, KANJI_LEVEL4, // æ·º + 0x6DD9, KANJI_LEVEL4, // 淙 + 0x6DE4, KANJI_LEVEL4, // æ·€ + 0x6DD5, KANJI_LEVEL4, // 淕 + 0x6DEA, KANJI_LEVEL4, // æ·ª + 0x6DEE, KANJI_LEVEL4, // æ·® + 0x6E2D, KANJI_LEVEL4, // æž­ + 0x6E6E, KANJI_LEVEL4, // æ¹® + 0x6E2E, KANJI_LEVEL4, // æž® + 0x6E19, KANJI_LEVEL4, // æž™ + 0x6E72, KANJI_LEVEL4, // æ¹² + 0x6E5F, KANJI_LEVEL4, // 湟 + 0x6E3E, KANJI_LEVEL4, // 枟 + 0x6E23, KANJI_LEVEL4, // 枣 + 0x6E6B, KANJI_LEVEL4, // 湫 + 0x6E2B, KANJI_LEVEL4, // æž« + 0x6E76, KANJI_LEVEL4, // æ¹¶ + 0x6E4D, KANJI_LEVEL4, // 湍 + 0x6E1F, KANJI_LEVEL4, // 枟 + 0x6E43, KANJI_LEVEL4, // 湃 + 0x6E3A, KANJI_LEVEL4, // 枺 + 0x6E4E, KANJI_LEVEL4, // 湎 + 0x6E24, KANJI_LEVEL4, // 枀 + 0x6EFF, KANJI_LEVEL4, // 滿 + 0x6E1D, KANJI_LEVEL4, // 枝 + 0x6E38, KANJI_LEVEL4, // æžž + 0x6E82, KANJI_LEVEL4, // 溂 + 0x6EAA, KANJI_LEVEL4, // 溪 + 0x6E98, KANJI_LEVEL4, // 溘 + 0x6EC9, KANJI_LEVEL4, // 滉 + 0x6EB7, KANJI_LEVEL4, // 溷 + 0x6ED3, KANJI_LEVEL4, // 滓 + 0x6EBD, KANJI_LEVEL4, // 溜 + 0x6EAF, KANJI_LEVEL4, // 溯 + 0x6EC4, KANJI_LEVEL4, // 滄 + 0x6EB2, KANJI_LEVEL4, // 溲 + 0x6ED4, KANJI_LEVEL4, // 滔 + 0x6ED5, KANJI_LEVEL4, // 滕 + 0x6E8F, KANJI_LEVEL4, // 溏 + 0x6EA5, KANJI_LEVEL4, // 溥 + 0x6EC2, KANJI_LEVEL4, // 滂 + 0x6E9F, KANJI_LEVEL4, // 溟 + 0x6F41, KANJI_LEVEL4, // 朁 + 0x6F11, KANJI_LEVEL4, // 挑 + 0x704C, KANJI_LEVEL4, // 灌 + 0x6EEC, KANJI_LEVEL4, // 滬 + 0x6EF8, KANJI_LEVEL4, // 滞 + 0x6EFE, KANJI_LEVEL4, // 滟 + 0x6F3F, KANJI_LEVEL4, // 挿 + 0x6EF2, KANJI_LEVEL4, // 滲 + 0x6F31, KANJI_LEVEL4, // 挱 + 0x6EEF, KANJI_LEVEL4, // 滯 + 0x6F32, KANJI_LEVEL4, // 挲 + 0x6ECC, KANJI_LEVEL4, // 滌 + 0x6F3E, KANJI_LEVEL4, // 挟 + 0x6F13, KANJI_LEVEL4, // 挓 + 0x6EF7, KANJI_LEVEL4, // æ»· + 0x6F86, KANJI_LEVEL4, // 柆 + 0x6F7A, KANJI_LEVEL4, // 机 + 0x6F78, KANJI_LEVEL4, // 朞 + 0x6F81, KANJI_LEVEL4, // 柁 + 0x6F80, KANJI_LEVEL4, // 柀 + 0x6F6F, KANJI_LEVEL4, // 术 + 0x6F5B, KANJI_LEVEL4, // 望 + 0x6FF3, KANJI_LEVEL4, // 濳 + 0x6F6D, KANJI_LEVEL4, // 札 + 0x6F82, KANJI_LEVEL4, // 柂 + 0x6F7C, KANJI_LEVEL4, // 朌 + 0x6F58, KANJI_LEVEL4, // 朘 + 0x6F8E, KANJI_LEVEL4, // 柎 + 0x6F91, KANJI_LEVEL4, // 柑 + 0x6FC2, KANJI_LEVEL4, // 濂 + 0x6F66, KANJI_LEVEL4, // 朊 + 0x6FB3, KANJI_LEVEL4, // 柳 + 0x6FA3, KANJI_LEVEL4, // 柣 + 0x6FA1, KANJI_LEVEL4, // 柡 + 0x6FA4, KANJI_LEVEL4, // 柀 + 0x6FB9, KANJI_LEVEL4, // 柹 + 0x6FC6, KANJI_LEVEL4, // 濆 + 0x6FAA, KANJI_LEVEL4, // 柪 + 0x6FDF, KANJI_LEVEL4, // 濟 + 0x6FD5, KANJI_LEVEL4, // 濕 + 0x6FEC, KANJI_LEVEL4, // 濬 + 0x6FD4, KANJI_LEVEL4, // 濔 + 0x6FD8, KANJI_LEVEL4, // 濘 + 0x6FF1, KANJI_LEVEL4, // 濱 + 0x6FEE, KANJI_LEVEL4, // æ¿® + 0x6FDB, KANJI_LEVEL4, // 濛 + 0x7009, KANJI_LEVEL4, // 瀉 + 0x700B, KANJI_LEVEL4, // 瀋 + 0x6FFA, KANJI_LEVEL4, // 濺 + 0x7011, KANJI_LEVEL4, // 瀑 + 0x7001, KANJI_LEVEL4, // 瀁 + 0x700F, KANJI_LEVEL4, // 瀏 + 0x6FFE, KANJI_LEVEL4, // 濟 + 0x701B, KANJI_LEVEL4, // 瀛 + 0x701A, KANJI_LEVEL4, // 瀚 + 0x6F74, KANJI_LEVEL4, // 朎 + 0x701D, KANJI_LEVEL4, // 瀝 + 0x7018, KANJI_LEVEL4, // 瀘 + 0x701F, KANJI_LEVEL4, // 瀟 + 0x7030, KANJI_LEVEL4, // 瀰 + 0x703E, KANJI_LEVEL4, // 瀟 + 0x7032, KANJI_LEVEL4, // 瀲 + 0x7051, KANJI_LEVEL4, // 灑 + 0x7063, KANJI_LEVEL4, // 灣 + 0x7099, KANJI_LEVEL4, // 炙 + 0x7092, KANJI_LEVEL4, // 炒 + 0x70AF, KANJI_LEVEL4, // 炯 + 0x70F1, KANJI_LEVEL4, // 烱 + 0x70AC, KANJI_LEVEL4, // 炬 + 0x70B8, KANJI_LEVEL4, // 炾 + 0x70B3, KANJI_LEVEL4, // 炳 + 0x70AE, KANJI_LEVEL4, // 炮 + 0x70DF, KANJI_LEVEL4, // 烟 + 0x70CB, KANJI_LEVEL4, // 烋 + 0x70DD, KANJI_LEVEL4, // 烝 + 0x70D9, KANJI_LEVEL4, // 烙 + 0x7109, KANJI_LEVEL4, // 焉 + 0x70FD, KANJI_LEVEL4, // 烜 + 0x711C, KANJI_LEVEL4, // 焜 + 0x7119, KANJI_LEVEL4, // 焙 + 0x7165, KANJI_LEVEL4, // 煥 + 0x7155, KANJI_LEVEL4, // 煕 + 0x7188, KANJI_LEVEL4, // 熈 + 0x7166, KANJI_LEVEL4, // 煩 + 0x7162, KANJI_LEVEL4, // 煢 + 0x714C, KANJI_LEVEL4, // 煌 + 0x7156, KANJI_LEVEL4, // 煖 + 0x716C, KANJI_LEVEL4, // 煬 + 0x718F, KANJI_LEVEL4, // 熏 + 0x71FB, KANJI_LEVEL4, // 燻 + 0x7184, KANJI_LEVEL4, // 熄 + 0x7195, KANJI_LEVEL4, // 熕 + 0x71A8, KANJI_LEVEL4, // 熹 + 0x71AC, KANJI_LEVEL4, // 熬 + 0x71D7, KANJI_LEVEL4, // 燗 + 0x71B9, KANJI_LEVEL4, // 熹 + 0x71BE, KANJI_LEVEL4, // 熟 + 0x71D2, KANJI_LEVEL4, // 燒 + 0x71C9, KANJI_LEVEL4, // 燉 + 0x71D4, KANJI_LEVEL4, // 燔 + 0x71CE, KANJI_LEVEL4, // 燎 + 0x71E0, KANJI_LEVEL4, // 燠 + 0x71EC, KANJI_LEVEL4, // 燬 + 0x71E7, KANJI_LEVEL4, // 燧 + 0x71F5, KANJI_LEVEL4, // 燵 + 0x71FC, KANJI_LEVEL4, // 燌 + 0x71F9, KANJI_LEVEL4, // 燹 + 0x71FF, KANJI_LEVEL4, // 燿 + 0x720D, KANJI_LEVEL4, // 爍 + 0x7210, KANJI_LEVEL4, // 爐 + 0x721B, KANJI_LEVEL4, // 爛 + 0x7228, KANJI_LEVEL4, // 爚 + 0x722D, KANJI_LEVEL4, // 爭 + 0x722C, KANJI_LEVEL4, // 爬 + 0x7230, KANJI_LEVEL4, // 爰 + 0x7232, KANJI_LEVEL4, // 爲 + 0x723B, KANJI_LEVEL4, // 爻 + 0x723C, KANJI_LEVEL4, // 爌 + 0x723F, KANJI_LEVEL4, // 爿 + 0x7240, KANJI_LEVEL4, // 牀 + 0x7246, KANJI_LEVEL4, // 牆 + 0x724B, KANJI_LEVEL4, // 牋 + 0x7258, KANJI_LEVEL4, // 牘 + 0x7274, KANJI_LEVEL4, // 牮 + 0x727E, KANJI_LEVEL4, // 牟 + 0x7282, KANJI_LEVEL4, // 犂 + 0x7281, KANJI_LEVEL4, // 犁 + 0x7287, KANJI_LEVEL4, // 犇 + 0x7292, KANJI_LEVEL4, // 犒 + 0x7296, KANJI_LEVEL4, // 犖 + 0x72A2, KANJI_LEVEL4, // 犢 + 0x72A7, KANJI_LEVEL4, // 犧 + 0x72B9, KANJI_LEVEL4, // 犹 + 0x72B2, KANJI_LEVEL4, // 犲 + 0x72C3, KANJI_LEVEL4, // 狃 + 0x72C6, KANJI_LEVEL4, // 狆 + 0x72C4, KANJI_LEVEL4, // 狄 + 0x72CE, KANJI_LEVEL4, // 狎 + 0x72D2, KANJI_LEVEL4, // 狒 + 0x72E2, KANJI_LEVEL4, // 狢 + 0x72E0, KANJI_LEVEL4, // 狠 + 0x72E1, KANJI_LEVEL4, // 狡 + 0x72F9, KANJI_LEVEL4, // 狹 + 0x72F7, KANJI_LEVEL4, // 狷 + 0x500F, KANJI_LEVEL4, // 倏 + 0x7317, KANJI_LEVEL4, // 猗 + 0x730A, KANJI_LEVEL4, // 猊 + 0x731C, KANJI_LEVEL4, // 猜 + 0x7316, KANJI_LEVEL4, // 猖 + 0x731D, KANJI_LEVEL4, // 猝 + 0x7334, KANJI_LEVEL4, // 献 + 0x732F, KANJI_LEVEL4, // 猯 + 0x7329, KANJI_LEVEL4, // 猩 + 0x7325, KANJI_LEVEL4, // 猥 + 0x733E, KANJI_LEVEL4, // 猟 + 0x734E, KANJI_LEVEL4, // 獎 + 0x734F, KANJI_LEVEL4, // 獏 + 0x9ED8, KANJI_LEVEL4, // 默 + 0x7357, KANJI_LEVEL4, // 獗 + 0x736A, KANJI_LEVEL4, // 獪 + 0x7368, KANJI_LEVEL4, // 獚 + 0x7370, KANJI_LEVEL4, // 獰 + 0x7378, KANJI_LEVEL4, // 獞 + 0x7375, KANJI_LEVEL4, // 獵 + 0x737B, KANJI_LEVEL4, // 獻 + 0x737A, KANJI_LEVEL4, // 獺 + 0x73C8, KANJI_LEVEL4, // 珈 + 0x73B3, KANJI_LEVEL4, // 玳 + 0x73CE, KANJI_LEVEL4, // 珎 + 0x73BB, KANJI_LEVEL4, // 玻 + 0x73C0, KANJI_LEVEL4, // 珀 + 0x73E5, KANJI_LEVEL4, // 珥 + 0x73EE, KANJI_LEVEL4, // 珮 + 0x73DE, KANJI_LEVEL4, // 珞 + 0x74A2, KANJI_LEVEL4, // 璢 + 0x7405, KANJI_LEVEL4, // 琅 + 0x746F, KANJI_LEVEL4, // 瑯 + 0x7425, KANJI_LEVEL4, // 琥 + 0x73F8, KANJI_LEVEL4, // 珞 + 0x7432, KANJI_LEVEL4, // 琲 + 0x743A, KANJI_LEVEL4, // 琺 + 0x7455, KANJI_LEVEL4, // 瑕 + 0x743F, KANJI_LEVEL4, // 琿 + 0x745F, KANJI_LEVEL4, // 瑟 + 0x7459, KANJI_LEVEL4, // 瑙 + 0x7441, KANJI_LEVEL4, // 瑁 + 0x745C, KANJI_LEVEL4, // 瑜 + 0x7469, KANJI_LEVEL4, // 瑩 + 0x7470, KANJI_LEVEL4, // 瑰 + 0x7463, KANJI_LEVEL4, // 瑣 + 0x746A, KANJI_LEVEL4, // 瑪 + 0x7476, KANJI_LEVEL4, // 瑶 + 0x747E, KANJI_LEVEL4, // 瑟 + 0x748B, KANJI_LEVEL4, // 璋 + 0x749E, KANJI_LEVEL4, // 璞 + 0x74A7, KANJI_LEVEL4, // 璧 + 0x74CA, KANJI_LEVEL4, // 瓊 + 0x74CF, KANJI_LEVEL4, // 瓏 + 0x74D4, KANJI_LEVEL4, // 瓔 + 0x73F1, KANJI_LEVEL4, // 珱 + 0x74E0, KANJI_LEVEL4, // 瓠 + 0x74E3, KANJI_LEVEL4, // 瓣 + 0x74E7, KANJI_LEVEL4, // 瓧 + 0x74E9, KANJI_LEVEL4, // 瓩 + 0x74EE, KANJI_LEVEL4, // 瓮 + 0x74F2, KANJI_LEVEL4, // 瓲 + 0x74F0, KANJI_LEVEL4, // 瓰 + 0x74F1, KANJI_LEVEL4, // 瓱 + 0x74F8, KANJI_LEVEL4, // 瓾 + 0x74F7, KANJI_LEVEL4, // 瓷 + 0x7504, KANJI_LEVEL4, // 甄 + 0x7503, KANJI_LEVEL4, // 甃 + 0x7505, KANJI_LEVEL4, // 甅 + 0x750C, KANJI_LEVEL4, // 甌 + 0x750E, KANJI_LEVEL4, // 甎 + 0x750D, KANJI_LEVEL4, // 甍 + 0x7515, KANJI_LEVEL4, // 甕 + 0x7513, KANJI_LEVEL4, // 甓 + 0x751E, KANJI_LEVEL4, // 甞 + 0x7526, KANJI_LEVEL4, // 甩 + 0x752C, KANJI_LEVEL4, // 甬 + 0x753C, KANJI_LEVEL4, // 甌 + 0x7544, KANJI_LEVEL4, // 畄 + 0x754D, KANJI_LEVEL4, // 畍 + 0x754A, KANJI_LEVEL4, // 畊 + 0x7549, KANJI_LEVEL4, // 畉 + 0x755B, KANJI_LEVEL4, // 畛 + 0x7546, KANJI_LEVEL4, // 畆 + 0x755A, KANJI_LEVEL4, // 畚 + 0x7569, KANJI_LEVEL4, // 畩 + 0x7564, KANJI_LEVEL4, // ç•€ + 0x7567, KANJI_LEVEL4, // 畧 + 0x756B, KANJI_LEVEL4, // 畫 + 0x756D, KANJI_LEVEL4, // 畭 + 0x7578, KANJI_LEVEL4, // 畾 + 0x7576, KANJI_LEVEL4, // 當 + 0x7586, KANJI_LEVEL4, // 疆 + 0x7587, KANJI_LEVEL4, // 疇 + 0x7574, KANJI_LEVEL4, // 畮 + 0x758A, KANJI_LEVEL4, // 疊 + 0x7589, KANJI_LEVEL4, // 疉 + 0x7582, KANJI_LEVEL4, // 疂 + 0x7594, KANJI_LEVEL4, // 疔 + 0x759A, KANJI_LEVEL4, // 疚 + 0x759D, KANJI_LEVEL4, // 疝 + 0x75A5, KANJI_LEVEL4, // 疥 + 0x75A3, KANJI_LEVEL4, // 疣 + 0x75C2, KANJI_LEVEL4, // 痂 + 0x75B3, KANJI_LEVEL4, // 疳 + 0x75C3, KANJI_LEVEL4, // 痃 + 0x75B5, KANJI_LEVEL4, // 疵 + 0x75BD, KANJI_LEVEL4, // ç–œ + 0x75B8, KANJI_LEVEL4, // 疾 + 0x75BC, KANJI_LEVEL4, // ç–Œ + 0x75B1, KANJI_LEVEL4, // 疱 + 0x75CD, KANJI_LEVEL4, // 痍 + 0x75CA, KANJI_LEVEL4, // 痊 + 0x75D2, KANJI_LEVEL4, // 痒 + 0x75D9, KANJI_LEVEL4, // 痙 + 0x75E3, KANJI_LEVEL4, // 痣 + 0x75DE, KANJI_LEVEL4, // 痞 + 0x75FE, KANJI_LEVEL4, // ç—Ÿ + 0x75FF, KANJI_LEVEL4, // 痿 + 0x75FC, KANJI_LEVEL4, // ç—Œ + 0x7601, KANJI_LEVEL4, // 瘁 + 0x75F0, KANJI_LEVEL4, // 痰 + 0x75FA, KANJI_LEVEL4, // 痺 + 0x75F2, KANJI_LEVEL4, // 痲 + 0x75F3, KANJI_LEVEL4, // 痳 + 0x760B, KANJI_LEVEL4, // 瘋 + 0x760D, KANJI_LEVEL4, // 瘍 + 0x7609, KANJI_LEVEL4, // 瘉 + 0x761F, KANJI_LEVEL4, // 瘟 + 0x7627, KANJI_LEVEL4, // 瘧 + 0x7620, KANJI_LEVEL4, // 瘠 + 0x7621, KANJI_LEVEL4, // 瘡 + 0x7622, KANJI_LEVEL4, // 瘢 + 0x7624, KANJI_LEVEL4, // 瘀 + 0x7634, KANJI_LEVEL4, // 瘎 + 0x7630, KANJI_LEVEL4, // 瘰 + 0x763B, KANJI_LEVEL4, // 瘻 + 0x7647, KANJI_LEVEL4, // 癇 + 0x7648, KANJI_LEVEL4, // 癈 + 0x7646, KANJI_LEVEL4, // 癆 + 0x765C, KANJI_LEVEL4, // 癜 + 0x7658, KANJI_LEVEL4, // 癘 + 0x7661, KANJI_LEVEL4, // 癡 + 0x7662, KANJI_LEVEL4, // 癢 + 0x7668, KANJI_LEVEL4, // 癹 + 0x7669, KANJI_LEVEL4, // 癩 + 0x766A, KANJI_LEVEL4, // 癪 + 0x7667, KANJI_LEVEL4, // 癧 + 0x766C, KANJI_LEVEL4, // 癬 + 0x7670, KANJI_LEVEL4, // 癰 + 0x7672, KANJI_LEVEL4, // 癲 + 0x7676, KANJI_LEVEL4, // 癶 + 0x7678, KANJI_LEVEL4, // 百 + 0x767C, KANJI_LEVEL4, // 癌 + 0x7680, KANJI_LEVEL4, // 皀 + 0x7683, KANJI_LEVEL4, // 皃 + 0x7688, KANJI_LEVEL4, // 皈 + 0x768B, KANJI_LEVEL4, // 皋 + 0x768E, KANJI_LEVEL4, // 皎 + 0x7696, KANJI_LEVEL4, // 皖 + 0x7693, KANJI_LEVEL4, // 皓 + 0x7699, KANJI_LEVEL4, // 皙 + 0x769A, KANJI_LEVEL4, // 皚 + 0x76B0, KANJI_LEVEL4, // 皰 + 0x76B4, KANJI_LEVEL4, // 皮 + 0x76B8, KANJI_LEVEL4, // 皾 + 0x76B9, KANJI_LEVEL4, // 皹 + 0x76BA, KANJI_LEVEL4, // 皺 + 0x76C2, KANJI_LEVEL4, // 盂 + 0x76CD, KANJI_LEVEL4, // 盍 + 0x76D6, KANJI_LEVEL4, // 盖 + 0x76D2, KANJI_LEVEL4, // 盒 + 0x76DE, KANJI_LEVEL4, // 盞 + 0x76E1, KANJI_LEVEL4, // 盡 + 0x76E5, KANJI_LEVEL4, // 盥 + 0x76E7, KANJI_LEVEL4, // 盧 + 0x76EA, KANJI_LEVEL4, // 盪 + 0x862F, KANJI_LEVEL4, // 蘯 + 0x76FB, KANJI_LEVEL4, // 盻 + 0x7708, KANJI_LEVEL4, // 眈 + 0x7707, KANJI_LEVEL4, // 眇 + 0x7704, KANJI_LEVEL4, // 眄 + 0x7729, KANJI_LEVEL4, // 眩 + 0x7724, KANJI_LEVEL4, // 眀 + 0x771E, KANJI_LEVEL4, // 眞 + 0x7725, KANJI_LEVEL4, // 眥 + 0x7726, KANJI_LEVEL4, // 眩 + 0x771B, KANJI_LEVEL4, // 眛 + 0x7737, KANJI_LEVEL4, // 眷 + 0x7738, KANJI_LEVEL4, // 眾 + 0x7747, KANJI_LEVEL4, // 睇 + 0x775A, KANJI_LEVEL4, // 睚 + 0x7768, KANJI_LEVEL4, // 睚 + 0x776B, KANJI_LEVEL4, // 睫 + 0x775B, KANJI_LEVEL4, // 睛 + 0x7765, KANJI_LEVEL4, // 睥 + 0x777F, KANJI_LEVEL4, // 睿 + 0x777E, KANJI_LEVEL4, // 睟 + 0x7779, KANJI_LEVEL4, // 睹 + 0x778E, KANJI_LEVEL4, // 瞎 + 0x778B, KANJI_LEVEL4, // 瞋 + 0x7791, KANJI_LEVEL4, // 瞑 + 0x77A0, KANJI_LEVEL4, // 瞠 + 0x779E, KANJI_LEVEL4, // 瞞 + 0x77B0, KANJI_LEVEL4, // 瞰 + 0x77B6, KANJI_LEVEL4, // 瞶 + 0x77B9, KANJI_LEVEL4, // 瞹 + 0x77BF, KANJI_LEVEL4, // 瞿 + 0x77BC, KANJI_LEVEL4, // 瞌 + 0x77BD, KANJI_LEVEL4, // 瞜 + 0x77BB, KANJI_LEVEL4, // 瞻 + 0x77C7, KANJI_LEVEL4, // 矇 + 0x77CD, KANJI_LEVEL4, // 矍 + 0x77D7, KANJI_LEVEL4, // 矗 + 0x77DA, KANJI_LEVEL4, // 矚 + 0x77DC, KANJI_LEVEL4, // 矜 + 0x77E3, KANJI_LEVEL4, // 矣 + 0x77EE, KANJI_LEVEL4, // 矮 + 0x77FC, KANJI_LEVEL4, // 矌 + 0x780C, KANJI_LEVEL4, // 砌 + 0x7812, KANJI_LEVEL4, // 砒 + 0x7926, KANJI_LEVEL4, // 瀊 + 0x7820, KANJI_LEVEL4, // ç   + 0x792A, KANJI_LEVEL4, // 瀪 + 0x7845, KANJI_LEVEL4, // 硅 + 0x788E, KANJI_LEVEL4, // 碎 + 0x7874, KANJI_LEVEL4, // 硎 + 0x7886, KANJI_LEVEL4, // 碆 + 0x787C, KANJI_LEVEL4, // 硌 + 0x789A, KANJI_LEVEL4, // 碚 + 0x788C, KANJI_LEVEL4, // 碌 + 0x78A3, KANJI_LEVEL4, // 碣 + 0x78B5, KANJI_LEVEL4, // 碵 + 0x78AA, KANJI_LEVEL4, // 碪 + 0x78AF, KANJI_LEVEL4, // 碯 + 0x78D1, KANJI_LEVEL4, // 磑 + 0x78C6, KANJI_LEVEL4, // 磆 + 0x78CB, KANJI_LEVEL4, // 磋 + 0x78D4, KANJI_LEVEL4, // 磔 + 0x78BE, KANJI_LEVEL4, // 碟 + 0x78BC, KANJI_LEVEL4, // 碌 + 0x78C5, KANJI_LEVEL4, // 磅 + 0x78CA, KANJI_LEVEL4, // 磊 + 0x78EC, KANJI_LEVEL4, // 磬 + 0x78E7, KANJI_LEVEL4, // 磧 + 0x78DA, KANJI_LEVEL4, // 磚 + 0x78FD, KANJI_LEVEL4, // 磜 + 0x78F4, KANJI_LEVEL4, // 磎 + 0x7907, KANJI_LEVEL4, // 瀇 + 0x7912, KANJI_LEVEL4, // 瀒 + 0x7911, KANJI_LEVEL4, // 瀑 + 0x7919, KANJI_LEVEL4, // 瀙 + 0x792C, KANJI_LEVEL4, // 瀬 + 0x792B, KANJI_LEVEL4, // 瀫 + 0x7940, KANJI_LEVEL4, // 祀 + 0x7960, KANJI_LEVEL4, // 祠 + 0x7957, KANJI_LEVEL4, // 祗 + 0x795F, KANJI_LEVEL4, // 祟 + 0x795A, KANJI_LEVEL4, // 祚 + 0x7955, KANJI_LEVEL4, // 祕 + 0x7953, KANJI_LEVEL4, // 祓 + 0x797A, KANJI_LEVEL4, // 祺 + 0x797F, KANJI_LEVEL4, // 祿 + 0x798A, KANJI_LEVEL4, // 穊 + 0x799D, KANJI_LEVEL4, // 犝 + 0x79A7, KANJI_LEVEL4, // 犧 + 0x9F4B, KANJI_LEVEL4, // 霋 + 0x79AA, KANJI_LEVEL4, // 犪 + 0x79AE, KANJI_LEVEL4, // 犮 + 0x79B3, KANJI_LEVEL4, // 犳 + 0x79B9, KANJI_LEVEL4, // 犹 + 0x79BA, KANJI_LEVEL4, // 犺 + 0x79C9, KANJI_LEVEL4, // 秉 + 0x79D5, KANJI_LEVEL4, // 秕 + 0x79E7, KANJI_LEVEL4, // ç§§ + 0x79EC, KANJI_LEVEL4, // 秬 + 0x79E1, KANJI_LEVEL4, // ç§¡ + 0x79E3, KANJI_LEVEL4, // ç§£ + 0x7A08, KANJI_LEVEL4, // 皈 + 0x7A0D, KANJI_LEVEL4, // 皍 + 0x7A18, KANJI_LEVEL4, // 皘 + 0x7A19, KANJI_LEVEL4, // 繙 + 0x7A20, KANJI_LEVEL4, // çš  + 0x7A1F, KANJI_LEVEL4, // 繟 + 0x7980, KANJI_LEVEL4, // 穀 + 0x7A31, KANJI_LEVEL4, // çš± + 0x7A3B, KANJI_LEVEL4, // çš» + 0x7A3E, KANJI_LEVEL4, // 皟 + 0x7A37, KANJI_LEVEL4, // çš· + 0x7A43, KANJI_LEVEL4, // 穃 + 0x7A57, KANJI_LEVEL4, // 穗 + 0x7A49, KANJI_LEVEL4, // 穉 + 0x7A61, KANJI_LEVEL4, // ç©¡ + 0x7A62, KANJI_LEVEL4, // ç©¢ + 0x7A69, KANJI_LEVEL4, // ç©© + 0x9F9D, KANJI_LEVEL4, // 韝 + 0x7A70, KANJI_LEVEL4, // ç©° + 0x7A79, KANJI_LEVEL4, // 穹 + 0x7A7D, KANJI_LEVEL4, // 穜 + 0x7A88, KANJI_LEVEL4, // 窈 + 0x7A97, KANJI_LEVEL4, // 窗 + 0x7A95, KANJI_LEVEL4, // 窕 + 0x7A98, KANJI_LEVEL4, // 窘 + 0x7A96, KANJI_LEVEL4, // 窖 + 0x7AA9, KANJI_LEVEL4, // 窩 + 0x7AC8, KANJI_LEVEL4, // 竈 + 0x7AB0, KANJI_LEVEL4, // 窰 + 0x7AB6, KANJI_LEVEL4, // 窶 + 0x7AC5, KANJI_LEVEL4, // 竅 + 0x7AC4, KANJI_LEVEL4, // 竄 + 0x7ABF, KANJI_LEVEL4, // 窿 + 0x9083, KANJI_LEVEL4, // 邃 + 0x7AC7, KANJI_LEVEL4, // 竇 + 0x7ACA, KANJI_LEVEL4, // 竊 + 0x7ACD, KANJI_LEVEL4, // 竍 + 0x7ACF, KANJI_LEVEL4, // 竏 + 0x7AD5, KANJI_LEVEL4, // 竕 + 0x7AD3, KANJI_LEVEL4, // 竓 + 0x7AD9, KANJI_LEVEL4, // 站 + 0x7ADA, KANJI_LEVEL4, // 竚 + 0x7ADD, KANJI_LEVEL4, // 竝 + 0x7AE1, KANJI_LEVEL4, // ç«¡ + 0x7AE2, KANJI_LEVEL4, // ç«¢ + 0x7AE6, KANJI_LEVEL4, // 竊 + 0x7AED, KANJI_LEVEL4, // ç«­ + 0x7AF0, KANJI_LEVEL4, // ç«° + 0x7B02, KANJI_LEVEL4, // 笂 + 0x7B0F, KANJI_LEVEL4, // 笏 + 0x7B0A, KANJI_LEVEL4, // 笊 + 0x7B06, KANJI_LEVEL4, // 笆 + 0x7B33, KANJI_LEVEL4, // 笳 + 0x7B18, KANJI_LEVEL4, // 笘 + 0x7B19, KANJI_LEVEL4, // 笙 + 0x7B1E, KANJI_LEVEL4, // 笞 + 0x7B35, KANJI_LEVEL4, // 笵 + 0x7B28, KANJI_LEVEL4, // 笚 + 0x7B36, KANJI_LEVEL4, // 笶 + 0x7B50, KANJI_LEVEL4, // 筐 + 0x7B7A, KANJI_LEVEL4, // ç­º + 0x7B04, KANJI_LEVEL4, // 笄 + 0x7B4D, KANJI_LEVEL4, // 筍 + 0x7B0B, KANJI_LEVEL4, // 笋 + 0x7B4C, KANJI_LEVEL4, // 筌 + 0x7B45, KANJI_LEVEL4, // 筅 + 0x7B75, KANJI_LEVEL4, // ç­µ + 0x7B65, KANJI_LEVEL4, // ç­¥ + 0x7B74, KANJI_LEVEL4, // ç­Ž + 0x7B67, KANJI_LEVEL4, // ç­§ + 0x7B70, KANJI_LEVEL4, // ç­° + 0x7B71, KANJI_LEVEL4, // ç­± + 0x7B6C, KANJI_LEVEL4, // ç­¬ + 0x7B6E, KANJI_LEVEL4, // ç­® + 0x7B9D, KANJI_LEVEL4, // 箝 + 0x7B98, KANJI_LEVEL4, // 箘 + 0x7B9F, KANJI_LEVEL4, // 箟 + 0x7B8D, KANJI_LEVEL4, // 箍 + 0x7B9C, KANJI_LEVEL4, // 箜 + 0x7B9A, KANJI_LEVEL4, // 箚 + 0x7B8B, KANJI_LEVEL4, // 箋 + 0x7B92, KANJI_LEVEL4, // 箒 + 0x7B8F, KANJI_LEVEL4, // 箏 + 0x7B5D, KANJI_LEVEL4, // 筝 + 0x7B99, KANJI_LEVEL4, // 箙 + 0x7BCB, KANJI_LEVEL4, // 篋 + 0x7BC1, KANJI_LEVEL4, // 篁 + 0x7BCC, KANJI_LEVEL4, // 篌 + 0x7BCF, KANJI_LEVEL4, // 篏 + 0x7BB4, KANJI_LEVEL4, // 箎 + 0x7BC6, KANJI_LEVEL4, // 篆 + 0x7BDD, KANJI_LEVEL4, // 篝 + 0x7BE9, KANJI_LEVEL4, // 篩 + 0x7C11, KANJI_LEVEL4, // 簑 + 0x7C14, KANJI_LEVEL4, // 簔 + 0x7BE6, KANJI_LEVEL4, // 篊 + 0x7BE5, KANJI_LEVEL4, // 篥 + 0x7C60, KANJI_LEVEL4, // ç±  + 0x7C00, KANJI_LEVEL4, // 簀 + 0x7C07, KANJI_LEVEL4, // 簇 + 0x7C13, KANJI_LEVEL4, // 簓 + 0x7BF3, KANJI_LEVEL4, // 篳 + 0x7BF7, KANJI_LEVEL4, // 篷 + 0x7C17, KANJI_LEVEL4, // 簗 + 0x7C0D, KANJI_LEVEL4, // 簍 + 0x7BF6, KANJI_LEVEL4, // 篶 + 0x7C23, KANJI_LEVEL4, // ç°£ + 0x7C27, KANJI_LEVEL4, // ç°§ + 0x7C2A, KANJI_LEVEL4, // ç°ª + 0x7C1F, KANJI_LEVEL4, // 簟 + 0x7C37, KANJI_LEVEL4, // ç°· + 0x7C2B, KANJI_LEVEL4, // ç°« + 0x7C3D, KANJI_LEVEL4, // ç°œ + 0x7C4C, KANJI_LEVEL4, // 籌 + 0x7C43, KANJI_LEVEL4, // 籃 + 0x7C54, KANJI_LEVEL4, // 籔 + 0x7C4F, KANJI_LEVEL4, // 籏 + 0x7C40, KANJI_LEVEL4, // 籀 + 0x7C50, KANJI_LEVEL4, // 籐 + 0x7C58, KANJI_LEVEL4, // 籘 + 0x7C5F, KANJI_LEVEL4, // 籟 + 0x7C64, KANJI_LEVEL4, // ç±€ + 0x7C56, KANJI_LEVEL4, // 籖 + 0x7C65, KANJI_LEVEL4, // ç±¥ + 0x7C6C, KANJI_LEVEL4, // 籬 + 0x7C75, KANJI_LEVEL4, // ç±µ + 0x7C83, KANJI_LEVEL4, // 粃 + 0x7C90, KANJI_LEVEL4, // 粐 + 0x7CA4, KANJI_LEVEL4, // ç²€ + 0x7CAD, KANJI_LEVEL4, // ç²­ + 0x7CA2, KANJI_LEVEL4, // ç²¢ + 0x7CAB, KANJI_LEVEL4, // 粫 + 0x7CA1, KANJI_LEVEL4, // 粡 + 0x7CA8, KANJI_LEVEL4, // 粚 + 0x7CB3, KANJI_LEVEL4, // ç²³ + 0x7CB2, KANJI_LEVEL4, // ç²² + 0x7CB1, KANJI_LEVEL4, // ç²± + 0x7CAE, KANJI_LEVEL4, // ç²® + 0x7CB9, KANJI_LEVEL4, // ç²¹ + 0x7CBD, KANJI_LEVEL4, // 粜 + 0x7CC0, KANJI_LEVEL4, // 糀 + 0x7CC5, KANJI_LEVEL4, // 糅 + 0x7CC2, KANJI_LEVEL4, // 糂 + 0x7CD8, KANJI_LEVEL4, // 糘 + 0x7CD2, KANJI_LEVEL4, // 糒 + 0x7CDC, KANJI_LEVEL4, // 糜 + 0x7CE2, KANJI_LEVEL4, // ç³¢ + 0x9B3B, KANJI_LEVEL4, // 鬻 + 0x7CEF, KANJI_LEVEL4, // 糯 + 0x7CF2, KANJI_LEVEL4, // ç³² + 0x7CF4, KANJI_LEVEL4, // 糎 + 0x7CF6, KANJI_LEVEL4, // ç³¶ + 0x7CFA, KANJI_LEVEL4, // 糺 + 0x7D06, KANJI_LEVEL4, // 箆 + 0x7D02, KANJI_LEVEL4, // 箂 + 0x7D1C, KANJI_LEVEL4, // 箜 + 0x7D15, KANJI_LEVEL4, // 箕 + 0x7D0A, KANJI_LEVEL4, // 箊 + 0x7D45, KANJI_LEVEL4, // 絅 + 0x7D4B, KANJI_LEVEL4, // 絋 + 0x7D2E, KANJI_LEVEL4, // 玮 + 0x7D32, KANJI_LEVEL4, // 玲 + 0x7D3F, KANJI_LEVEL4, // 玿 + 0x7D35, KANJI_LEVEL4, // 玵 + 0x7D46, KANJI_LEVEL4, // 絆 + 0x7D73, KANJI_LEVEL4, // çµ³ + 0x7D56, KANJI_LEVEL4, // 絖 + 0x7D4E, KANJI_LEVEL4, // 絎 + 0x7D72, KANJI_LEVEL4, // çµ² + 0x7D68, KANJI_LEVEL4, // 絚 + 0x7D6E, KANJI_LEVEL4, // çµ® + 0x7D4F, KANJI_LEVEL4, // 絏 + 0x7D63, KANJI_LEVEL4, // çµ£ + 0x7D93, KANJI_LEVEL4, // 經 + 0x7D89, KANJI_LEVEL4, // 綉 + 0x7D5B, KANJI_LEVEL4, // 絛 + 0x7D8F, KANJI_LEVEL4, // 綏 + 0x7D7D, KANJI_LEVEL4, // 絜 + 0x7D9B, KANJI_LEVEL4, // 綛 + 0x7DBA, KANJI_LEVEL4, // 綺 + 0x7DAE, KANJI_LEVEL4, // ç¶® + 0x7DA3, KANJI_LEVEL4, // ç¶£ + 0x7DB5, KANJI_LEVEL4, // ç¶µ + 0x7DC7, KANJI_LEVEL4, // 緇 + 0x7DBD, KANJI_LEVEL4, // ç¶œ + 0x7DAB, KANJI_LEVEL4, // ç¶« + 0x7E3D, KANJI_LEVEL4, // çžœ + 0x7DA2, KANJI_LEVEL4, // ç¶¢ + 0x7DAF, KANJI_LEVEL4, // 綯 + 0x7DDC, KANJI_LEVEL4, // 緜 + 0x7DB8, KANJI_LEVEL4, // ç¶ž + 0x7D9F, KANJI_LEVEL4, // 綟 + 0x7DB0, KANJI_LEVEL4, // ç¶° + 0x7DD8, KANJI_LEVEL4, // 緘 + 0x7DDD, KANJI_LEVEL4, // 緝 + 0x7DE4, KANJI_LEVEL4, // ç·€ + 0x7DDE, KANJI_LEVEL4, // 緞 + 0x7DFB, KANJI_LEVEL4, // ç·» + 0x7DF2, KANJI_LEVEL4, // ç·² + 0x7DE1, KANJI_LEVEL4, // ç·¡ + 0x7E05, KANJI_LEVEL4, // 羅 + 0x7E0A, KANJI_LEVEL4, // 羊 + 0x7E23, KANJI_LEVEL4, // 瞣 + 0x7E21, KANJI_LEVEL4, // çž¡ + 0x7E12, KANJI_LEVEL4, // 羒 + 0x7E31, KANJI_LEVEL4, // çž± + 0x7E1F, KANJI_LEVEL4, // 羟 + 0x7E09, KANJI_LEVEL4, // 羉 + 0x7E0B, KANJI_LEVEL4, // 羋 + 0x7E22, KANJI_LEVEL4, // 瞢 + 0x7E46, KANJI_LEVEL4, // 繆 + 0x7E66, KANJI_LEVEL4, // 繊 + 0x7E3B, KANJI_LEVEL4, // çž» + 0x7E35, KANJI_LEVEL4, // çžµ + 0x7E39, KANJI_LEVEL4, // çž¹ + 0x7E43, KANJI_LEVEL4, // 繃 + 0x7E37, KANJI_LEVEL4, // çž· + 0x7E32, KANJI_LEVEL4, // çž² + 0x7E3A, KANJI_LEVEL4, // 瞺 + 0x7E67, KANJI_LEVEL4, // ç¹§ + 0x7E5D, KANJI_LEVEL4, // 繝 + 0x7E56, KANJI_LEVEL4, // 繖 + 0x7E5E, KANJI_LEVEL4, // 繞 + 0x7E59, KANJI_LEVEL4, // 繙 + 0x7E5A, KANJI_LEVEL4, // 繚 + 0x7E79, KANJI_LEVEL4, // ç¹¹ + 0x7E6A, KANJI_LEVEL4, // 繪 + 0x7E69, KANJI_LEVEL4, // 繩 + 0x7E7C, KANJI_LEVEL4, // 繌 + 0x7E7B, KANJI_LEVEL4, // ç¹» + 0x7E83, KANJI_LEVEL4, // 纃 + 0x7DD5, KANJI_LEVEL4, // 緕 + 0x7E7D, KANJI_LEVEL4, // 繜 + 0x8FAE, KANJI_LEVEL4, // 蟮 + 0x7E7F, KANJI_LEVEL4, // 繿 + 0x7E88, KANJI_LEVEL4, // 纈 + 0x7E89, KANJI_LEVEL4, // 纉 + 0x7E8C, KANJI_LEVEL4, // 續 + 0x7E92, KANJI_LEVEL4, // 纒 + 0x7E90, KANJI_LEVEL4, // 纐 + 0x7E93, KANJI_LEVEL4, // 纓 + 0x7E94, KANJI_LEVEL4, // 纔 + 0x7E96, KANJI_LEVEL4, // 纖 + 0x7E8E, KANJI_LEVEL4, // 纎 + 0x7E9B, KANJI_LEVEL4, // 纛 + 0x7E9C, KANJI_LEVEL4, // 纜 + 0x7F38, KANJI_LEVEL4, // 猞 + 0x7F3A, KANJI_LEVEL4, // 猺 + 0x7F45, KANJI_LEVEL4, // 眅 + 0x7F4C, KANJI_LEVEL4, // 県 + 0x7F4D, KANJI_LEVEL4, // 眍 + 0x7F4E, KANJI_LEVEL4, // 眎 + 0x7F50, KANJI_LEVEL4, // 眐 + 0x7F51, KANJI_LEVEL4, // 眑 + 0x7F55, KANJI_LEVEL4, // 眕 + 0x7F54, KANJI_LEVEL4, // 眔 + 0x7F58, KANJI_LEVEL4, // 眘 + 0x7F5F, KANJI_LEVEL4, // 真 + 0x7F60, KANJI_LEVEL4, // 眠 + 0x7F68, KANJI_LEVEL4, // 眚 + 0x7F69, KANJI_LEVEL4, // 眩 + 0x7F67, KANJI_LEVEL4, // 眧 + 0x7F78, KANJI_LEVEL4, // 眞 + 0x7F82, KANJI_LEVEL4, // 矂 + 0x7F86, KANJI_LEVEL4, // 矆 + 0x7F83, KANJI_LEVEL4, // 矃 + 0x7F88, KANJI_LEVEL4, // 矈 + 0x7F87, KANJI_LEVEL4, // 矇 + 0x7F8C, KANJI_LEVEL4, // 矌 + 0x7F94, KANJI_LEVEL4, // 矔 + 0x7F9E, KANJI_LEVEL4, // 矞 + 0x7F9D, KANJI_LEVEL4, // 矝 + 0x7F9A, KANJI_LEVEL4, // 矚 + 0x7FA3, KANJI_LEVEL4, // 矣 + 0x7FAF, KANJI_LEVEL4, // 矯 + 0x7FB2, KANJI_LEVEL4, // 矲 + 0x7FB9, KANJI_LEVEL4, // 矹 + 0x7FAE, KANJI_LEVEL4, // 矮 + 0x7FB6, KANJI_LEVEL4, // 矶 + 0x7FB8, KANJI_LEVEL4, // 矞 + 0x8B71, KANJI_LEVEL4, // è­± + 0x7FC5, KANJI_LEVEL4, // 翅 + 0x7FC6, KANJI_LEVEL4, // 翆 + 0x7FCA, KANJI_LEVEL4, // 翊 + 0x7FD5, KANJI_LEVEL4, // 翕 + 0x7FD4, KANJI_LEVEL4, // 翔 + 0x7FE1, KANJI_LEVEL4, // ç¿¡ + 0x7FE6, KANJI_LEVEL4, // 翊 + 0x7FE9, KANJI_LEVEL4, // ç¿© + 0x7FF3, KANJI_LEVEL4, // 翳 + 0x7FF9, KANJI_LEVEL4, // 翹 + 0x98DC, KANJI_LEVEL4, // 飜 + 0x8006, KANJI_LEVEL4, // 耆 + 0x8004, KANJI_LEVEL4, // 耄 + 0x800B, KANJI_LEVEL4, // 耋 + 0x8012, KANJI_LEVEL4, // 耒 + 0x8018, KANJI_LEVEL4, // 耘 + 0x8019, KANJI_LEVEL4, // 耙 + 0x801C, KANJI_LEVEL4, // 耜 + 0x8021, KANJI_LEVEL4, // 耡 + 0x8028, KANJI_LEVEL4, // 耚 + 0x803F, KANJI_LEVEL4, // 耿 + 0x803B, KANJI_LEVEL4, // 耻 + 0x804A, KANJI_LEVEL4, // 聊 + 0x8046, KANJI_LEVEL4, // 聆 + 0x8052, KANJI_LEVEL4, // 聒 + 0x8058, KANJI_LEVEL4, // 聘 + 0x805A, KANJI_LEVEL4, // 聚 + 0x805F, KANJI_LEVEL4, // 聟 + 0x8062, KANJI_LEVEL4, // 聢 + 0x8068, KANJI_LEVEL4, // 聚 + 0x8073, KANJI_LEVEL4, // 聳 + 0x8072, KANJI_LEVEL4, // 聲 + 0x8070, KANJI_LEVEL4, // 聰 + 0x8076, KANJI_LEVEL4, // 聶 + 0x8079, KANJI_LEVEL4, // 聹 + 0x807D, KANJI_LEVEL4, // 聜 + 0x807F, KANJI_LEVEL4, // 聿 + 0x8084, KANJI_LEVEL4, // 肄 + 0x8086, KANJI_LEVEL4, // 肆 + 0x8085, KANJI_LEVEL4, // 肅 + 0x809B, KANJI_LEVEL4, // 肛 + 0x8093, KANJI_LEVEL4, // 肓 + 0x809A, KANJI_LEVEL4, // 肚 + 0x80AD, KANJI_LEVEL4, // 肭 + 0x5190, KANJI_LEVEL4, // 冐 + 0x80AC, KANJI_LEVEL4, // 肬 + 0x80DB, KANJI_LEVEL4, // 胛 + 0x80E5, KANJI_LEVEL4, // 胥 + 0x80D9, KANJI_LEVEL4, // 胙 + 0x80DD, KANJI_LEVEL4, // 胝 + 0x80C4, KANJI_LEVEL4, // 胄 + 0x80DA, KANJI_LEVEL4, // 胚 + 0x80D6, KANJI_LEVEL4, // 胖 + 0x8109, KANJI_LEVEL4, // 脉 + 0x80EF, KANJI_LEVEL4, // 胯 + 0x80F1, KANJI_LEVEL4, // 胱 + 0x811B, KANJI_LEVEL4, // 脛 + 0x8129, KANJI_LEVEL4, // 脩 + 0x8123, KANJI_LEVEL4, // 脣 + 0x812F, KANJI_LEVEL4, // 脯 + 0x814B, KANJI_LEVEL4, // 腋 + 0x968B, KANJI_LEVEL4, // 隋 + 0x8146, KANJI_LEVEL4, // 腆 + 0x813E, KANJI_LEVEL4, // 脟 + 0x8153, KANJI_LEVEL4, // 腓 + 0x8151, KANJI_LEVEL4, // 腑 + 0x80FC, KANJI_LEVEL4, // 背 + 0x8171, KANJI_LEVEL4, // 腱 + 0x816E, KANJI_LEVEL4, // 腮 + 0x8165, KANJI_LEVEL4, // 腥 + 0x8166, KANJI_LEVEL4, // è…Š + 0x8174, KANJI_LEVEL4, // è…Ž + 0x8183, KANJI_LEVEL4, // 膃 + 0x8188, KANJI_LEVEL4, // 膈 + 0x818A, KANJI_LEVEL4, // 膊 + 0x8180, KANJI_LEVEL4, // 膀 + 0x8182, KANJI_LEVEL4, // 膂 + 0x81A0, KANJI_LEVEL4, // 膠 + 0x8195, KANJI_LEVEL4, // 膕 + 0x81A4, KANJI_LEVEL4, // 膀 + 0x81A3, KANJI_LEVEL4, // 膣 + 0x815F, KANJI_LEVEL4, // 腟 + 0x8193, KANJI_LEVEL4, // 膓 + 0x81A9, KANJI_LEVEL4, // 膩 + 0x81B0, KANJI_LEVEL4, // 膰 + 0x81B5, KANJI_LEVEL4, // 膵 + 0x81BE, KANJI_LEVEL4, // 膟 + 0x81B8, KANJI_LEVEL4, // 膞 + 0x81BD, KANJI_LEVEL4, // 膜 + 0x81C0, KANJI_LEVEL4, // 臀 + 0x81C2, KANJI_LEVEL4, // 臂 + 0x81BA, KANJI_LEVEL4, // 膺 + 0x81C9, KANJI_LEVEL4, // 臉 + 0x81CD, KANJI_LEVEL4, // 臍 + 0x81D1, KANJI_LEVEL4, // 臑 + 0x81D9, KANJI_LEVEL4, // 臙 + 0x81D8, KANJI_LEVEL4, // 臘 + 0x81C8, KANJI_LEVEL4, // 臈 + 0x81DA, KANJI_LEVEL4, // 臚 + 0x81DF, KANJI_LEVEL4, // 臟 + 0x81E0, KANJI_LEVEL4, // 臠 + 0x81E7, KANJI_LEVEL4, // 臧 + 0x81FA, KANJI_LEVEL4, // 臺 + 0x81FB, KANJI_LEVEL4, // 臻 + 0x81FE, KANJI_LEVEL4, // 臟 + 0x8201, KANJI_LEVEL4, // 舁 + 0x8202, KANJI_LEVEL4, // 舂 + 0x8205, KANJI_LEVEL4, // 舅 + 0x8207, KANJI_LEVEL4, // 與 + 0x820A, KANJI_LEVEL4, // 舊 + 0x820D, KANJI_LEVEL4, // 舍 + 0x8210, KANJI_LEVEL4, // 舐 + 0x8216, KANJI_LEVEL4, // 舖 + 0x8229, KANJI_LEVEL4, // 舩 + 0x822B, KANJI_LEVEL4, // 舫 + 0x8238, KANJI_LEVEL4, // 舞 + 0x8233, KANJI_LEVEL4, // 舳 + 0x8240, KANJI_LEVEL4, // 艀 + 0x8259, KANJI_LEVEL4, // 艙 + 0x8258, KANJI_LEVEL4, // 艘 + 0x825D, KANJI_LEVEL4, // 艝 + 0x825A, KANJI_LEVEL4, // 艚 + 0x825F, KANJI_LEVEL4, // 艟 + 0x8264, KANJI_LEVEL4, // 艀 + 0x8262, KANJI_LEVEL4, // 艢 + 0x8268, KANJI_LEVEL4, // 艚 + 0x826A, KANJI_LEVEL4, // 艪 + 0x826B, KANJI_LEVEL4, // 艫 + 0x822E, KANJI_LEVEL4, // 舮 + 0x8271, KANJI_LEVEL4, // 艱 + 0x8277, KANJI_LEVEL4, // 艷 + 0x8278, KANJI_LEVEL4, // 艞 + 0x827E, KANJI_LEVEL4, // 艟 + 0x828D, KANJI_LEVEL4, // 芍 + 0x8292, KANJI_LEVEL4, // 芒 + 0x82AB, KANJI_LEVEL4, // 芫 + 0x829F, KANJI_LEVEL4, // 芟 + 0x82BB, KANJI_LEVEL4, // 芻 + 0x82AC, KANJI_LEVEL4, // 芬 + 0x82E1, KANJI_LEVEL4, // 苡 + 0x82E3, KANJI_LEVEL4, // 苣 + 0x82DF, KANJI_LEVEL4, // 苟 + 0x82D2, KANJI_LEVEL4, // 苒 + 0x82F4, KANJI_LEVEL4, // 苎 + 0x82F3, KANJI_LEVEL4, // 苳 + 0x82FA, KANJI_LEVEL4, // 苺 + 0x8393, KANJI_LEVEL4, // 莓 + 0x8303, KANJI_LEVEL4, // 范 + 0x82FB, KANJI_LEVEL4, // 苻 + 0x82F9, KANJI_LEVEL4, // 苹 + 0x82DE, KANJI_LEVEL4, // 苞 + 0x8306, KANJI_LEVEL4, // 茆 + 0x82DC, KANJI_LEVEL4, // 苜 + 0x8309, KANJI_LEVEL4, // 茉 + 0x82D9, KANJI_LEVEL4, // 苙 + 0x8335, KANJI_LEVEL4, // 茵 + 0x8334, KANJI_LEVEL4, // 茎 + 0x8316, KANJI_LEVEL4, // 茖 + 0x8332, KANJI_LEVEL4, // 茲 + 0x8331, KANJI_LEVEL4, // 茱 + 0x8340, KANJI_LEVEL4, // 荀 + 0x8339, KANJI_LEVEL4, // 茹 + 0x8350, KANJI_LEVEL4, // 荐 + 0x8345, KANJI_LEVEL4, // 荅 + 0x832F, KANJI_LEVEL4, // 茯 + 0x832B, KANJI_LEVEL4, // 茫 + 0x8317, KANJI_LEVEL4, // 茗 + 0x8318, KANJI_LEVEL4, // 茘 + 0x8385, KANJI_LEVEL4, // 莅 + 0x839A, KANJI_LEVEL4, // 莚 + 0x83AA, KANJI_LEVEL4, // 莪 + 0x839F, KANJI_LEVEL4, // 莟 + 0x83A2, KANJI_LEVEL4, // 莢 + 0x8396, KANJI_LEVEL4, // 莖 + 0x8323, KANJI_LEVEL4, // 茣 + 0x838E, KANJI_LEVEL4, // 莎 + 0x8387, KANJI_LEVEL4, // 莇 + 0x838A, KANJI_LEVEL4, // 莊 + 0x837C, KANJI_LEVEL4, // 荌 + 0x83B5, KANJI_LEVEL4, // 莵 + 0x8373, KANJI_LEVEL4, // 荳 + 0x8375, KANJI_LEVEL4, // 荵 + 0x83A0, KANJI_LEVEL4, // 莠 + 0x8389, KANJI_LEVEL4, // 莉 + 0x83A8, KANJI_LEVEL4, // 莚 + 0x83F4, KANJI_LEVEL4, // 菎 + 0x8413, KANJI_LEVEL4, // 萓 + 0x83EB, KANJI_LEVEL4, // 菫 + 0x83CE, KANJI_LEVEL4, // 菎 + 0x83FD, KANJI_LEVEL4, // 菜 + 0x8403, KANJI_LEVEL4, // 萃 + 0x83D8, KANJI_LEVEL4, // 菘 + 0x840B, KANJI_LEVEL4, // 萋 + 0x83C1, KANJI_LEVEL4, // 菁 + 0x83F7, KANJI_LEVEL4, // 菷 + 0x8407, KANJI_LEVEL4, // 萇 + 0x83E0, KANJI_LEVEL4, // 菠 + 0x83F2, KANJI_LEVEL4, // 菲 + 0x840D, KANJI_LEVEL4, // 萍 + 0x8422, KANJI_LEVEL4, // 萢 + 0x8420, KANJI_LEVEL4, // 萠 + 0x83BD, KANJI_LEVEL4, // 莜 + 0x8438, KANJI_LEVEL4, // 萞 + 0x8506, KANJI_LEVEL4, // 蔆 + 0x83FB, KANJI_LEVEL4, // 菻 + 0x846D, KANJI_LEVEL4, // 葭 + 0x842A, KANJI_LEVEL4, // 萪 + 0x843C, KANJI_LEVEL4, // 萌 + 0x855A, KANJI_LEVEL4, // 蕚 + 0x8484, KANJI_LEVEL4, // 蒄 + 0x8477, KANJI_LEVEL4, // 葷 + 0x846B, KANJI_LEVEL4, // 葫 + 0x84AD, KANJI_LEVEL4, // 蒭 + 0x846E, KANJI_LEVEL4, // 葮 + 0x8482, KANJI_LEVEL4, // 蒂 + 0x8469, KANJI_LEVEL4, // 葩 + 0x8446, KANJI_LEVEL4, // 葆 + 0x842C, KANJI_LEVEL4, // 萬 + 0x846F, KANJI_LEVEL4, // 葯 + 0x8479, KANJI_LEVEL4, // 葹 + 0x8435, KANJI_LEVEL4, // 萵 + 0x84CA, KANJI_LEVEL4, // 蓊 + 0x8462, KANJI_LEVEL4, // 葢 + 0x84B9, KANJI_LEVEL4, // 蒹 + 0x84BF, KANJI_LEVEL4, // 蒿 + 0x849F, KANJI_LEVEL4, // 蒟 + 0x84D9, KANJI_LEVEL4, // 蓙 + 0x84CD, KANJI_LEVEL4, // 蓍 + 0x84BB, KANJI_LEVEL4, // 蒻 + 0x84DA, KANJI_LEVEL4, // 蓚 + 0x84D0, KANJI_LEVEL4, // 蓐 + 0x84C1, KANJI_LEVEL4, // 蓁 + 0x84C6, KANJI_LEVEL4, // 蓆 + 0x84D6, KANJI_LEVEL4, // 蓖 + 0x84A1, KANJI_LEVEL4, // 蒡 + 0x8521, KANJI_LEVEL4, // 蔡 + 0x84FF, KANJI_LEVEL4, // 蓿 + 0x84F4, KANJI_LEVEL4, // 蓎 + 0x8517, KANJI_LEVEL4, // 蔗 + 0x8518, KANJI_LEVEL4, // 蔘 + 0x852C, KANJI_LEVEL4, // 蔬 + 0x851F, KANJI_LEVEL4, // 蔟 + 0x8515, KANJI_LEVEL4, // 蔕 + 0x8514, KANJI_LEVEL4, // 蔔 + 0x84FC, KANJI_LEVEL4, // 蓌 + 0x8540, KANJI_LEVEL4, // 蕀 + 0x8563, KANJI_LEVEL4, // 蕣 + 0x8558, KANJI_LEVEL4, // 蕘 + 0x8548, KANJI_LEVEL4, // 蕈 + 0x8541, KANJI_LEVEL4, // 蕁 + 0x8602, KANJI_LEVEL4, // 蘂 + 0x854B, KANJI_LEVEL4, // 蕋 + 0x8555, KANJI_LEVEL4, // 蕕 + 0x8580, KANJI_LEVEL4, // 薀 + 0x85A4, KANJI_LEVEL4, // è–€ + 0x8588, KANJI_LEVEL4, // 薈 + 0x8591, KANJI_LEVEL4, // 薑 + 0x858A, KANJI_LEVEL4, // 薊 + 0x85A8, KANJI_LEVEL4, // è–š + 0x856D, KANJI_LEVEL4, // 蕭 + 0x8594, KANJI_LEVEL4, // 薔 + 0x859B, KANJI_LEVEL4, // 薛 + 0x85EA, KANJI_LEVEL4, // 藪 + 0x8587, KANJI_LEVEL4, // 薇 + 0x859C, KANJI_LEVEL4, // 薜 + 0x8577, KANJI_LEVEL4, // 蕷 + 0x857E, KANJI_LEVEL4, // 蕟 + 0x8590, KANJI_LEVEL4, // 薐 + 0x85C9, KANJI_LEVEL4, // 藉 + 0x85BA, KANJI_LEVEL4, // 薺 + 0x85CF, KANJI_LEVEL4, // 藏 + 0x85B9, KANJI_LEVEL4, // 薹 + 0x85D0, KANJI_LEVEL4, // 藐 + 0x85D5, KANJI_LEVEL4, // 藕 + 0x85DD, KANJI_LEVEL4, // 藝 + 0x85E5, KANJI_LEVEL4, // 藥 + 0x85DC, KANJI_LEVEL4, // 藜 + 0x85F9, KANJI_LEVEL4, // 藹 + 0x860A, KANJI_LEVEL4, // 蘊 + 0x8613, KANJI_LEVEL4, // 蘓 + 0x860B, KANJI_LEVEL4, // 蘋 + 0x85FE, KANJI_LEVEL4, // è—Ÿ + 0x85FA, KANJI_LEVEL4, // 藺 + 0x8606, KANJI_LEVEL4, // 蘆 + 0x8622, KANJI_LEVEL4, // 蘢 + 0x861A, KANJI_LEVEL4, // 蘚 + 0x8630, KANJI_LEVEL4, // 蘰 + 0x863F, KANJI_LEVEL4, // 蘿 + 0x864D, KANJI_LEVEL4, // 虍 + 0x4E55, KANJI_LEVEL4, // 乕 + 0x8654, KANJI_LEVEL4, // 虔 + 0x865F, KANJI_LEVEL4, // 號 + 0x8667, KANJI_LEVEL4, // 虧 + 0x8671, KANJI_LEVEL4, // 虱 + 0x8693, KANJI_LEVEL4, // 蚓 + 0x86A3, KANJI_LEVEL4, // 蚣 + 0x86A9, KANJI_LEVEL4, // 蚩 + 0x86AA, KANJI_LEVEL4, // 蚪 + 0x868B, KANJI_LEVEL4, // 蚋 + 0x868C, KANJI_LEVEL4, // 蚌 + 0x86B6, KANJI_LEVEL4, // 蚶 + 0x86AF, KANJI_LEVEL4, // 蚯 + 0x86C4, KANJI_LEVEL4, // 蛄 + 0x86C6, KANJI_LEVEL4, // 蛆 + 0x86B0, KANJI_LEVEL4, // 蚰 + 0x86C9, KANJI_LEVEL4, // 蛉 + 0x8823, KANJI_LEVEL4, // è £ + 0x86AB, KANJI_LEVEL4, // 蚫 + 0x86D4, KANJI_LEVEL4, // 蛔 + 0x86DE, KANJI_LEVEL4, // 蛞 + 0x86E9, KANJI_LEVEL4, // 蛩 + 0x86EC, KANJI_LEVEL4, // 蛬 + 0x86DF, KANJI_LEVEL4, // 蛟 + 0x86DB, KANJI_LEVEL4, // 蛛 + 0x86EF, KANJI_LEVEL4, // 蛯 + 0x8712, KANJI_LEVEL4, // 蜒 + 0x8706, KANJI_LEVEL4, // 蜆 + 0x8708, KANJI_LEVEL4, // 蜈 + 0x8700, KANJI_LEVEL4, // 蜀 + 0x8703, KANJI_LEVEL4, // 蜃 + 0x86FB, KANJI_LEVEL4, // 蛻 + 0x8711, KANJI_LEVEL4, // 蜑 + 0x8709, KANJI_LEVEL4, // 蜉 + 0x870D, KANJI_LEVEL4, // 蜍 + 0x86F9, KANJI_LEVEL4, // 蛹 + 0x870A, KANJI_LEVEL4, // 蜊 + 0x8734, KANJI_LEVEL4, // 蜎 + 0x873F, KANJI_LEVEL4, // 蜿 + 0x8737, KANJI_LEVEL4, // 蜷 + 0x873B, KANJI_LEVEL4, // 蜻 + 0x8725, KANJI_LEVEL4, // 蜥 + 0x8729, KANJI_LEVEL4, // 蜩 + 0x871A, KANJI_LEVEL4, // 蜚 + 0x8760, KANJI_LEVEL4, // 蝠 + 0x875F, KANJI_LEVEL4, // 蝟 + 0x8778, KANJI_LEVEL4, // 蝞 + 0x874C, KANJI_LEVEL4, // 蝌 + 0x874E, KANJI_LEVEL4, // 蝎 + 0x8774, KANJI_LEVEL4, // 蝎 + 0x8757, KANJI_LEVEL4, // 蝗 + 0x8768, KANJI_LEVEL4, // 蝚 + 0x876E, KANJI_LEVEL4, // 蝮 + 0x8759, KANJI_LEVEL4, // 蝙 + 0x8753, KANJI_LEVEL4, // 蝓 + 0x8763, KANJI_LEVEL4, // 蝣 + 0x876A, KANJI_LEVEL4, // 蝪 + 0x8805, KANJI_LEVEL4, // 蠅 + 0x87A2, KANJI_LEVEL4, // 螢 + 0x879F, KANJI_LEVEL4, // 螟 + 0x8782, KANJI_LEVEL4, // 螂 + 0x87AF, KANJI_LEVEL4, // 螯 + 0x87CB, KANJI_LEVEL4, // 蟋 + 0x87BD, KANJI_LEVEL4, // 螜 + 0x87C0, KANJI_LEVEL4, // 蟀 + 0x87D0, KANJI_LEVEL4, // 蟐 + 0x96D6, KANJI_LEVEL4, // 雖 + 0x87AB, KANJI_LEVEL4, // 螫 + 0x87C4, KANJI_LEVEL4, // 蟄 + 0x87B3, KANJI_LEVEL4, // 螳 + 0x87C7, KANJI_LEVEL4, // 蟇 + 0x87C6, KANJI_LEVEL4, // 蟆 + 0x87BB, KANJI_LEVEL4, // 螻 + 0x87EF, KANJI_LEVEL4, // 蟯 + 0x87F2, KANJI_LEVEL4, // 蟲 + 0x87E0, KANJI_LEVEL4, // 蟠 + 0x880F, KANJI_LEVEL4, // 蠏 + 0x880D, KANJI_LEVEL4, // 蠍 + 0x87FE, KANJI_LEVEL4, // 蟟 + 0x87F6, KANJI_LEVEL4, // 蟶 + 0x87F7, KANJI_LEVEL4, // 蟷 + 0x880E, KANJI_LEVEL4, // 蠎 + 0x87D2, KANJI_LEVEL4, // 蟒 + 0x8811, KANJI_LEVEL4, // 蠑 + 0x8816, KANJI_LEVEL4, // 蠖 + 0x8815, KANJI_LEVEL4, // 蠕 + 0x8822, KANJI_LEVEL4, // è ¢ + 0x8821, KANJI_LEVEL4, // è ¡ + 0x8831, KANJI_LEVEL4, // è ± + 0x8836, KANJI_LEVEL4, // è ¶ + 0x8839, KANJI_LEVEL4, // è ¹ + 0x8827, KANJI_LEVEL4, // è § + 0x883B, KANJI_LEVEL4, // è » + 0x8844, KANJI_LEVEL4, // 衄 + 0x8842, KANJI_LEVEL4, // 衂 + 0x8852, KANJI_LEVEL4, // 衒 + 0x8859, KANJI_LEVEL4, // 衙 + 0x885E, KANJI_LEVEL4, // 衞 + 0x8862, KANJI_LEVEL4, // è¡¢ + 0x886B, KANJI_LEVEL4, // è¡« + 0x8881, KANJI_LEVEL4, // 袁 + 0x887E, KANJI_LEVEL4, // 衟 + 0x889E, KANJI_LEVEL4, // 袞 + 0x8875, KANJI_LEVEL4, // 衵 + 0x887D, KANJI_LEVEL4, // 衜 + 0x88B5, KANJI_LEVEL4, // 袵 + 0x8872, KANJI_LEVEL4, // 衲 + 0x8882, KANJI_LEVEL4, // 袂 + 0x8897, KANJI_LEVEL4, // 袗 + 0x8892, KANJI_LEVEL4, // 袒 + 0x88AE, KANJI_LEVEL4, // 袮 + 0x8899, KANJI_LEVEL4, // 袙 + 0x88A2, KANJI_LEVEL4, // 袢 + 0x888D, KANJI_LEVEL4, // 袍 + 0x88A4, KANJI_LEVEL4, // 袀 + 0x88B0, KANJI_LEVEL4, // 袰 + 0x88BF, KANJI_LEVEL4, // 袿 + 0x88B1, KANJI_LEVEL4, // 袱 + 0x88C3, KANJI_LEVEL4, // 裃 + 0x88C4, KANJI_LEVEL4, // 裄 + 0x88D4, KANJI_LEVEL4, // 裔 + 0x88D8, KANJI_LEVEL4, // 裘 + 0x88D9, KANJI_LEVEL4, // 裙 + 0x88DD, KANJI_LEVEL4, // 裝 + 0x88F9, KANJI_LEVEL4, // 裹 + 0x8902, KANJI_LEVEL4, // 耂 + 0x88FC, KANJI_LEVEL4, // 裌 + 0x88F4, KANJI_LEVEL4, // 裎 + 0x88E8, KANJI_LEVEL4, // 裚 + 0x88F2, KANJI_LEVEL4, // 裲 + 0x8904, KANJI_LEVEL4, // 耄 + 0x890C, KANJI_LEVEL4, // 而 + 0x890A, KANJI_LEVEL4, // 耊 + 0x8913, KANJI_LEVEL4, // 耓 + 0x8943, KANJI_LEVEL4, // 襃 + 0x891E, KANJI_LEVEL4, // 耞 + 0x8925, KANJI_LEVEL4, // 耥 + 0x892A, KANJI_LEVEL4, // 耪 + 0x892B, KANJI_LEVEL4, // 耫 + 0x8941, KANJI_LEVEL4, // 襁 + 0x8944, KANJI_LEVEL4, // 襄 + 0x893B, KANJI_LEVEL4, // 耻 + 0x8936, KANJI_LEVEL4, // 耶 + 0x8938, KANJI_LEVEL4, // 耞 + 0x894C, KANJI_LEVEL4, // 襌 + 0x891D, KANJI_LEVEL4, // 耝 + 0x8960, KANJI_LEVEL4, // 襠 + 0x895E, KANJI_LEVEL4, // 襞 + 0x8966, KANJI_LEVEL4, // 襊 + 0x8964, KANJI_LEVEL4, // 襀 + 0x896D, KANJI_LEVEL4, // 襭 + 0x896A, KANJI_LEVEL4, // 襪 + 0x896F, KANJI_LEVEL4, // 襯 + 0x8974, KANJI_LEVEL4, // 襎 + 0x8977, KANJI_LEVEL4, // 襷 + 0x897E, KANJI_LEVEL4, // 襟 + 0x8983, KANJI_LEVEL4, // 芃 + 0x8988, KANJI_LEVEL4, // 芈 + 0x898A, KANJI_LEVEL4, // 芊 + 0x8993, KANJI_LEVEL4, // 芓 + 0x8998, KANJI_LEVEL4, // 芘 + 0x89A1, KANJI_LEVEL4, // 芡 + 0x89A9, KANJI_LEVEL4, // 芩 + 0x89A6, KANJI_LEVEL4, // 芊 + 0x89AC, KANJI_LEVEL4, // 芬 + 0x89AF, KANJI_LEVEL4, // 芯 + 0x89B2, KANJI_LEVEL4, // 芲 + 0x89BA, KANJI_LEVEL4, // 芺 + 0x89BD, KANJI_LEVEL4, // 芜 + 0x89BF, KANJI_LEVEL4, // 芿 + 0x89C0, KANJI_LEVEL4, // 觀 + 0x89DA, KANJI_LEVEL4, // 觚 + 0x89DC, KANJI_LEVEL4, // 觜 + 0x89DD, KANJI_LEVEL4, // 觝 + 0x89E7, KANJI_LEVEL4, // è§§ + 0x89F4, KANJI_LEVEL4, // è§Ž + 0x89F8, KANJI_LEVEL4, // è§ž + 0x8A03, KANJI_LEVEL4, // 蚃 + 0x8A16, KANJI_LEVEL4, // èš– + 0x8A10, KANJI_LEVEL4, // 蚐 + 0x8A0C, KANJI_LEVEL4, // 蚌 + 0x8A1B, KANJI_LEVEL4, // èš› + 0x8A1D, KANJI_LEVEL4, // 蚝 + 0x8A25, KANJI_LEVEL4, // 蚥 + 0x8A36, KANJI_LEVEL4, // èš¶ + 0x8A41, KANJI_LEVEL4, // 詁 + 0x8A5B, KANJI_LEVEL4, // 詛 + 0x8A52, KANJI_LEVEL4, // 詒 + 0x8A46, KANJI_LEVEL4, // 詆 + 0x8A48, KANJI_LEVEL4, // 詈 + 0x8A7C, KANJI_LEVEL4, // 詌 + 0x8A6D, KANJI_LEVEL4, // è©­ + 0x8A6C, KANJI_LEVEL4, // 詬 + 0x8A62, KANJI_LEVEL4, // è©¢ + 0x8A85, KANJI_LEVEL4, // 誅 + 0x8A82, KANJI_LEVEL4, // 誂 + 0x8A84, KANJI_LEVEL4, // 誄 + 0x8AA8, KANJI_LEVEL4, // 誚 + 0x8AA1, KANJI_LEVEL4, // 誡 + 0x8A91, KANJI_LEVEL4, // 誑 + 0x8AA5, KANJI_LEVEL4, // 誥 + 0x8AA6, KANJI_LEVEL4, // 誊 + 0x8A9A, KANJI_LEVEL4, // 誚 + 0x8AA3, KANJI_LEVEL4, // 誣 + 0x8AC4, KANJI_LEVEL4, // 諄 + 0x8ACD, KANJI_LEVEL4, // 諍 + 0x8AC2, KANJI_LEVEL4, // 諂 + 0x8ADA, KANJI_LEVEL4, // 諚 + 0x8AEB, KANJI_LEVEL4, // è«« + 0x8AF3, KANJI_LEVEL4, // 諳 + 0x8AE7, KANJI_LEVEL4, // è«§ + 0x8AE4, KANJI_LEVEL4, // è«€ + 0x8AF1, KANJI_LEVEL4, // 諱 + 0x8B14, KANJI_LEVEL4, // 謔 + 0x8AE0, KANJI_LEVEL4, // è«  + 0x8AE2, KANJI_LEVEL4, // è«¢ + 0x8AF7, KANJI_LEVEL4, // è«· + 0x8ADE, KANJI_LEVEL4, // 諞 + 0x8ADB, KANJI_LEVEL4, // 諛 + 0x8B0C, KANJI_LEVEL4, // 謌 + 0x8B07, KANJI_LEVEL4, // 謇 + 0x8B1A, KANJI_LEVEL4, // 謚 + 0x8AE1, KANJI_LEVEL4, // è«¡ + 0x8B16, KANJI_LEVEL4, // 謖 + 0x8B10, KANJI_LEVEL4, // 謐 + 0x8B17, KANJI_LEVEL4, // 謗 + 0x8B20, KANJI_LEVEL4, // 謠 + 0x8B33, KANJI_LEVEL4, // 謳 + 0x97AB, KANJI_LEVEL4, // 鞫 + 0x8B26, KANJI_LEVEL4, // 謊 + 0x8B2B, KANJI_LEVEL4, // 謫 + 0x8B3E, KANJI_LEVEL4, // 謟 + 0x8B28, KANJI_LEVEL4, // 謚 + 0x8B41, KANJI_LEVEL4, // 譁 + 0x8B4C, KANJI_LEVEL4, // 譌 + 0x8B4F, KANJI_LEVEL4, // 譏 + 0x8B4E, KANJI_LEVEL4, // 譎 + 0x8B49, KANJI_LEVEL4, // 證 + 0x8B56, KANJI_LEVEL4, // 譖 + 0x8B5B, KANJI_LEVEL4, // 譛 + 0x8B5A, KANJI_LEVEL4, // 譚 + 0x8B6B, KANJI_LEVEL4, // è­« + 0x8B5F, KANJI_LEVEL4, // 譟 + 0x8B6C, KANJI_LEVEL4, // è­¬ + 0x8B6F, KANJI_LEVEL4, // è­¯ + 0x8B74, KANJI_LEVEL4, // è­Ž + 0x8B7D, KANJI_LEVEL4, // è­œ + 0x8B80, KANJI_LEVEL4, // 讀 + 0x8B8C, KANJI_LEVEL4, // 讌 + 0x8B8E, KANJI_LEVEL4, // 讎 + 0x8B92, KANJI_LEVEL4, // 讒 + 0x8B93, KANJI_LEVEL4, // 讓 + 0x8B96, KANJI_LEVEL4, // 讖 + 0x8B99, KANJI_LEVEL4, // 讙 + 0x8B9A, KANJI_LEVEL4, // 讚 + 0x8C3A, KANJI_LEVEL4, // è°º + 0x8C41, KANJI_LEVEL4, // 豁 + 0x8C3F, KANJI_LEVEL4, // è°¿ + 0x8C48, KANJI_LEVEL4, // 豈 + 0x8C4C, KANJI_LEVEL4, // 豌 + 0x8C4E, KANJI_LEVEL4, // 豎 + 0x8C50, KANJI_LEVEL4, // 豐 + 0x8C55, KANJI_LEVEL4, // 豕 + 0x8C62, KANJI_LEVEL4, // è±¢ + 0x8C6C, KANJI_LEVEL4, // 豬 + 0x8C78, KANJI_LEVEL4, // 豞 + 0x8C7A, KANJI_LEVEL4, // 豺 + 0x8C82, KANJI_LEVEL4, // 貂 + 0x8C89, KANJI_LEVEL4, // 貉 + 0x8C85, KANJI_LEVEL4, // 貅 + 0x8C8A, KANJI_LEVEL4, // 貊 + 0x8C8D, KANJI_LEVEL4, // 貍 + 0x8C8E, KANJI_LEVEL4, // 貎 + 0x8C94, KANJI_LEVEL4, // 貔 + 0x8C7C, KANJI_LEVEL4, // 豌 + 0x8C98, KANJI_LEVEL4, // 貘 + 0x621D, KANJI_LEVEL4, // 戝 + 0x8CAD, KANJI_LEVEL4, // è²­ + 0x8CAA, KANJI_LEVEL4, // 貪 + 0x8CBD, KANJI_LEVEL4, // 貜 + 0x8CB2, KANJI_LEVEL4, // è²² + 0x8CB3, KANJI_LEVEL4, // è²³ + 0x8CAE, KANJI_LEVEL4, // è²® + 0x8CB6, KANJI_LEVEL4, // è²¶ + 0x8CC8, KANJI_LEVEL4, // 賈 + 0x8CC1, KANJI_LEVEL4, // 賁 + 0x8CE4, KANJI_LEVEL4, // è³€ + 0x8CE3, KANJI_LEVEL4, // è³£ + 0x8CDA, KANJI_LEVEL4, // 賚 + 0x8CFD, KANJI_LEVEL4, // 賜 + 0x8CFA, KANJI_LEVEL4, // 賺 + 0x8CFB, KANJI_LEVEL4, // è³» + 0x8D04, KANJI_LEVEL4, // 莄 + 0x8D05, KANJI_LEVEL4, // 莅 + 0x8D0A, KANJI_LEVEL4, // 莊 + 0x8D07, KANJI_LEVEL4, // 莇 + 0x8D0F, KANJI_LEVEL4, // 莏 + 0x8D0D, KANJI_LEVEL4, // 莍 + 0x8D10, KANJI_LEVEL4, // 莐 + 0x9F4E, KANJI_LEVEL4, // 霎 + 0x8D13, KANJI_LEVEL4, // 莓 + 0x8CCD, KANJI_LEVEL4, // 賍 + 0x8D14, KANJI_LEVEL4, // 莔 + 0x8D16, KANJI_LEVEL4, // 莖 + 0x8D67, KANJI_LEVEL4, // èµ§ + 0x8D6D, KANJI_LEVEL4, // èµ­ + 0x8D71, KANJI_LEVEL4, // èµ± + 0x8D73, KANJI_LEVEL4, // èµ³ + 0x8D81, KANJI_LEVEL4, // 趁 + 0x8D99, KANJI_LEVEL4, // 趙 + 0x8DC2, KANJI_LEVEL4, // 跂 + 0x8DBE, KANJI_LEVEL4, // è¶Ÿ + 0x8DBA, KANJI_LEVEL4, // 趺 + 0x8DCF, KANJI_LEVEL4, // 跏 + 0x8DDA, KANJI_LEVEL4, // 跚 + 0x8DD6, KANJI_LEVEL4, // 跖 + 0x8DCC, KANJI_LEVEL4, // 跌 + 0x8DDB, KANJI_LEVEL4, // 跛 + 0x8DCB, KANJI_LEVEL4, // 跋 + 0x8DEA, KANJI_LEVEL4, // è·ª + 0x8DEB, KANJI_LEVEL4, // è·« + 0x8DDF, KANJI_LEVEL4, // 跟 + 0x8DE3, KANJI_LEVEL4, // è·£ + 0x8DFC, KANJI_LEVEL4, // è·Œ + 0x8E08, KANJI_LEVEL4, // 螈 + 0x8E09, KANJI_LEVEL4, // 螉 + 0x8DFF, KANJI_LEVEL4, // è·¿ + 0x8E1D, KANJI_LEVEL4, // 螝 + 0x8E1E, KANJI_LEVEL4, // èžž + 0x8E10, KANJI_LEVEL4, // 螐 + 0x8E1F, KANJI_LEVEL4, // 螟 + 0x8E42, KANJI_LEVEL4, // 蹂 + 0x8E35, KANJI_LEVEL4, // èžµ + 0x8E30, KANJI_LEVEL4, // èž° + 0x8E34, KANJI_LEVEL4, // 螎 + 0x8E4A, KANJI_LEVEL4, // 蹊 + 0x8E47, KANJI_LEVEL4, // 蹇 + 0x8E49, KANJI_LEVEL4, // 蹉 + 0x8E4C, KANJI_LEVEL4, // 蹌 + 0x8E50, KANJI_LEVEL4, // 蹐 + 0x8E48, KANJI_LEVEL4, // 蹈 + 0x8E59, KANJI_LEVEL4, // 蹙 + 0x8E64, KANJI_LEVEL4, // è¹€ + 0x8E60, KANJI_LEVEL4, // è¹  + 0x8E2A, KANJI_LEVEL4, // 螪 + 0x8E63, KANJI_LEVEL4, // è¹£ + 0x8E55, KANJI_LEVEL4, // 蹕 + 0x8E76, KANJI_LEVEL4, // è¹¶ + 0x8E72, KANJI_LEVEL4, // è¹² + 0x8E7C, KANJI_LEVEL4, // 蹌 + 0x8E81, KANJI_LEVEL4, // 躁 + 0x8E87, KANJI_LEVEL4, // 躇 + 0x8E85, KANJI_LEVEL4, // 躅 + 0x8E84, KANJI_LEVEL4, // 躄 + 0x8E8B, KANJI_LEVEL4, // 躋 + 0x8E8A, KANJI_LEVEL4, // 躊 + 0x8E93, KANJI_LEVEL4, // 躓 + 0x8E91, KANJI_LEVEL4, // 躑 + 0x8E94, KANJI_LEVEL4, // 躔 + 0x8E99, KANJI_LEVEL4, // 躙 + 0x8EAA, KANJI_LEVEL4, // 躪 + 0x8EA1, KANJI_LEVEL4, // 躡 + 0x8EAC, KANJI_LEVEL4, // 躬 + 0x8EB0, KANJI_LEVEL4, // 躰 + 0x8EC6, KANJI_LEVEL4, // 軆 + 0x8EB1, KANJI_LEVEL4, // 躱 + 0x8EBE, KANJI_LEVEL4, // 躟 + 0x8EC5, KANJI_LEVEL4, // 軅 + 0x8EC8, KANJI_LEVEL4, // 軈 + 0x8ECB, KANJI_LEVEL4, // 軋 + 0x8EDB, KANJI_LEVEL4, // 軛 + 0x8EE3, KANJI_LEVEL4, // 軣 + 0x8EFC, KANJI_LEVEL4, // 軌 + 0x8EFB, KANJI_LEVEL4, // è»» + 0x8EEB, KANJI_LEVEL4, // 軫 + 0x8EFE, KANJI_LEVEL4, // 軟 + 0x8F0A, KANJI_LEVEL4, // 茊 + 0x8F05, KANJI_LEVEL4, // 茅 + 0x8F15, KANJI_LEVEL4, // 茕 + 0x8F12, KANJI_LEVEL4, // 茒 + 0x8F19, KANJI_LEVEL4, // 茙 + 0x8F13, KANJI_LEVEL4, // 茓 + 0x8F1C, KANJI_LEVEL4, // 茜 + 0x8F1F, KANJI_LEVEL4, // 茟 + 0x8F1B, KANJI_LEVEL4, // 茛 + 0x8F0C, KANJI_LEVEL4, // 茌 + 0x8F26, KANJI_LEVEL4, // 茊 + 0x8F33, KANJI_LEVEL4, // 茳 + 0x8F3B, KANJI_LEVEL4, // 茻 + 0x8F39, KANJI_LEVEL4, // 茹 + 0x8F45, KANJI_LEVEL4, // 蜅 + 0x8F42, KANJI_LEVEL4, // 蜂 + 0x8F3E, KANJI_LEVEL4, // 茟 + 0x8F4C, KANJI_LEVEL4, // 蜌 + 0x8F49, KANJI_LEVEL4, // 蜉 + 0x8F46, KANJI_LEVEL4, // 蜆 + 0x8F4E, KANJI_LEVEL4, // 蜎 + 0x8F57, KANJI_LEVEL4, // 蜗 + 0x8F5C, KANJI_LEVEL4, // 蜜 + 0x8F62, KANJI_LEVEL4, // 蜢 + 0x8F63, KANJI_LEVEL4, // 蜣 + 0x8F64, KANJI_LEVEL4, // 蜀 + 0x8F9C, KANJI_LEVEL4, // 蟜 + 0x8F9F, KANJI_LEVEL4, // 蟟 + 0x8FA3, KANJI_LEVEL4, // 蟣 + 0x8FAD, KANJI_LEVEL4, // 蟭 + 0x8FAF, KANJI_LEVEL4, // 蟯 + 0x8FB7, KANJI_LEVEL4, // 蟷 + 0x8FDA, KANJI_LEVEL4, // 迚 + 0x8FE5, KANJI_LEVEL4, // è¿¥ + 0x8FE2, KANJI_LEVEL4, // è¿¢ + 0x8FEA, KANJI_LEVEL4, // 迪 + 0x8FEF, KANJI_LEVEL4, // 迯 + 0x9087, KANJI_LEVEL4, // 邇 + 0x8FF4, KANJI_LEVEL4, // 迎 + 0x9005, KANJI_LEVEL4, // 逅 + 0x8FF9, KANJI_LEVEL4, // 迹 + 0x8FFA, KANJI_LEVEL4, // 迺 + 0x9011, KANJI_LEVEL4, // 逑 + 0x9015, KANJI_LEVEL4, // 逕 + 0x9021, KANJI_LEVEL4, // 逡 + 0x900D, KANJI_LEVEL4, // 逍 + 0x901E, KANJI_LEVEL4, // 逞 + 0x9016, KANJI_LEVEL4, // 逖 + 0x900B, KANJI_LEVEL4, // 逋 + 0x9027, KANJI_LEVEL4, // 逧 + 0x9036, KANJI_LEVEL4, // 逶 + 0x9035, KANJI_LEVEL4, // 逵 + 0x9039, KANJI_LEVEL4, // 逹 + 0x8FF8, KANJI_LEVEL4, // 连 + 0x904F, KANJI_LEVEL4, // 遏 + 0x9050, KANJI_LEVEL4, // 遐 + 0x9051, KANJI_LEVEL4, // 遑 + 0x9052, KANJI_LEVEL4, // 遒 + 0x900E, KANJI_LEVEL4, // 逎 + 0x9049, KANJI_LEVEL4, // 遉 + 0x903E, KANJI_LEVEL4, // 速 + 0x9056, KANJI_LEVEL4, // 遖 + 0x9058, KANJI_LEVEL4, // 遘 + 0x905E, KANJI_LEVEL4, // 遞 + 0x9068, KANJI_LEVEL4, // 遚 + 0x906F, KANJI_LEVEL4, // 遯 + 0x9076, KANJI_LEVEL4, // 遶 + 0x96A8, KANJI_LEVEL4, // 隹 + 0x9072, KANJI_LEVEL4, // 遲 + 0x9082, KANJI_LEVEL4, // 邂 + 0x907D, KANJI_LEVEL4, // 遜 + 0x9081, KANJI_LEVEL4, // 邁 + 0x9080, KANJI_LEVEL4, // 邀 + 0x908A, KANJI_LEVEL4, // 邊 + 0x9089, KANJI_LEVEL4, // 邉 + 0x908F, KANJI_LEVEL4, // 邏 + 0x90A8, KANJI_LEVEL4, // 邹 + 0x90AF, KANJI_LEVEL4, // 邯 + 0x90B1, KANJI_LEVEL4, // 邱 + 0x90B5, KANJI_LEVEL4, // 邵 + 0x90E2, KANJI_LEVEL4, // 郢 + 0x90E4, KANJI_LEVEL4, // 郀 + 0x6248, KANJI_LEVEL4, // 扈 + 0x90DB, KANJI_LEVEL4, // 郛 + 0x9102, KANJI_LEVEL4, // 鄂 + 0x9112, KANJI_LEVEL4, // 鄒 + 0x9119, KANJI_LEVEL4, // 鄙 + 0x9132, KANJI_LEVEL4, // 鄲 + 0x9130, KANJI_LEVEL4, // 鄰 + 0x914A, KANJI_LEVEL4, // 酊 + 0x9156, KANJI_LEVEL4, // 酖 + 0x9158, KANJI_LEVEL4, // 酘 + 0x9163, KANJI_LEVEL4, // 酣 + 0x9165, KANJI_LEVEL4, // 酥 + 0x9169, KANJI_LEVEL4, // 酩 + 0x9173, KANJI_LEVEL4, // 酳 + 0x9172, KANJI_LEVEL4, // 酲 + 0x918B, KANJI_LEVEL4, // 醋 + 0x9189, KANJI_LEVEL4, // 醉 + 0x9182, KANJI_LEVEL4, // 醂 + 0x91A2, KANJI_LEVEL4, // 醢 + 0x91AB, KANJI_LEVEL4, // 醫 + 0x91AF, KANJI_LEVEL4, // 醯 + 0x91AA, KANJI_LEVEL4, // 醪 + 0x91B5, KANJI_LEVEL4, // 醵 + 0x91B4, KANJI_LEVEL4, // 醮 + 0x91BA, KANJI_LEVEL4, // 醺 + 0x91C0, KANJI_LEVEL4, // 釀 + 0x91C1, KANJI_LEVEL4, // 釁 + 0x91C9, KANJI_LEVEL4, // 釉 + 0x91CB, KANJI_LEVEL4, // 釋 + 0x91D0, KANJI_LEVEL4, // 釐 + 0x91D6, KANJI_LEVEL4, // 釖 + 0x91DF, KANJI_LEVEL4, // 釟 + 0x91E1, KANJI_LEVEL4, // 釡 + 0x91DB, KANJI_LEVEL4, // 釛 + 0x91FC, KANJI_LEVEL4, // 里 + 0x91F5, KANJI_LEVEL4, // 釵 + 0x91F6, KANJI_LEVEL4, // 釶 + 0x921E, KANJI_LEVEL4, // 鈞 + 0x91FF, KANJI_LEVEL4, // 釿 + 0x9214, KANJI_LEVEL4, // 鈔 + 0x922C, KANJI_LEVEL4, // 鈬 + 0x9215, KANJI_LEVEL4, // 鈕 + 0x9211, KANJI_LEVEL4, // 鈑 + 0x925E, KANJI_LEVEL4, // 鉞 + 0x9257, KANJI_LEVEL4, // 鉗 + 0x9245, KANJI_LEVEL4, // 鉅 + 0x9249, KANJI_LEVEL4, // 鉉 + 0x9264, KANJI_LEVEL4, // 鉀 + 0x9248, KANJI_LEVEL4, // 鉈 + 0x9295, KANJI_LEVEL4, // 銕 + 0x923F, KANJI_LEVEL4, // 鈿 + 0x924B, KANJI_LEVEL4, // 鉋 + 0x9250, KANJI_LEVEL4, // 鉐 + 0x929C, KANJI_LEVEL4, // 銜 + 0x9296, KANJI_LEVEL4, // 銖 + 0x9293, KANJI_LEVEL4, // 銓 + 0x929B, KANJI_LEVEL4, // 銛 + 0x925A, KANJI_LEVEL4, // 鉚 + 0x92CF, KANJI_LEVEL4, // 鋏 + 0x92B9, KANJI_LEVEL4, // 銹 + 0x92B7, KANJI_LEVEL4, // 銷 + 0x92E9, KANJI_LEVEL4, // 鋩 + 0x930F, KANJI_LEVEL4, // 錏 + 0x92FA, KANJI_LEVEL4, // 鋺 + 0x9344, KANJI_LEVEL4, // 鍄 + 0x932E, KANJI_LEVEL4, // 錮 + 0x9319, KANJI_LEVEL4, // 錙 + 0x9322, KANJI_LEVEL4, // 錢 + 0x931A, KANJI_LEVEL4, // 錚 + 0x9323, KANJI_LEVEL4, // 錣 + 0x933A, KANJI_LEVEL4, // 錺 + 0x9335, KANJI_LEVEL4, // 錵 + 0x933B, KANJI_LEVEL4, // 錻 + 0x935C, KANJI_LEVEL4, // 鍜 + 0x9360, KANJI_LEVEL4, // 鍠 + 0x937C, KANJI_LEVEL4, // 鍌 + 0x936E, KANJI_LEVEL4, // 鍮 + 0x9356, KANJI_LEVEL4, // 鍖 + 0x93B0, KANJI_LEVEL4, // 鎰 + 0x93AC, KANJI_LEVEL4, // 鎬 + 0x93AD, KANJI_LEVEL4, // 鎭 + 0x9394, KANJI_LEVEL4, // 鎔 + 0x93B9, KANJI_LEVEL4, // 鎹 + 0x93D6, KANJI_LEVEL4, // 鏖 + 0x93D7, KANJI_LEVEL4, // 鏗 + 0x93E8, KANJI_LEVEL4, // 鏚 + 0x93E5, KANJI_LEVEL4, // 鏥 + 0x93D8, KANJI_LEVEL4, // 鏘 + 0x93C3, KANJI_LEVEL4, // 鏃 + 0x93DD, KANJI_LEVEL4, // 鏝 + 0x93D0, KANJI_LEVEL4, // 鏐 + 0x93C8, KANJI_LEVEL4, // 鏈 + 0x93E4, KANJI_LEVEL4, // 鏀 + 0x941A, KANJI_LEVEL4, // 鐚 + 0x9414, KANJI_LEVEL4, // 鐔 + 0x9413, KANJI_LEVEL4, // 鐓 + 0x9403, KANJI_LEVEL4, // 鐃 + 0x9407, KANJI_LEVEL4, // 鐇 + 0x9410, KANJI_LEVEL4, // 鐐 + 0x9436, KANJI_LEVEL4, // 鐶 + 0x942B, KANJI_LEVEL4, // 鐫 + 0x9435, KANJI_LEVEL4, // 鐵 + 0x9421, KANJI_LEVEL4, // 鐡 + 0x943A, KANJI_LEVEL4, // 鐺 + 0x9441, KANJI_LEVEL4, // 鑁 + 0x9452, KANJI_LEVEL4, // 鑒 + 0x9444, KANJI_LEVEL4, // 鑄 + 0x945B, KANJI_LEVEL4, // 鑛 + 0x9460, KANJI_LEVEL4, // 鑠 + 0x9462, KANJI_LEVEL4, // 鑢 + 0x945E, KANJI_LEVEL4, // 鑞 + 0x946A, KANJI_LEVEL4, // 鑪 + 0x9229, KANJI_LEVEL4, // 鈩 + 0x9470, KANJI_LEVEL4, // 鑰 + 0x9475, KANJI_LEVEL4, // 鑵 + 0x9477, KANJI_LEVEL4, // 鑷 + 0x947D, KANJI_LEVEL4, // 鑜 + 0x945A, KANJI_LEVEL4, // 鑚 + 0x947C, KANJI_LEVEL4, // 鑌 + 0x947E, KANJI_LEVEL4, // 鑟 + 0x9481, KANJI_LEVEL4, // 钁 + 0x947F, KANJI_LEVEL4, // 鑿 + 0x9582, KANJI_LEVEL4, // 閂 + 0x9587, KANJI_LEVEL4, // 閇 + 0x958A, KANJI_LEVEL4, // 閊 + 0x9594, KANJI_LEVEL4, // 閔 + 0x9596, KANJI_LEVEL4, // 閖 + 0x9598, KANJI_LEVEL4, // 閘 + 0x9599, KANJI_LEVEL4, // 閙 + 0x95A0, KANJI_LEVEL4, // 閠 + 0x95A8, KANJI_LEVEL4, // 閹 + 0x95A7, KANJI_LEVEL4, // 閧 + 0x95AD, KANJI_LEVEL4, // 閭 + 0x95BC, KANJI_LEVEL4, // é–Œ + 0x95BB, KANJI_LEVEL4, // 閻 + 0x95B9, KANJI_LEVEL4, // 閹 + 0x95BE, KANJI_LEVEL4, // é–Ÿ + 0x95CA, KANJI_LEVEL4, // 闊 + 0x6FF6, KANJI_LEVEL4, // æ¿¶ + 0x95C3, KANJI_LEVEL4, // 闃 + 0x95CD, KANJI_LEVEL4, // 闍 + 0x95CC, KANJI_LEVEL4, // 闌 + 0x95D5, KANJI_LEVEL4, // 闕 + 0x95D4, KANJI_LEVEL4, // 闔 + 0x95D6, KANJI_LEVEL4, // 闖 + 0x95DC, KANJI_LEVEL4, // 關 + 0x95E1, KANJI_LEVEL4, // 闡 + 0x95E5, KANJI_LEVEL4, // 闥 + 0x95E2, KANJI_LEVEL4, // 闢 + 0x9621, KANJI_LEVEL4, // 阡 + 0x9628, KANJI_LEVEL4, // 阚 + 0x962E, KANJI_LEVEL4, // 阮 + 0x962F, KANJI_LEVEL4, // 阯 + 0x9642, KANJI_LEVEL4, // 陂 + 0x964C, KANJI_LEVEL4, // 陌 + 0x964F, KANJI_LEVEL4, // 陏 + 0x964B, KANJI_LEVEL4, // 陋 + 0x9677, KANJI_LEVEL4, // 陷 + 0x965C, KANJI_LEVEL4, // 陜 + 0x965E, KANJI_LEVEL4, // 陞 + 0x965D, KANJI_LEVEL4, // 陝 + 0x965F, KANJI_LEVEL4, // 陟 + 0x9666, KANJI_LEVEL4, // 险 + 0x9672, KANJI_LEVEL4, // 陲 + 0x966C, KANJI_LEVEL4, // 陬 + 0x968D, KANJI_LEVEL4, // 隍 + 0x9698, KANJI_LEVEL4, // 隘 + 0x9695, KANJI_LEVEL4, // 隕 + 0x9697, KANJI_LEVEL4, // 隗 + 0x96AA, KANJI_LEVEL4, // 險 + 0x96A7, KANJI_LEVEL4, // 隧 + 0x96B1, KANJI_LEVEL4, // 隱 + 0x96B2, KANJI_LEVEL4, // 隲 + 0x96B0, KANJI_LEVEL4, // 隰 + 0x96B4, KANJI_LEVEL4, // 隮 + 0x96B6, KANJI_LEVEL4, // 隶 + 0x96B8, KANJI_LEVEL4, // 难 + 0x96B9, KANJI_LEVEL4, // 隹 + 0x96CE, KANJI_LEVEL4, // 雎 + 0x96CB, KANJI_LEVEL4, // 雋 + 0x96C9, KANJI_LEVEL4, // 雉 + 0x96CD, KANJI_LEVEL4, // 雍 + 0x894D, KANJI_LEVEL4, // 襍 + 0x96DC, KANJI_LEVEL4, // 雜 + 0x970D, KANJI_LEVEL4, // 霍 + 0x96D5, KANJI_LEVEL4, // 雕 + 0x96F9, KANJI_LEVEL4, // 雹 + 0x9704, KANJI_LEVEL4, // 霄 + 0x9706, KANJI_LEVEL4, // 霆 + 0x9708, KANJI_LEVEL4, // 霈 + 0x9713, KANJI_LEVEL4, // 霓 + 0x970E, KANJI_LEVEL4, // 霎 + 0x9711, KANJI_LEVEL4, // 霑 + 0x970F, KANJI_LEVEL4, // 霏 + 0x9716, KANJI_LEVEL4, // 霖 + 0x9719, KANJI_LEVEL4, // 霙 + 0x9724, KANJI_LEVEL4, // 需 + 0x972A, KANJI_LEVEL4, // 霪 + 0x9730, KANJI_LEVEL4, // 霰 + 0x9739, KANJI_LEVEL4, // 霹 + 0x973D, KANJI_LEVEL4, // 霜 + 0x973E, KANJI_LEVEL4, // 霟 + 0x9744, KANJI_LEVEL4, // 靄 + 0x9746, KANJI_LEVEL4, // 靆 + 0x9748, KANJI_LEVEL4, // 靈 + 0x9742, KANJI_LEVEL4, // 靂 + 0x9749, KANJI_LEVEL4, // 靉 + 0x975C, KANJI_LEVEL4, // 靜 + 0x9760, KANJI_LEVEL4, // 靠 + 0x9764, KANJI_LEVEL4, // 靀 + 0x9766, KANJI_LEVEL4, // 靊 + 0x9768, KANJI_LEVEL4, // 靚 + 0x52D2, KANJI_LEVEL4, // 勒 + 0x976B, KANJI_LEVEL4, // 靫 + 0x9771, KANJI_LEVEL4, // 靱 + 0x9779, KANJI_LEVEL4, // 靹 + 0x9785, KANJI_LEVEL4, // 鞅 + 0x977C, KANJI_LEVEL4, // 靌 + 0x9781, KANJI_LEVEL4, // 鞁 + 0x977A, KANJI_LEVEL4, // 靺 + 0x9786, KANJI_LEVEL4, // 鞆 + 0x978B, KANJI_LEVEL4, // 鞋 + 0x978F, KANJI_LEVEL4, // 鞏 + 0x9790, KANJI_LEVEL4, // 鞐 + 0x979C, KANJI_LEVEL4, // 鞜 + 0x97A8, KANJI_LEVEL4, // 鞚 + 0x97A6, KANJI_LEVEL4, // 鞊 + 0x97A3, KANJI_LEVEL4, // 鞣 + 0x97B3, KANJI_LEVEL4, // 鞳 + 0x97B4, KANJI_LEVEL4, // 鞮 + 0x97C3, KANJI_LEVEL4, // 韃 + 0x97C6, KANJI_LEVEL4, // 韆 + 0x97C8, KANJI_LEVEL4, // 韈 + 0x97CB, KANJI_LEVEL4, // 韋 + 0x97DC, KANJI_LEVEL4, // 韜 + 0x97ED, KANJI_LEVEL4, // 韭 + 0x9F4F, KANJI_LEVEL4, // 霏 + 0x97F2, KANJI_LEVEL4, // 韲 + 0x7ADF, KANJI_LEVEL4, // 竟 + 0x97F6, KANJI_LEVEL4, // 韶 + 0x97F5, KANJI_LEVEL4, // 韵 + 0x980F, KANJI_LEVEL4, // 頏 + 0x980C, KANJI_LEVEL4, // 頌 + 0x9838, KANJI_LEVEL4, // é ž + 0x9824, KANJI_LEVEL4, // é € + 0x9821, KANJI_LEVEL4, // é ¡ + 0x9837, KANJI_LEVEL4, // é · + 0x983D, KANJI_LEVEL4, // é œ + 0x9846, KANJI_LEVEL4, // 顆 + 0x984F, KANJI_LEVEL4, // 顏 + 0x984B, KANJI_LEVEL4, // 顋 + 0x986B, KANJI_LEVEL4, // é¡« + 0x986F, KANJI_LEVEL4, // 顯 + 0x9870, KANJI_LEVEL4, // é¡° + 0x9871, KANJI_LEVEL4, // 顱 + 0x9874, KANJI_LEVEL4, // 顎 + 0x9873, KANJI_LEVEL4, // 顳 + 0x98AA, KANJI_LEVEL4, // 颪 + 0x98AF, KANJI_LEVEL4, // 颯 + 0x98B1, KANJI_LEVEL4, // 颱 + 0x98B6, KANJI_LEVEL4, // 颶 + 0x98C4, KANJI_LEVEL4, // 飄 + 0x98C3, KANJI_LEVEL4, // 飃 + 0x98C6, KANJI_LEVEL4, // 飆 + 0x98E9, KANJI_LEVEL4, // 飩 + 0x98EB, KANJI_LEVEL4, // 飫 + 0x9903, KANJI_LEVEL4, // 逃 + 0x9909, KANJI_LEVEL4, // 选 + 0x9912, KANJI_LEVEL4, // 递 + 0x9914, KANJI_LEVEL4, // 途 + 0x9918, KANJI_LEVEL4, // 逘 + 0x9921, KANJI_LEVEL4, // 逡 + 0x991D, KANJI_LEVEL4, // 逝 + 0x991E, KANJI_LEVEL4, // 逞 + 0x9924, KANJI_LEVEL4, // 退 + 0x9920, KANJI_LEVEL4, // 造 + 0x992C, KANJI_LEVEL4, // 逬 + 0x992E, KANJI_LEVEL4, // 逮 + 0x993D, KANJI_LEVEL4, // 逜 + 0x993E, KANJI_LEVEL4, // 速 + 0x9942, KANJI_LEVEL4, // 饂 + 0x9949, KANJI_LEVEL4, // 饉 + 0x9945, KANJI_LEVEL4, // 饅 + 0x9950, KANJI_LEVEL4, // 饐 + 0x994B, KANJI_LEVEL4, // 饋 + 0x9951, KANJI_LEVEL4, // 饑 + 0x9952, KANJI_LEVEL4, // 饒 + 0x994C, KANJI_LEVEL4, // 饌 + 0x9955, KANJI_LEVEL4, // 饕 + 0x9997, KANJI_LEVEL4, // 驗 + 0x9998, KANJI_LEVEL4, // 銘 + 0x99A5, KANJI_LEVEL4, // 銥 + 0x99AD, KANJI_LEVEL4, // 銭 + 0x99AE, KANJI_LEVEL4, // 銮 + 0x99BC, KANJI_LEVEL4, // 銌 + 0x99DF, KANJI_LEVEL4, // 駟 + 0x99DB, KANJI_LEVEL4, // 駛 + 0x99DD, KANJI_LEVEL4, // 駝 + 0x99D8, KANJI_LEVEL4, // 駘 + 0x99D1, KANJI_LEVEL4, // 駑 + 0x99ED, KANJI_LEVEL4, // é§­ + 0x99EE, KANJI_LEVEL4, // é§® + 0x99F1, KANJI_LEVEL4, // é§± + 0x99F2, KANJI_LEVEL4, // é§² + 0x99FB, KANJI_LEVEL4, // é§» + 0x99F8, KANJI_LEVEL4, // é§ž + 0x9A01, KANJI_LEVEL4, // 隁 + 0x9A0F, KANJI_LEVEL4, // 随 + 0x9A05, KANJI_LEVEL4, // 鹅 + 0x99E2, KANJI_LEVEL4, // é§¢ + 0x9A19, KANJI_LEVEL4, // 鹙 + 0x9A2B, KANJI_LEVEL4, // éš« + 0x9A37, KANJI_LEVEL4, // éš· + 0x9A45, KANJI_LEVEL4, // 驅 + 0x9A42, KANJI_LEVEL4, // 驂 + 0x9A40, KANJI_LEVEL4, // 驀 + 0x9A43, KANJI_LEVEL4, // 驃 + 0x9A3E, KANJI_LEVEL4, // 隟 + 0x9A55, KANJI_LEVEL4, // 驕 + 0x9A4D, KANJI_LEVEL4, // 驍 + 0x9A5B, KANJI_LEVEL4, // 驛 + 0x9A57, KANJI_LEVEL4, // 驗 + 0x9A5F, KANJI_LEVEL4, // 驟 + 0x9A62, KANJI_LEVEL4, // é©¢ + 0x9A65, KANJI_LEVEL4, // é©¥ + 0x9A64, KANJI_LEVEL4, // é©€ + 0x9A69, KANJI_LEVEL4, // é©© + 0x9A6B, KANJI_LEVEL4, // é©« + 0x9A6A, KANJI_LEVEL4, // 驪 + 0x9AAD, KANJI_LEVEL4, // 骭 + 0x9AB0, KANJI_LEVEL4, // 骰 + 0x9ABC, KANJI_LEVEL4, // 验 + 0x9AC0, KANJI_LEVEL4, // 髀 + 0x9ACF, KANJI_LEVEL4, // 髏 + 0x9AD1, KANJI_LEVEL4, // 髑 + 0x9AD3, KANJI_LEVEL4, // 髓 + 0x9AD4, KANJI_LEVEL4, // 體 + 0x9ADE, KANJI_LEVEL4, // 髞 + 0x9ADF, KANJI_LEVEL4, // 髟 + 0x9AE2, KANJI_LEVEL4, // é«¢ + 0x9AE3, KANJI_LEVEL4, // é«£ + 0x9AE6, KANJI_LEVEL4, // 髊 + 0x9AEF, KANJI_LEVEL4, // 髯 + 0x9AEB, KANJI_LEVEL4, // é«« + 0x9AEE, KANJI_LEVEL4, // é«® + 0x9AF4, KANJI_LEVEL4, // 髎 + 0x9AF1, KANJI_LEVEL4, // 髱 + 0x9AF7, KANJI_LEVEL4, // é«· + 0x9AFB, KANJI_LEVEL4, // é«» + 0x9B06, KANJI_LEVEL4, // 鬆 + 0x9B18, KANJI_LEVEL4, // 鬘 + 0x9B1A, KANJI_LEVEL4, // 鬚 + 0x9B1F, KANJI_LEVEL4, // 鬟 + 0x9B22, KANJI_LEVEL4, // 鬢 + 0x9B23, KANJI_LEVEL4, // 鬣 + 0x9B25, KANJI_LEVEL4, // 鬥 + 0x9B27, KANJI_LEVEL4, // 鬧 + 0x9B28, KANJI_LEVEL4, // 鬚 + 0x9B29, KANJI_LEVEL4, // 鬩 + 0x9B2A, KANJI_LEVEL4, // 鬪 + 0x9B2E, KANJI_LEVEL4, // 鬮 + 0x9B2F, KANJI_LEVEL4, // 鬯 + 0x9B32, KANJI_LEVEL4, // 鬲 + 0x9B44, KANJI_LEVEL4, // 魄 + 0x9B43, KANJI_LEVEL4, // 魃 + 0x9B4F, KANJI_LEVEL4, // 魏 + 0x9B4D, KANJI_LEVEL4, // 魍 + 0x9B4E, KANJI_LEVEL4, // 魎 + 0x9B51, KANJI_LEVEL4, // 魑 + 0x9B58, KANJI_LEVEL4, // 魘 + 0x9B74, KANJI_LEVEL4, // é­Ž + 0x9B93, KANJI_LEVEL4, // 鮓 + 0x9B83, KANJI_LEVEL4, // 鮃 + 0x9B91, KANJI_LEVEL4, // 鮑 + 0x9B96, KANJI_LEVEL4, // 鮖 + 0x9B97, KANJI_LEVEL4, // 鮗 + 0x9B9F, KANJI_LEVEL4, // 鮟 + 0x9BA0, KANJI_LEVEL4, // é®  + 0x9BA8, KANJI_LEVEL4, // 鮚 + 0x9BB4, KANJI_LEVEL4, // 鮎 + 0x9BC0, KANJI_LEVEL4, // 鯀 + 0x9BCA, KANJI_LEVEL4, // 鯊 + 0x9BB9, KANJI_LEVEL4, // 鮹 + 0x9BC6, KANJI_LEVEL4, // 鯆 + 0x9BCF, KANJI_LEVEL4, // 鯏 + 0x9BD1, KANJI_LEVEL4, // 鯑 + 0x9BD2, KANJI_LEVEL4, // 鯒 + 0x9BE3, KANJI_LEVEL4, // 鯣 + 0x9BE2, KANJI_LEVEL4, // 鯢 + 0x9BE4, KANJI_LEVEL4, // 鯀 + 0x9BD4, KANJI_LEVEL4, // 鯔 + 0x9BE1, KANJI_LEVEL4, // 鯡 + 0x9C3A, KANJI_LEVEL4, // é°º + 0x9BF2, KANJI_LEVEL4, // 鯲 + 0x9BF1, KANJI_LEVEL4, // 鯱 + 0x9BF0, KANJI_LEVEL4, // 鯰 + 0x9C15, KANJI_LEVEL4, // 鰕 + 0x9C14, KANJI_LEVEL4, // 鰔 + 0x9C09, KANJI_LEVEL4, // 鰉 + 0x9C13, KANJI_LEVEL4, // 鰓 + 0x9C0C, KANJI_LEVEL4, // 鰌 + 0x9C06, KANJI_LEVEL4, // 鰆 + 0x9C08, KANJI_LEVEL4, // 鰈 + 0x9C12, KANJI_LEVEL4, // 鰒 + 0x9C0A, KANJI_LEVEL4, // 鰊 + 0x9C04, KANJI_LEVEL4, // 鰄 + 0x9C2E, KANJI_LEVEL4, // é°® + 0x9C1B, KANJI_LEVEL4, // 鰛 + 0x9C25, KANJI_LEVEL4, // é°¥ + 0x9C24, KANJI_LEVEL4, // é°€ + 0x9C21, KANJI_LEVEL4, // é°¡ + 0x9C30, KANJI_LEVEL4, // é°° + 0x9C47, KANJI_LEVEL4, // 鱇 + 0x9C32, KANJI_LEVEL4, // é°² + 0x9C46, KANJI_LEVEL4, // 鱆 + 0x9C3E, KANJI_LEVEL4, // é°Ÿ + 0x9C5A, KANJI_LEVEL4, // 鱚 + 0x9C60, KANJI_LEVEL4, // é±  + 0x9C67, KANJI_LEVEL4, // é±§ + 0x9C76, KANJI_LEVEL4, // é±¶ + 0x9C78, KANJI_LEVEL4, // 鱞 + 0x9CE7, KANJI_LEVEL4, // é³§ + 0x9CEC, KANJI_LEVEL4, // 鳬 + 0x9CF0, KANJI_LEVEL4, // é³° + 0x9D09, KANJI_LEVEL4, // 鮉 + 0x9D08, KANJI_LEVEL4, // 鎈 + 0x9CEB, KANJI_LEVEL4, // 鳫 + 0x9D03, KANJI_LEVEL4, // 鎃 + 0x9D06, KANJI_LEVEL4, // 鮆 + 0x9D2A, KANJI_LEVEL4, // 鎪 + 0x9D26, KANJI_LEVEL4, // 鎊 + 0x9DAF, KANJI_LEVEL4, // 鶯 + 0x9D23, KANJI_LEVEL4, // 鎣 + 0x9D1F, KANJI_LEVEL4, // 鮟 + 0x9D44, KANJI_LEVEL4, // 鵄 + 0x9D15, KANJI_LEVEL4, // 鮕 + 0x9D12, KANJI_LEVEL4, // 鮒 + 0x9D41, KANJI_LEVEL4, // 鵁 + 0x9D3F, KANJI_LEVEL4, // 鎿 + 0x9D3E, KANJI_LEVEL4, // 鎟 + 0x9D46, KANJI_LEVEL4, // 鵆 + 0x9D48, KANJI_LEVEL4, // 鵈 + 0x9D5D, KANJI_LEVEL4, // 鵝 + 0x9D5E, KANJI_LEVEL4, // 鵞 + 0x9D64, KANJI_LEVEL4, // éµ€ + 0x9D51, KANJI_LEVEL4, // 鵑 + 0x9D50, KANJI_LEVEL4, // 鵐 + 0x9D59, KANJI_LEVEL4, // 鵙 + 0x9D72, KANJI_LEVEL4, // éµ² + 0x9D89, KANJI_LEVEL4, // 鶉 + 0x9D87, KANJI_LEVEL4, // 鶇 + 0x9DAB, KANJI_LEVEL4, // é¶« + 0x9D6F, KANJI_LEVEL4, // 鵯 + 0x9D7A, KANJI_LEVEL4, // 鵺 + 0x9D9A, KANJI_LEVEL4, // 鶚 + 0x9DA4, KANJI_LEVEL4, // é¶€ + 0x9DA9, KANJI_LEVEL4, // é¶© + 0x9DB2, KANJI_LEVEL4, // é¶² + 0x9DC4, KANJI_LEVEL4, // 鷄 + 0x9DC1, KANJI_LEVEL4, // 鷁 + 0x9DBB, KANJI_LEVEL4, // é¶» + 0x9DB8, KANJI_LEVEL4, // é¶ž + 0x9DBA, KANJI_LEVEL4, // 鶺 + 0x9DC6, KANJI_LEVEL4, // 鷆 + 0x9DCF, KANJI_LEVEL4, // 鷏 + 0x9DC2, KANJI_LEVEL4, // 鷂 + 0x9DD9, KANJI_LEVEL4, // 鷙 + 0x9DD3, KANJI_LEVEL4, // 鷓 + 0x9DF8, KANJI_LEVEL4, // é·ž + 0x9DE6, KANJI_LEVEL4, // é·Š + 0x9DED, KANJI_LEVEL4, // é·­ + 0x9DEF, KANJI_LEVEL4, // é·¯ + 0x9DFD, KANJI_LEVEL4, // é·œ + 0x9E1A, KANJI_LEVEL4, // 龚 + 0x9E1B, KANJI_LEVEL4, // 龛 + 0x9E1E, KANJI_LEVEL4, // 龞 + 0x9E75, KANJI_LEVEL4, // é¹µ + 0x9E79, KANJI_LEVEL4, // é¹¹ + 0x9E7D, KANJI_LEVEL4, // 鹜 + 0x9E81, KANJI_LEVEL4, // 麁 + 0x9E88, KANJI_LEVEL4, // 麈 + 0x9E8B, KANJI_LEVEL4, // 麋 + 0x9E8C, KANJI_LEVEL4, // 麌 + 0x9E92, KANJI_LEVEL4, // 麒 + 0x9E95, KANJI_LEVEL4, // 麕 + 0x9E91, KANJI_LEVEL4, // 麑 + 0x9E9D, KANJI_LEVEL4, // 麝 + 0x9EA5, KANJI_LEVEL4, // 麥 + 0x9EA9, KANJI_LEVEL4, // 麩 + 0x9EB8, KANJI_LEVEL4, // 麞 + 0x9EAA, KANJI_LEVEL4, // 麪 + 0x9EAD, KANJI_LEVEL4, // 麭 + 0x9761, KANJI_LEVEL4, // 靡 + 0x9ECC, KANJI_LEVEL4, // 黌 + 0x9ECE, KANJI_LEVEL4, // 黎 + 0x9ECF, KANJI_LEVEL4, // 黏 + 0x9ED0, KANJI_LEVEL4, // 黐 + 0x9ED4, KANJI_LEVEL4, // 黔 + 0x9EDC, KANJI_LEVEL4, // 黜 + 0x9EDE, KANJI_LEVEL4, // 點 + 0x9EDD, KANJI_LEVEL4, // 黝 + 0x9EE0, KANJI_LEVEL4, // é»  + 0x9EE5, KANJI_LEVEL4, // 黥 + 0x9EE8, KANJI_LEVEL4, // 黚 + 0x9EEF, KANJI_LEVEL4, // 黯 + 0x9EF4, KANJI_LEVEL4, // 黎 + 0x9EF6, KANJI_LEVEL4, // é»¶ + 0x9EF7, KANJI_LEVEL4, // é»· + 0x9EF9, KANJI_LEVEL4, // 黹 + 0x9EFB, KANJI_LEVEL4, // é»» + 0x9EFC, KANJI_LEVEL4, // 黌 + 0x9EFD, KANJI_LEVEL4, // 黜 + 0x9F07, KANJI_LEVEL4, // 錇 + 0x9F08, KANJI_LEVEL4, // 錈 + 0x76B7, KANJI_LEVEL4, // 皷 + 0x9F15, KANJI_LEVEL4, // 錕 + 0x9F21, KANJI_LEVEL4, // 錡 + 0x9F2C, KANJI_LEVEL4, // 錬 + 0x9F3E, KANJI_LEVEL4, // 錟 + 0x9F4A, KANJI_LEVEL4, // 霊 + 0x9F52, KANJI_LEVEL4, // 霒 + 0x9F54, KANJI_LEVEL4, // 霔 + 0x9F63, KANJI_LEVEL4, // 霣 + 0x9F5F, KANJI_LEVEL4, // 霟 + 0x9F60, KANJI_LEVEL4, // 霠 + 0x9F61, KANJI_LEVEL4, // 霡 + 0x9F66, KANJI_LEVEL4, // 霊 + 0x9F67, KANJI_LEVEL4, // 霧 + 0x9F6C, KANJI_LEVEL4, // 霬 + 0x9F6A, KANJI_LEVEL4, // 霪 + 0x9F77, KANJI_LEVEL4, // 霷 + 0x9F72, KANJI_LEVEL4, // 露 + 0x9F76, KANJI_LEVEL4, // 霶 + 0x9F95, KANJI_LEVEL4, // 韕 + 0x9F9C, KANJI_LEVEL4, // 韜 + 0x9FA0, KANJI_LEVEL4, // 韠 + 0x582F, KANJI_LEVEL4, // å ¯ + 0x69C7, KANJI_LEVEL4, // 槇 + 0x9059, KANJI_LEVEL4, // 遙 + 0x7464, KANJI_LEVEL4, // ç‘€ + 0x51DC, KANJI_LEVEL4, // 凜 + 0x7199, KANJI_LEVEL4, // 熙 + 0x5653, KANJI_LEVEL4, // 噓 + 0x5DE2, KANJI_LEVEL4, // å·¢ + 0x5E14, KANJI_LEVEL4, // åž” + 0x5E18, KANJI_LEVEL4, // 垘 + 0x5E58, KANJI_LEVEL4, // 幘 + 0x5E5E, KANJI_LEVEL4, // 幞 + 0x5EBE, KANJI_LEVEL4, // 废 + 0xF928, KANJI_LEVEL4, //  + 0x5ECB, KANJI_LEVEL4, // 廋 + 0x5EF9, KANJI_LEVEL4, // 廹 + 0x5F00, KANJI_LEVEL4, // 匀 + 0x5F02, KANJI_LEVEL4, // 匂 + 0x5F07, KANJI_LEVEL4, // 匇 + 0x5F1D, KANJI_LEVEL4, // 匝 + 0x5F23, KANJI_LEVEL4, // 匣 + 0x5F34, KANJI_LEVEL4, // 匎 + 0x5F36, KANJI_LEVEL4, // 匶 + 0x5F3D, KANJI_LEVEL4, // 匜 + 0x5F40, KANJI_LEVEL4, // 圀 + 0x5F45, KANJI_LEVEL4, // 圅 + 0x5F54, KANJI_LEVEL4, // 圔 + 0x5F58, KANJI_LEVEL4, // 團 + 0x5F64, KANJI_LEVEL4, // 圀 + 0x5F67, KANJI_LEVEL4, // 圧 + 0x5F7D, KANJI_LEVEL4, // 圜 + 0x5F89, KANJI_LEVEL4, // 埉 + 0x5F9C, KANJI_LEVEL4, // 埜 + 0x5FA7, KANJI_LEVEL4, // 埧 + 0x5FAF, KANJI_LEVEL4, // 埯 + 0x5FB5, KANJI_LEVEL4, // 埵 + 0x5FB7, KANJI_LEVEL4, // 執 + 0x5FC9, KANJI_LEVEL4, // 忉 + 0x5FDE, KANJI_LEVEL4, // 忞 + 0x5FE1, KANJI_LEVEL4, // å¿¡ + 0x5FE9, KANJI_LEVEL4, // å¿© + 0x600D, KANJI_LEVEL4, // 怍 + 0x6014, KANJI_LEVEL4, // 怔 + 0x6018, KANJI_LEVEL4, // 怘 + 0x6033, KANJI_LEVEL4, // 怳 + 0x6035, KANJI_LEVEL4, // 怵 + 0x6047, KANJI_LEVEL4, // 恇 + 0xFA3D, KANJI_LEVEL4, // ïšœ + 0x609D, KANJI_LEVEL4, // 悝 + 0x609E, KANJI_LEVEL4, // 悞 + 0x60CB, KANJI_LEVEL4, // 惋 + 0x60D4, KANJI_LEVEL4, // 惔 + 0x60D5, KANJI_LEVEL4, // 惕 + 0x60DD, KANJI_LEVEL4, // 惝 + 0x60F8, KANJI_LEVEL4, // 惞 + 0x611C, KANJI_LEVEL4, // 愜 + 0x612B, KANJI_LEVEL4, // 愫 + 0x6130, KANJI_LEVEL4, // 愰 + 0x6137, KANJI_LEVEL4, // 愷 + 0xFA3E, KANJI_LEVEL4, //  + 0x618D, KANJI_LEVEL4, // 憍 + 0xFA3F, KANJI_LEVEL4, // ïš¿ + 0x61BC, KANJI_LEVEL4, // 憌 + 0x61B9, KANJI_LEVEL4, // 憹 + 0xFA40, KANJI_LEVEL4, // 懲 + 0x6222, KANJI_LEVEL4, // 戢 + 0x623E, KANJI_LEVEL4, // 戟 + 0x6243, KANJI_LEVEL4, // 扃 + 0x6256, KANJI_LEVEL4, // 扖 + 0x625A, KANJI_LEVEL4, // 扚 + 0x626F, KANJI_LEVEL4, // 扯 + 0x6285, KANJI_LEVEL4, // 抅 + 0x62C4, KANJI_LEVEL4, // 拄 + 0x62D6, KANJI_LEVEL4, // 拖 + 0x62FC, KANJI_LEVEL4, // 拌 + 0x630A, KANJI_LEVEL4, // 挊 + 0x6318, KANJI_LEVEL4, // 挘 + 0x6339, KANJI_LEVEL4, // 挹 + 0x6343, KANJI_LEVEL4, // 捃 + 0x6365, KANJI_LEVEL4, // 捥 + 0x637C, KANJI_LEVEL4, // 捌 + 0x63E5, KANJI_LEVEL4, // 揥 + 0x63ED, KANJI_LEVEL4, // 揭 + 0x63F5, KANJI_LEVEL4, // 揵 + 0x6410, KANJI_LEVEL4, // 搐 + 0x6414, KANJI_LEVEL4, // 搔 + 0x6422, KANJI_LEVEL4, // 搢 + 0x6479, KANJI_LEVEL4, // 摹 + 0x6451, KANJI_LEVEL4, // 摑 + 0x6460, KANJI_LEVEL4, // 摠 + 0x646D, KANJI_LEVEL4, // 摭 + 0x64CE, KANJI_LEVEL4, // 擎 + 0x64BE, KANJI_LEVEL4, // æ’Ÿ + 0x64BF, KANJI_LEVEL4, // 撿 + 0x64C4, KANJI_LEVEL4, // 擄 + 0x64CA, KANJI_LEVEL4, // 擊 + 0x64D0, KANJI_LEVEL4, // 擐 + 0x64F7, KANJI_LEVEL4, // 擷 + 0x64FB, KANJI_LEVEL4, // 擻 + 0x6522, KANJI_LEVEL4, // 攢 + 0x6529, KANJI_LEVEL4, // 攩 + 0xFA41, KANJI_LEVEL4, // 敏 + 0x6567, KANJI_LEVEL4, // 敧 + 0x659D, KANJI_LEVEL4, // 斝 + 0xFA42, KANJI_LEVEL4, // 既 + 0x6600, KANJI_LEVEL4, // 昀 + 0x6609, KANJI_LEVEL4, // 昉 + 0x6615, KANJI_LEVEL4, // 昕 + 0x661E, KANJI_LEVEL4, // 昞 + 0x663A, KANJI_LEVEL4, // 昺 + 0x6622, KANJI_LEVEL4, // 昢 + 0x6624, KANJI_LEVEL4, // 昀 + 0x662B, KANJI_LEVEL4, // 昫 + 0x6630, KANJI_LEVEL4, // 昰 + 0x6631, KANJI_LEVEL4, // 昱 + 0x6633, KANJI_LEVEL4, // 昳 + 0x66FB, KANJI_LEVEL4, // 曻 + 0x6648, KANJI_LEVEL4, // 晈 + 0x664C, KANJI_LEVEL4, // 晌 + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDDC4, KANJI_LEVEL4, // ᅵ + 0x6659, KANJI_LEVEL4, // 晙 + 0x665A, KANJI_LEVEL4, // 晚 + 0x6661, KANJI_LEVEL4, // 晡 + 0x6665, KANJI_LEVEL4, // 晥 + 0x6673, KANJI_LEVEL4, // 晳 + 0x6677, KANJI_LEVEL4, // 晷 + 0x6678, KANJI_LEVEL4, // 晞 + 0x668D, KANJI_LEVEL4, // 暍 + 0xFA43, KANJI_LEVEL4, // 暑 + 0x66A0, KANJI_LEVEL4, // 暠 + 0x66B2, KANJI_LEVEL4, // 暲 + 0x66BB, KANJI_LEVEL4, // 暻 + 0x66C6, KANJI_LEVEL4, // 曆 + 0x66C8, KANJI_LEVEL4, // 曈 + 0x3B22, KANJI_LEVEL4, // 㬢 + 0x66DB, KANJI_LEVEL4, // 曛 + 0x66E8, KANJI_LEVEL4, // 曚 + 0x66FA, KANJI_LEVEL4, // 曺 + 0x6713, KANJI_LEVEL4, // 朓 + 0xF929, KANJI_LEVEL4, //  + 0x6733, KANJI_LEVEL4, // 朳 + 0x6766, KANJI_LEVEL4, // 杊 + 0x6747, KANJI_LEVEL4, // 杇 + 0x6748, KANJI_LEVEL4, // 杈 + 0x677B, KANJI_LEVEL4, // 杻 + 0x6781, KANJI_LEVEL4, // 极 + 0x6793, KANJI_LEVEL4, // 枓 + 0x6798, KANJI_LEVEL4, // 枘 + 0x679B, KANJI_LEVEL4, // 枛 + 0x67BB, KANJI_LEVEL4, // 枻 + 0x67F9, KANJI_LEVEL4, // 柹 + 0x67C0, KANJI_LEVEL4, // 柀 + 0x67D7, KANJI_LEVEL4, // 柗 + 0x67FC, KANJI_LEVEL4, // 柌 + 0x6801, KANJI_LEVEL4, // 栁 + 0x6852, KANJI_LEVEL4, // 桒 + 0x681D, KANJI_LEVEL4, // 栝 + 0x682C, KANJI_LEVEL4, // æ ¬ + 0x6831, KANJI_LEVEL4, // æ ± + 0x685B, KANJI_LEVEL4, // 桛 + 0x6872, KANJI_LEVEL4, // 桲 + 0x6875, KANJI_LEVEL4, // 桵 + 0xFA44, KANJI_LEVEL4, // 梅 + 0x68A3, KANJI_LEVEL4, // 梣 + 0x68A5, KANJI_LEVEL4, // 梥 + 0x68B2, KANJI_LEVEL4, // 梲 + 0x68C8, KANJI_LEVEL4, // 棈 + 0x68D0, KANJI_LEVEL4, // 棐 + 0x68E8, KANJI_LEVEL4, // 棚 + 0x68ED, KANJI_LEVEL4, // 棭 + 0x68F0, KANJI_LEVEL4, // 棰 + 0x68F1, KANJI_LEVEL4, // 棱 + 0x68FC, KANJI_LEVEL4, // 棌 + 0x690A, KANJI_LEVEL4, // 怊 + 0x6949, KANJI_LEVEL4, // 楉 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDDC4, KANJI_LEVEL4, // ᅵ + 0x6935, KANJI_LEVEL4, // 怵 + 0x6942, KANJI_LEVEL4, // 楂 + 0x6957, KANJI_LEVEL4, // 楗 + 0x6963, KANJI_LEVEL4, // 楣 + 0x6964, KANJI_LEVEL4, // 楀 + 0x6968, KANJI_LEVEL4, // 楚 + 0x6980, KANJI_LEVEL4, // 技 + 0xFA14, KANJI_LEVEL4, // ïš” + 0x69A5, KANJI_LEVEL4, // 报 + 0x69AD, KANJI_LEVEL4, // 抭 + 0x69CF, KANJI_LEVEL4, // 槏 + 0x3BB6, KANJI_LEVEL4, // ã®¶ + 0x3BC3, KANJI_LEVEL4, // 㯃 + 0x69E2, KANJI_LEVEL4, // æ§¢ + 0x69E9, KANJI_LEVEL4, // æ§© + 0x69EA, KANJI_LEVEL4, // 槪 + 0x69F5, KANJI_LEVEL4, // æ§µ + 0x69F6, KANJI_LEVEL4, // æ§¶ + 0x6A0F, KANJI_LEVEL4, // 暏 + 0x6A15, KANJI_LEVEL4, // æš• + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDF3F, KANJI_LEVEL4, // ᅵ + 0x6A3B, KANJI_LEVEL4, // æš» + 0x6A3E, KANJI_LEVEL4, // 暟 + 0x6A45, KANJI_LEVEL4, // 橅 + 0x6A50, KANJI_LEVEL4, // 橐 + 0x6A56, KANJI_LEVEL4, // 橖 + 0x6A5B, KANJI_LEVEL4, // 橛 + 0x6A6B, KANJI_LEVEL4, // æ©« + 0x6A73, KANJI_LEVEL4, // 橳 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDF63, KANJI_LEVEL4, // ᅵ + 0x6A89, KANJI_LEVEL4, // 檉 + 0x6A94, KANJI_LEVEL4, // 檔 + 0x6A9D, KANJI_LEVEL4, // 檝 + 0x6A9E, KANJI_LEVEL4, // 檞 + 0x6AA5, KANJI_LEVEL4, // 檥 + 0x6AE4, KANJI_LEVEL4, // æ«€ + 0x6AE7, KANJI_LEVEL4, // æ«§ + 0x3C0F, KANJI_LEVEL4, // 㰏 + 0xF91D, KANJI_LEVEL4, //  + 0x6B1B, KANJI_LEVEL4, // 欛 + 0x6B1E, KANJI_LEVEL4, // 欞 + 0x6B2C, KANJI_LEVEL4, // 欬 + 0x6B35, KANJI_LEVEL4, // 欵 + 0x6B46, KANJI_LEVEL4, // 歆 + 0x6B56, KANJI_LEVEL4, // 歖 + 0x6B60, KANJI_LEVEL4, // æ­  + 0x6B65, KANJI_LEVEL4, // æ­¥ + 0x6B67, KANJI_LEVEL4, // æ­§ + 0x6B77, KANJI_LEVEL4, // æ­· + 0x6B82, KANJI_LEVEL4, // 殂 + 0x6BA9, KANJI_LEVEL4, // 殩 + 0x6BAD, KANJI_LEVEL4, // æ®­ + 0xF970, KANJI_LEVEL4, // 殺 + 0x6BCF, KANJI_LEVEL4, // 每 + 0x6BD6, KANJI_LEVEL4, // 毖 + 0x6BD7, KANJI_LEVEL4, // 毗 + 0x6BFF, KANJI_LEVEL4, // 毿 + 0x6C05, KANJI_LEVEL4, // 氅 + 0x6C10, KANJI_LEVEL4, // 氐 + 0x6C33, KANJI_LEVEL4, // æ°³ + 0x6C59, KANJI_LEVEL4, // 汙 + 0x6C5C, KANJI_LEVEL4, // 汜 + 0x6CAA, KANJI_LEVEL4, // 沪 + 0x6C74, KANJI_LEVEL4, // 汎 + 0x6C76, KANJI_LEVEL4, // æ±¶ + 0x6C85, KANJI_LEVEL4, // 沅 + 0x6C86, KANJI_LEVEL4, // 沆 + 0x6C98, KANJI_LEVEL4, // 沘 + 0x6C9C, KANJI_LEVEL4, // 沜 + 0x6CFB, KANJI_LEVEL4, // æ³» + 0x6CC6, KANJI_LEVEL4, // 泆 + 0x6CD4, KANJI_LEVEL4, // 泔 + 0x6CE0, KANJI_LEVEL4, // æ³  + 0x6CEB, KANJI_LEVEL4, // 泫 + 0x6CEE, KANJI_LEVEL4, // æ³® + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDCFE, KANJI_LEVEL4, // ᅵ + 0x6D04, KANJI_LEVEL4, // 掄 + 0x6D0E, KANJI_LEVEL4, // 掎 + 0x6D2E, KANJI_LEVEL4, // 掮 + 0x6D31, KANJI_LEVEL4, // 掱 + 0x6D39, KANJI_LEVEL4, // 掹 + 0x6D3F, KANJI_LEVEL4, // 掿 + 0x6D58, KANJI_LEVEL4, // 浘 + 0x6D65, KANJI_LEVEL4, // æµ¥ + 0xFA45, KANJI_LEVEL4, // 海 + 0x6D82, KANJI_LEVEL4, // 涂 + 0x6D87, KANJI_LEVEL4, // 涇 + 0x6D89, KANJI_LEVEL4, // 涉 + 0x6D94, KANJI_LEVEL4, // 涔 + 0x6DAA, KANJI_LEVEL4, // 涪 + 0x6DAC, KANJI_LEVEL4, // 涬 + 0x6DBF, KANJI_LEVEL4, // æ¶¿ + 0x6DC4, KANJI_LEVEL4, // 淄 + 0x6DD6, KANJI_LEVEL4, // 淖 + 0x6DDA, KANJI_LEVEL4, // 淚 + 0x6DDB, KANJI_LEVEL4, // 淛 + 0x6DDD, KANJI_LEVEL4, // 淝 + 0x6DFC, KANJI_LEVEL4, // æ·Œ + 0xFA46, KANJI_LEVEL4, // 渚 + 0x6E34, KANJI_LEVEL4, // 枎 + 0x6E44, KANJI_LEVEL4, // 湄 + 0x6E5C, KANJI_LEVEL4, // 湜 + 0x6E5E, KANJI_LEVEL4, // 湞 + 0x6EAB, KANJI_LEVEL4, // 溫 + 0x6EB1, KANJI_LEVEL4, // 溱 + 0x6EC1, KANJI_LEVEL4, // 滁 + 0x6EC7, KANJI_LEVEL4, // 滇 + 0x6ECE, KANJI_LEVEL4, // 滎 + 0x6F10, KANJI_LEVEL4, // 挐 + 0x6F1A, KANJI_LEVEL4, // 挚 + 0xFA47, KANJI_LEVEL4, // 漢 + 0x6F2A, KANJI_LEVEL4, // 挪 + 0x6F2F, KANJI_LEVEL4, // 振 + 0x6F33, KANJI_LEVEL4, // 挳 + 0x6F51, KANJI_LEVEL4, // 朑 + 0x6F59, KANJI_LEVEL4, // 朙 + 0x6F5E, KANJI_LEVEL4, // 朞 + 0x6F61, KANJI_LEVEL4, // 朡 + 0x6F62, KANJI_LEVEL4, // 朢 + 0x6F7E, KANJI_LEVEL4, // 期 + 0x6F88, KANJI_LEVEL4, // 柈 + 0x6F8C, KANJI_LEVEL4, // 柌 + 0x6F8D, KANJI_LEVEL4, // 柍 + 0x6F94, KANJI_LEVEL4, // 柔 + 0x6FA0, KANJI_LEVEL4, // 柠 + 0x6FA7, KANJI_LEVEL4, // 柧 + 0x6FB6, KANJI_LEVEL4, // 柶 + 0x6FBC, KANJI_LEVEL4, // 柌 + 0x6FC7, KANJI_LEVEL4, // 濇 + 0x6FCA, KANJI_LEVEL4, // 濊 + 0x6FF9, KANJI_LEVEL4, // 濹 + 0x6FF0, KANJI_LEVEL4, // æ¿° + 0x6FF5, KANJI_LEVEL4, // 濵 + 0x7005, KANJI_LEVEL4, // 瀅 + 0x7006, KANJI_LEVEL4, // 瀆 + 0x7028, KANJI_LEVEL4, // 瀹 + 0x704A, KANJI_LEVEL4, // 灊 + 0x705D, KANJI_LEVEL4, // 灝 + 0x705E, KANJI_LEVEL4, // 灞 + 0x704E, KANJI_LEVEL4, // 灎 + 0x7064, KANJI_LEVEL4, // 灀 + 0x7075, KANJI_LEVEL4, // 灵 + 0x7085, KANJI_LEVEL4, // 炅 + 0x70A4, KANJI_LEVEL4, // ç‚€ + 0x70AB, KANJI_LEVEL4, // 炫 + 0x70B7, KANJI_LEVEL4, // 炷 + 0x70D4, KANJI_LEVEL4, // 烔 + 0x70D8, KANJI_LEVEL4, // 烘 + 0x70E4, KANJI_LEVEL4, // 烀 + 0x710F, KANJI_LEVEL4, // 焏 + 0x712B, KANJI_LEVEL4, // 焫 + 0x711E, KANJI_LEVEL4, // 焞 + 0x7120, KANJI_LEVEL4, // 焠 + 0x712E, KANJI_LEVEL4, // 焮 + 0x7130, KANJI_LEVEL4, // 焰 + 0x7146, KANJI_LEVEL4, // 煆 + 0x7147, KANJI_LEVEL4, // 煇 + 0x7151, KANJI_LEVEL4, // 煑 + 0xFA48, KANJI_LEVEL4, // 煮 + 0x7152, KANJI_LEVEL4, // 煒 + 0x715C, KANJI_LEVEL4, // 煜 + 0x7160, KANJI_LEVEL4, // 煠 + 0x7168, KANJI_LEVEL4, // 煹 + 0xFA15, KANJI_LEVEL4, // ïš• + 0x7185, KANJI_LEVEL4, // 熅 + 0x7187, KANJI_LEVEL4, // 熇 + 0x7192, KANJI_LEVEL4, // 熒 + 0x71C1, KANJI_LEVEL4, // 燁 + 0x71BA, KANJI_LEVEL4, // 熺 + 0x71C4, KANJI_LEVEL4, // 燄 + 0x71FE, KANJI_LEVEL4, // 營 + 0x7200, KANJI_LEVEL4, // 爀 + 0x7215, KANJI_LEVEL4, // 爕 + 0x7255, KANJI_LEVEL4, // 牕 + 0x7256, KANJI_LEVEL4, // 牖 + 0x3E3F, KANJI_LEVEL4, // ãž¿ + 0x728D, KANJI_LEVEL4, // 犍 + 0x729B, KANJI_LEVEL4, // 犛 + 0x72BE, KANJI_LEVEL4, // 犟 + 0x72C0, KANJI_LEVEL4, // 狀 + 0x72FB, KANJI_LEVEL4, // 狻 + 0xD851, KANJI_LEVEL4, // ᅵ + 0xDFF1, KANJI_LEVEL4, // ᅵ + 0x7327, KANJI_LEVEL4, // 猧 + 0x7328, KANJI_LEVEL4, // 猹 + 0xFA16, KANJI_LEVEL4, // ïš– + 0x7350, KANJI_LEVEL4, // 獐 + 0x7366, KANJI_LEVEL4, // 獊 + 0x737C, KANJI_LEVEL4, // 獌 + 0x7395, KANJI_LEVEL4, // 玕 + 0x739F, KANJI_LEVEL4, // 玟 + 0x73A0, KANJI_LEVEL4, // 玠 + 0x73A2, KANJI_LEVEL4, // 玢 + 0x73A6, KANJI_LEVEL4, // 玊 + 0x73AB, KANJI_LEVEL4, // 玫 + 0x73C9, KANJI_LEVEL4, // 珉 + 0x73CF, KANJI_LEVEL4, // 珏 + 0x73D6, KANJI_LEVEL4, // 珖 + 0x73D9, KANJI_LEVEL4, // 珙 + 0x73E3, KANJI_LEVEL4, // 珣 + 0x73E9, KANJI_LEVEL4, // 珩 + 0x7407, KANJI_LEVEL4, // 琇 + 0x740A, KANJI_LEVEL4, // 琊 + 0x741A, KANJI_LEVEL4, // 琚 + 0x741B, KANJI_LEVEL4, // 琛 + 0xFA4A, KANJI_LEVEL4, // 琢 + 0x7426, KANJI_LEVEL4, // 琊 + 0x7428, KANJI_LEVEL4, // 琚 + 0x742A, KANJI_LEVEL4, // 琪 + 0x742B, KANJI_LEVEL4, // 琫 + 0x742C, KANJI_LEVEL4, // 琬 + 0x742E, KANJI_LEVEL4, // 琮 + 0x742F, KANJI_LEVEL4, // 琯 + 0x7430, KANJI_LEVEL4, // 琰 + 0x7444, KANJI_LEVEL4, // 瑄 + 0x7446, KANJI_LEVEL4, // 瑆 + 0x7447, KANJI_LEVEL4, // 瑇 + 0x744B, KANJI_LEVEL4, // 瑋 + 0x7457, KANJI_LEVEL4, // 瑗 + 0x7462, KANJI_LEVEL4, // 瑢 + 0x746B, KANJI_LEVEL4, // 瑫 + 0x746D, KANJI_LEVEL4, // 瑭 + 0x7486, KANJI_LEVEL4, // 璆 + 0x7487, KANJI_LEVEL4, // 璇 + 0x7489, KANJI_LEVEL4, // 璉 + 0x7498, KANJI_LEVEL4, // 璘 + 0x749C, KANJI_LEVEL4, // 璜 + 0x749F, KANJI_LEVEL4, // 璟 + 0x74A3, KANJI_LEVEL4, // 璣 + 0x7490, KANJI_LEVEL4, // 璐 + 0x74A6, KANJI_LEVEL4, // 璩 + 0x74A8, KANJI_LEVEL4, // 璹 + 0x74A9, KANJI_LEVEL4, // 璩 + 0x74B5, KANJI_LEVEL4, // 璵 + 0x74BF, KANJI_LEVEL4, // 璿 + 0x74C8, KANJI_LEVEL4, // 瓈 + 0x74C9, KANJI_LEVEL4, // 瓉 + 0x74DA, KANJI_LEVEL4, // 瓚 + 0x74FF, KANJI_LEVEL4, // 瓿 + 0x7501, KANJI_LEVEL4, // 甁 + 0x7517, KANJI_LEVEL4, // 甗 + 0x752F, KANJI_LEVEL4, // 甯 + 0x756F, KANJI_LEVEL4, // 畯 + 0x7579, KANJI_LEVEL4, // 畹 + 0x7592, KANJI_LEVEL4, // 疒 + 0x3F72, KANJI_LEVEL4, // 㜲 + 0x75CE, KANJI_LEVEL4, // 痎 + 0x75E4, KANJI_LEVEL4, // ç—€ + 0x7600, KANJI_LEVEL4, // 瘀 + 0x7602, KANJI_LEVEL4, // 瘂 + 0x7608, KANJI_LEVEL4, // 瘈 + 0x7615, KANJI_LEVEL4, // 瘕 + 0x7616, KANJI_LEVEL4, // 瘖 + 0x7619, KANJI_LEVEL4, // 瘙 + 0x761E, KANJI_LEVEL4, // 瘞 + 0x762D, KANJI_LEVEL4, // 瘭 + 0x7635, KANJI_LEVEL4, // 瘵 + 0x7643, KANJI_LEVEL4, // 癃 + 0x764B, KANJI_LEVEL4, // 癋 + 0x7664, KANJI_LEVEL4, // 癀 + 0x7665, KANJI_LEVEL4, // 癥 + 0x766D, KANJI_LEVEL4, // 癭 + 0x766F, KANJI_LEVEL4, // 癯 + 0x7671, KANJI_LEVEL4, // 癱 + 0x7681, KANJI_LEVEL4, // 皁 + 0x769B, KANJI_LEVEL4, // 皛 + 0x769D, KANJI_LEVEL4, // 皝 + 0x769E, KANJI_LEVEL4, // 皞 + 0x76A6, KANJI_LEVEL4, // 皩 + 0x76AA, KANJI_LEVEL4, // 皪 + 0x76B6, KANJI_LEVEL4, // 皶 + 0x76C5, KANJI_LEVEL4, // 盅 + 0x76CC, KANJI_LEVEL4, // 盌 + 0x76CE, KANJI_LEVEL4, // 盎 + 0x76D4, KANJI_LEVEL4, // 盔 + 0x76E6, KANJI_LEVEL4, // 盩 + 0x76F1, KANJI_LEVEL4, // 盱 + 0x76FC, KANJI_LEVEL4, // 盌 + 0x770A, KANJI_LEVEL4, // 眊 + 0x7719, KANJI_LEVEL4, // 眙 + 0x7734, KANJI_LEVEL4, // 眮 + 0x7736, KANJI_LEVEL4, // 眶 + 0x7746, KANJI_LEVEL4, // 睆 + 0x774D, KANJI_LEVEL4, // 睍 + 0x774E, KANJI_LEVEL4, // 睎 + 0x775C, KANJI_LEVEL4, // 睜 + 0x775F, KANJI_LEVEL4, // 睟 + 0x7762, KANJI_LEVEL4, // 睢 + 0x777A, KANJI_LEVEL4, // 睺 + 0x7780, KANJI_LEVEL4, // 瞀 + 0x7794, KANJI_LEVEL4, // 瞔 + 0x77AA, KANJI_LEVEL4, // 瞪 + 0x77E0, KANJI_LEVEL4, // 矠 + 0x782D, KANJI_LEVEL4, // ç ­ + 0xD855, KANJI_LEVEL4, // ᅵ + 0xDC8E, KANJI_LEVEL4, // ᅵ + 0x7843, KANJI_LEVEL4, // 硃 + 0x784E, KANJI_LEVEL4, // 硎 + 0x784F, KANJI_LEVEL4, // 硏 + 0x7851, KANJI_LEVEL4, // 硑 + 0x7868, KANJI_LEVEL4, // 硚 + 0x786E, KANJI_LEVEL4, // ç¡® + 0xFA4B, KANJI_LEVEL4, // 碑 + 0x78B0, KANJI_LEVEL4, // 碰 + 0xD855, KANJI_LEVEL4, // ᅵ + 0xDD0E, KANJI_LEVEL4, // ᅵ + 0x78AD, KANJI_LEVEL4, // 碭 + 0x78E4, KANJI_LEVEL4, // 磀 + 0x78F2, KANJI_LEVEL4, // 磲 + 0x7900, KANJI_LEVEL4, // 瀀 + 0x78F7, KANJI_LEVEL4, // 磷 + 0x791C, KANJI_LEVEL4, // 瀜 + 0x792E, KANJI_LEVEL4, // 瀮 + 0x7931, KANJI_LEVEL4, // 瀱 + 0x7934, KANJI_LEVEL4, // 瀎 + 0xFA4C, KANJI_LEVEL4, // 社 + 0xFA4D, KANJI_LEVEL4, // 祉 + 0x7945, KANJI_LEVEL4, // 祅 + 0x7946, KANJI_LEVEL4, // 祆 + 0xFA4E, KANJI_LEVEL4, // 祈 + 0xFA4F, KANJI_LEVEL4, // 祐 + 0xFA50, KANJI_LEVEL4, // 祖 + 0x795C, KANJI_LEVEL4, // 祜 + 0xFA51, KANJI_LEVEL4, // 祝 + 0xFA19, KANJI_LEVEL4, // ïš™ + 0xFA1A, KANJI_LEVEL4, // ïšš + 0x7979, KANJI_LEVEL4, // 祹 + 0xFA52, KANJI_LEVEL4, // 禍 + 0xFA53, KANJI_LEVEL4, // 禎 + 0xFA1B, KANJI_LEVEL4, // ïš› + 0x7998, KANJI_LEVEL4, // 犘 + 0x79B1, KANJI_LEVEL4, // 犱 + 0x79B8, KANJI_LEVEL4, // 犞 + 0x79C8, KANJI_LEVEL4, // 秈 + 0x79CA, KANJI_LEVEL4, // 秊 + 0xD855, KANJI_LEVEL4, // ᅵ + 0xDF71, KANJI_LEVEL4, // ᅵ + 0x79D4, KANJI_LEVEL4, // 秔 + 0x79DE, KANJI_LEVEL4, // 秞 + 0x79EB, KANJI_LEVEL4, // ç§« + 0x79ED, KANJI_LEVEL4, // ç§­ + 0x7A03, KANJI_LEVEL4, // 皃 + 0xFA54, KANJI_LEVEL4, // 穀 + 0x7A39, KANJI_LEVEL4, // çš¹ + 0x7A5D, KANJI_LEVEL4, // 穝 + 0x7A6D, KANJI_LEVEL4, // ç©­ + 0xFA55, KANJI_LEVEL4, // 突 + 0x7A85, KANJI_LEVEL4, // 窅 + 0x7AA0, KANJI_LEVEL4, // 窠 + 0xD856, KANJI_LEVEL4, // ᅵ + 0xDDC4, KANJI_LEVEL4, // ᅵ + 0x7AB3, KANJI_LEVEL4, // 窳 + 0x7ABB, KANJI_LEVEL4, // 窻 + 0x7ACE, KANJI_LEVEL4, // 竎 + 0x7AEB, KANJI_LEVEL4, // ç«« + 0x7AFD, KANJI_LEVEL4, // 竜 + 0x7B12, KANJI_LEVEL4, // 笒 + 0x7B2D, KANJI_LEVEL4, // 笭 + 0x7B3B, KANJI_LEVEL4, // 笻 + 0x7B47, KANJI_LEVEL4, // 筇 + 0x7B4E, KANJI_LEVEL4, // 筎 + 0x7B60, KANJI_LEVEL4, // ç­  + 0x7B6D, KANJI_LEVEL4, // ç­­ + 0x7B6F, KANJI_LEVEL4, // ç­¯ + 0x7B72, KANJI_LEVEL4, // ç­² + 0x7B9E, KANJI_LEVEL4, // 箞 + 0xFA56, KANJI_LEVEL4, // 節 + 0x7BD7, KANJI_LEVEL4, // 篗 + 0x7BD9, KANJI_LEVEL4, // 篙 + 0x7C01, KANJI_LEVEL4, // 簁 + 0x7C31, KANJI_LEVEL4, // ç°± + 0x7C1E, KANJI_LEVEL4, // 簞 + 0x7C20, KANJI_LEVEL4, // ç°  + 0x7C33, KANJI_LEVEL4, // ç°³ + 0x7C36, KANJI_LEVEL4, // ç°¶ + 0x4264, KANJI_LEVEL4, // 䉀 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDDA1, KANJI_LEVEL4, // ᅵ + 0x7C59, KANJI_LEVEL4, // 籙 + 0x7C6D, KANJI_LEVEL4, // ç±­ + 0x7C79, KANJI_LEVEL4, // ç±¹ + 0x7C8F, KANJI_LEVEL4, // 粏 + 0x7C94, KANJI_LEVEL4, // 粔 + 0x7CA0, KANJI_LEVEL4, // ç²  + 0x7CBC, KANJI_LEVEL4, // 粌 + 0x7CD5, KANJI_LEVEL4, // 糕 + 0x7CD9, KANJI_LEVEL4, // 糙 + 0x7CDD, KANJI_LEVEL4, // 糝 + 0x7D07, KANJI_LEVEL4, // 箇 + 0x7D08, KANJI_LEVEL4, // 玈 + 0x7D13, KANJI_LEVEL4, // 箓 + 0x7D1D, KANJI_LEVEL4, // 玝 + 0x7D23, KANJI_LEVEL4, // 玣 + 0x7D31, KANJI_LEVEL4, // 玱 + 0x7D41, KANJI_LEVEL4, // 絁 + 0x7D48, KANJI_LEVEL4, // 絈 + 0x7D53, KANJI_LEVEL4, // 絓 + 0x7D5C, KANJI_LEVEL4, // 絜 + 0x7D7A, KANJI_LEVEL4, // 絺 + 0x7D83, KANJI_LEVEL4, // 綃 + 0x7D8B, KANJI_LEVEL4, // 綋 + 0x7DA0, KANJI_LEVEL4, // ç¶  + 0x7DA6, KANJI_LEVEL4, // ç¶Š + 0x7DC2, KANJI_LEVEL4, // 緂 + 0x7DCC, KANJI_LEVEL4, // 緌 + 0x7DD6, KANJI_LEVEL4, // 緖 + 0x7DE3, KANJI_LEVEL4, // ç·£ + 0xFA57, KANJI_LEVEL4, // 練 + 0x7E28, KANJI_LEVEL4, // çžš + 0x7E08, KANJI_LEVEL4, // 瞈 + 0x7E11, KANJI_LEVEL4, // 羑 + 0x7E15, KANJI_LEVEL4, // 羕 + 0xFA59, KANJI_LEVEL4, // 繁 + 0x7E47, KANJI_LEVEL4, // 繇 + 0x7E52, KANJI_LEVEL4, // 繒 + 0x7E61, KANJI_LEVEL4, // 繡 + 0x7E8A, KANJI_LEVEL4, // 纊 + 0x7E8D, KANJI_LEVEL4, // 纍 + 0x7F47, KANJI_LEVEL4, // 眇 + 0xFA5A, KANJI_LEVEL4, // 署 + 0x7F91, KANJI_LEVEL4, // 矑 + 0x7F97, KANJI_LEVEL4, // 矗 + 0x7FBF, KANJI_LEVEL4, // 矿 + 0x7FCE, KANJI_LEVEL4, // 翎 + 0x7FDB, KANJI_LEVEL4, // 翛 + 0x7FDF, KANJI_LEVEL4, // 翟 + 0x7FEC, KANJI_LEVEL4, // 翬 + 0x7FEE, KANJI_LEVEL4, // ç¿® + 0x7FFA, KANJI_LEVEL4, // 翺 + 0xFA5B, KANJI_LEVEL4, // 者 + 0x8014, KANJI_LEVEL4, // 耔 + 0x8026, KANJI_LEVEL4, // 耊 + 0x8035, KANJI_LEVEL4, // 耵 + 0x8037, KANJI_LEVEL4, // 耷 + 0x803C, KANJI_LEVEL4, // 而 + 0x80CA, KANJI_LEVEL4, // 胊 + 0x80D7, KANJI_LEVEL4, // 胗 + 0x80E0, KANJI_LEVEL4, // 胠 + 0x80F3, KANJI_LEVEL4, // 胳 + 0x8118, KANJI_LEVEL4, // 脘 + 0x814A, KANJI_LEVEL4, // 腊 + 0x8160, KANJI_LEVEL4, // 腠 + 0x8167, KANJI_LEVEL4, // 腧 + 0x8168, KANJI_LEVEL4, // è…š + 0x816D, KANJI_LEVEL4, // 腭 + 0x81BB, KANJI_LEVEL4, // 膻 + 0x81CA, KANJI_LEVEL4, // 臊 + 0x81CF, KANJI_LEVEL4, // 臏 + 0x81D7, KANJI_LEVEL4, // 臗 + 0xFA5C, KANJI_LEVEL4, // 臭 + 0x4453, KANJI_LEVEL4, // 䑓 + 0x445B, KANJI_LEVEL4, // 䑛 + 0x8260, KANJI_LEVEL4, // 艠 + 0x8274, KANJI_LEVEL4, // 艎 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDEFF, KANJI_LEVEL4, // ᅵ + 0x828E, KANJI_LEVEL4, // 芎 + 0x82A1, KANJI_LEVEL4, // 芡 + 0x82A3, KANJI_LEVEL4, // 芣 + 0x82A4, KANJI_LEVEL4, // 芀 + 0x82A9, KANJI_LEVEL4, // 芩 + 0x82AE, KANJI_LEVEL4, // 芮 + 0x82B7, KANJI_LEVEL4, // 芷 + 0x82BE, KANJI_LEVEL4, // 芟 + 0x82BF, KANJI_LEVEL4, // 芿 + 0x82C6, KANJI_LEVEL4, // 苆 + 0x82D5, KANJI_LEVEL4, // 苕 + 0x82FD, KANJI_LEVEL4, // 苜 + 0x82FE, KANJI_LEVEL4, // 苟 + 0x8300, KANJI_LEVEL4, // 茀 + 0x8301, KANJI_LEVEL4, // 茁 + 0x8362, KANJI_LEVEL4, // 荢 + 0x8322, KANJI_LEVEL4, // 茢 + 0x832D, KANJI_LEVEL4, // 茭 + 0x833A, KANJI_LEVEL4, // 茺 + 0x8343, KANJI_LEVEL4, // 荃 + 0x8347, KANJI_LEVEL4, // 荇 + 0x8351, KANJI_LEVEL4, // 荑 + 0x8355, KANJI_LEVEL4, // 荕 + 0x837D, KANJI_LEVEL4, // 荜 + 0x8386, KANJI_LEVEL4, // 莆 + 0x8392, KANJI_LEVEL4, // 莒 + 0x8398, KANJI_LEVEL4, // 莘 + 0x83A7, KANJI_LEVEL4, // 莧 + 0x83A9, KANJI_LEVEL4, // 莩 + 0x83BF, KANJI_LEVEL4, // 莿 + 0x83C0, KANJI_LEVEL4, // 菀 + 0x83C7, KANJI_LEVEL4, // 菇 + 0x83CF, KANJI_LEVEL4, // 菏 + 0x83D1, KANJI_LEVEL4, // 菑 + 0x83E1, KANJI_LEVEL4, // 菡 + 0x83EA, KANJI_LEVEL4, // 菪 + 0x8401, KANJI_LEVEL4, // 萁 + 0x8406, KANJI_LEVEL4, // 萆 + 0x840A, KANJI_LEVEL4, // 萊 + 0xFA5F, KANJI_LEVEL4, // 著 + 0x8448, KANJI_LEVEL4, // 葈 + 0x845F, KANJI_LEVEL4, // 葟 + 0x8470, KANJI_LEVEL4, // 葰 + 0x8473, KANJI_LEVEL4, // 葳 + 0x8485, KANJI_LEVEL4, // 蒅 + 0x849E, KANJI_LEVEL4, // 蒞 + 0x84AF, KANJI_LEVEL4, // 蒯 + 0x84B4, KANJI_LEVEL4, // è’Ž + 0x84BA, KANJI_LEVEL4, // 蒺 + 0x84C0, KANJI_LEVEL4, // 蓀 + 0x84C2, KANJI_LEVEL4, // 蓂 + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDE40, KANJI_LEVEL4, // ᅵ + 0x8532, KANJI_LEVEL4, // 蔲 + 0x851E, KANJI_LEVEL4, // 蔞 + 0x8523, KANJI_LEVEL4, // 蔣 + 0x852F, KANJI_LEVEL4, // 蔯 + 0x8559, KANJI_LEVEL4, // 蕙 + 0x8564, KANJI_LEVEL4, // è•€ + 0xFA1F, KANJI_LEVEL4, //  + 0x85AD, KANJI_LEVEL4, // 薭 + 0x857A, KANJI_LEVEL4, // 蕺 + 0x858C, KANJI_LEVEL4, // 薌 + 0x858F, KANJI_LEVEL4, // 薏 + 0x85A2, KANJI_LEVEL4, // 薢 + 0x85B0, KANJI_LEVEL4, // 薰 + 0x85CB, KANJI_LEVEL4, // 藋 + 0x85CE, KANJI_LEVEL4, // 藎 + 0x85ED, KANJI_LEVEL4, // 藭 + 0x8612, KANJI_LEVEL4, // 蘒 + 0x85FF, KANJI_LEVEL4, // 藿 + 0x8604, KANJI_LEVEL4, // 蘄 + 0x8605, KANJI_LEVEL4, // 蘅 + 0x8610, KANJI_LEVEL4, // 蘐 + 0xD85C, KANJI_LEVEL4, // ᅵ + 0xDCF4, KANJI_LEVEL4, // ᅵ + 0x8618, KANJI_LEVEL4, // 蘘 + 0x8629, KANJI_LEVEL4, // 蘩 + 0x8638, KANJI_LEVEL4, // 蘞 + 0x8657, KANJI_LEVEL4, // 虗 + 0x865B, KANJI_LEVEL4, // 虛 + 0xF936, KANJI_LEVEL4, //  + 0x8662, KANJI_LEVEL4, // 虢 + 0x459D, KANJI_LEVEL4, // 䖝 + 0x866C, KANJI_LEVEL4, // 虬 + 0x8675, KANJI_LEVEL4, // 虵 + 0x8698, KANJI_LEVEL4, // 蚘 + 0x86B8, KANJI_LEVEL4, // èšž + 0x86FA, KANJI_LEVEL4, // 蛺 + 0x86FC, KANJI_LEVEL4, // 蛌 + 0x86FD, KANJI_LEVEL4, // 蛜 + 0x870B, KANJI_LEVEL4, // 蜋 + 0x8771, KANJI_LEVEL4, // 蝱 + 0x8787, KANJI_LEVEL4, // 螇 + 0x8788, KANJI_LEVEL4, // 螈 + 0x87AC, KANJI_LEVEL4, // 螬 + 0x87AD, KANJI_LEVEL4, // 螭 + 0x87B5, KANJI_LEVEL4, // 螵 + 0x45EA, KANJI_LEVEL4, // 䗪 + 0x87D6, KANJI_LEVEL4, // 蟖 + 0x87EC, KANJI_LEVEL4, // 蟬 + 0x8806, KANJI_LEVEL4, // 蠆 + 0x880A, KANJI_LEVEL4, // 蠊 + 0x8810, KANJI_LEVEL4, // 蠐 + 0x8814, KANJI_LEVEL4, // 蠔 + 0x881F, KANJI_LEVEL4, // 蠟 + 0x8898, KANJI_LEVEL4, // 袘 + 0x88AA, KANJI_LEVEL4, // 袪 + 0x88CA, KANJI_LEVEL4, // 裊 + 0x88CE, KANJI_LEVEL4, // 裎 + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDE84, KANJI_LEVEL4, // ᅵ + 0x88F5, KANJI_LEVEL4, // 裵 + 0x891C, KANJI_LEVEL4, // 耜 + 0xFA60, KANJI_LEVEL4, // ï©  + 0x8918, KANJI_LEVEL4, // 耘 + 0x8919, KANJI_LEVEL4, // 耙 + 0x891A, KANJI_LEVEL4, // 耚 + 0x8927, KANJI_LEVEL4, // 耧 + 0x8930, KANJI_LEVEL4, // 耰 + 0x8932, KANJI_LEVEL4, // 耲 + 0x8939, KANJI_LEVEL4, // 耹 + 0x8940, KANJI_LEVEL4, // 襀 + 0x8994, KANJI_LEVEL4, // 芔 + 0xFA61, KANJI_LEVEL4, // ï©¡ + 0x89D4, KANJI_LEVEL4, // 觔 + 0x89E5, KANJI_LEVEL4, // è§¥ + 0x89F6, KANJI_LEVEL4, // è§¶ + 0x8A12, KANJI_LEVEL4, // èš’ + 0x8A15, KANJI_LEVEL4, // èš• + 0x8A22, KANJI_LEVEL4, // 蚢 + 0x8A37, KANJI_LEVEL4, // èš· + 0x8A47, KANJI_LEVEL4, // 詇 + 0x8A4E, KANJI_LEVEL4, // 詎 + 0x8A5D, KANJI_LEVEL4, // 詝 + 0x8A61, KANJI_LEVEL4, // è©¡ + 0x8A75, KANJI_LEVEL4, // 詵 + 0x8A79, KANJI_LEVEL4, // 詹 + 0x8AA7, KANJI_LEVEL4, // 誧 + 0x8AD0, KANJI_LEVEL4, // 諐 + 0x8ADF, KANJI_LEVEL4, // 諟 + 0x8AF4, KANJI_LEVEL4, // 諎 + 0x8AF6, KANJI_LEVEL4, // è«¶ + 0xFA22, KANJI_LEVEL4, //  + 0xFA62, KANJI_LEVEL4, // ï©¢ + 0xFA63, KANJI_LEVEL4, // ï©£ + 0x8B46, KANJI_LEVEL4, // 譆 + 0x8B54, KANJI_LEVEL4, // 譔 + 0x8B59, KANJI_LEVEL4, // 譙 + 0x8B69, KANJI_LEVEL4, // è­© + 0x8B9D, KANJI_LEVEL4, // 讝 + 0x8C49, KANJI_LEVEL4, // 豉 + 0x8C68, KANJI_LEVEL4, // 豚 + 0xFA64, KANJI_LEVEL4, // ï©€ + 0x8CE1, KANJI_LEVEL4, // 賡 + 0x8CF4, KANJI_LEVEL4, // 賎 + 0x8CF8, KANJI_LEVEL4, // 賞 + 0x8CFE, KANJI_LEVEL4, // 賟 + 0xFA65, KANJI_LEVEL4, // ï©¥ + 0x8D12, KANJI_LEVEL4, // 莒 + 0x8D1B, KANJI_LEVEL4, // 莛 + 0x8DAF, KANJI_LEVEL4, // 趯 + 0x8DCE, KANJI_LEVEL4, // 跎 + 0x8DD1, KANJI_LEVEL4, // 跑 + 0x8DD7, KANJI_LEVEL4, // 跗 + 0x8E20, KANJI_LEVEL4, // èž  + 0x8E23, KANJI_LEVEL4, // 螣 + 0x8E3D, KANJI_LEVEL4, // èžœ + 0x8E70, KANJI_LEVEL4, // è¹° + 0x8E7B, KANJI_LEVEL4, // è¹» + 0xD860, KANJI_LEVEL4, // ᅵ + 0xDE77, KANJI_LEVEL4, // ᅵ + 0x8EC0, KANJI_LEVEL4, // 軀 + 0x4844, KANJI_LEVEL4, // 䡄 + 0x8EFA, KANJI_LEVEL4, // 軺 + 0x8F1E, KANJI_LEVEL4, // 茞 + 0x8F2D, KANJI_LEVEL4, // 茭 + 0x8F36, KANJI_LEVEL4, // 茶 + 0x8F54, KANJI_LEVEL4, // 蜔 + 0xD860, KANJI_LEVEL4, // ᅵ + 0xDFCD, KANJI_LEVEL4, // ᅵ + 0x8FA6, KANJI_LEVEL4, // 蟊 + 0x8FB5, KANJI_LEVEL4, // 蟵 + 0x8FE4, KANJI_LEVEL4, // è¿€ + 0x8FE8, KANJI_LEVEL4, // 迚 + 0x8FEE, KANJI_LEVEL4, // è¿® + 0x9008, KANJI_LEVEL4, // 逈 + 0x902D, KANJI_LEVEL4, // 逭 + 0xFA67, KANJI_LEVEL4, // ï©§ + 0x9088, KANJI_LEVEL4, // 邈 + 0x9095, KANJI_LEVEL4, // 邕 + 0x9097, KANJI_LEVEL4, // 邗 + 0x9099, KANJI_LEVEL4, // 邙 + 0x909B, KANJI_LEVEL4, // 邛 + 0x90A2, KANJI_LEVEL4, // 邢 + 0x90B3, KANJI_LEVEL4, // 邳 + 0x90BE, KANJI_LEVEL4, // 邟 + 0x90C4, KANJI_LEVEL4, // 郄 + 0x90C5, KANJI_LEVEL4, // 郅 + 0x90C7, KANJI_LEVEL4, // 郇 + 0x90D7, KANJI_LEVEL4, // 郗 + 0x90DD, KANJI_LEVEL4, // 郝 + 0x90DE, KANJI_LEVEL4, // 郞 + 0x90EF, KANJI_LEVEL4, // 郯 + 0x90F4, KANJI_LEVEL4, // 郎 + 0xFA26, KANJI_LEVEL4, //  + 0x9114, KANJI_LEVEL4, // 鄔 + 0x9115, KANJI_LEVEL4, // 鄕 + 0x9116, KANJI_LEVEL4, // 鄖 + 0x9122, KANJI_LEVEL4, // 鄢 + 0x9123, KANJI_LEVEL4, // 鄣 + 0x9127, KANJI_LEVEL4, // 鄧 + 0x912F, KANJI_LEVEL4, // 鄯 + 0x9131, KANJI_LEVEL4, // 鄱 + 0x9134, KANJI_LEVEL4, // 鄮 + 0x913D, KANJI_LEVEL4, // 鄜 + 0x9148, KANJI_LEVEL4, // 酈 + 0x915B, KANJI_LEVEL4, // 酛 + 0x9183, KANJI_LEVEL4, // 醃 + 0x919E, KANJI_LEVEL4, // 醞 + 0x91AC, KANJI_LEVEL4, // 醬 + 0x91B1, KANJI_LEVEL4, // 醱 + 0x91BC, KANJI_LEVEL4, // 醌 + 0x91D7, KANJI_LEVEL4, // 釗 + 0x91FB, KANJI_LEVEL4, // 釻 + 0x91E4, KANJI_LEVEL4, // 釀 + 0x91E5, KANJI_LEVEL4, // 釥 + 0x91ED, KANJI_LEVEL4, // 釭 + 0x91F1, KANJI_LEVEL4, // 釱 + 0x9207, KANJI_LEVEL4, // 鈇 + 0x9210, KANJI_LEVEL4, // 鈐 + 0x9238, KANJI_LEVEL4, // 鈞 + 0x9239, KANJI_LEVEL4, // 鈹 + 0x923A, KANJI_LEVEL4, // 鈺 + 0x923C, KANJI_LEVEL4, // 鈌 + 0x9240, KANJI_LEVEL4, // 鉀 + 0x9243, KANJI_LEVEL4, // 鉃 + 0x924F, KANJI_LEVEL4, // 鉏 + 0x9278, KANJI_LEVEL4, // 鉾 + 0x9288, KANJI_LEVEL4, // 銈 + 0x92C2, KANJI_LEVEL4, // 鋂 + 0x92CB, KANJI_LEVEL4, // 鋋 + 0x92CC, KANJI_LEVEL4, // 鋌 + 0x92D3, KANJI_LEVEL4, // 鋓 + 0x92E0, KANJI_LEVEL4, // 鋠 + 0x92FF, KANJI_LEVEL4, // 鋿 + 0x9304, KANJI_LEVEL4, // 錄 + 0x931F, KANJI_LEVEL4, // 錟 + 0x9321, KANJI_LEVEL4, // 錡 + 0x9325, KANJI_LEVEL4, // 錥 + 0x9348, KANJI_LEVEL4, // 鍈 + 0x9349, KANJI_LEVEL4, // 鍉 + 0x934A, KANJI_LEVEL4, // 鍊 + 0x9364, KANJI_LEVEL4, // 鍀 + 0x9365, KANJI_LEVEL4, // 鍥 + 0x936A, KANJI_LEVEL4, // 鍪 + 0x9370, KANJI_LEVEL4, // 鍰 + 0x939B, KANJI_LEVEL4, // 鎛 + 0x93A3, KANJI_LEVEL4, // 鎣 + 0x93BA, KANJI_LEVEL4, // 鎺 + 0x93C6, KANJI_LEVEL4, // 鏆 + 0x93DE, KANJI_LEVEL4, // 鏞 + 0x93DF, KANJI_LEVEL4, // 鏟 + 0x9404, KANJI_LEVEL4, // 鐄 + 0x93FD, KANJI_LEVEL4, // 鏜 + 0x9433, KANJI_LEVEL4, // 鐳 + 0x944A, KANJI_LEVEL4, // 鑊 + 0x9463, KANJI_LEVEL4, // 鑣 + 0x946B, KANJI_LEVEL4, // 鑫 + 0x9471, KANJI_LEVEL4, // 鑱 + 0x9472, KANJI_LEVEL4, // 鑲 + 0x958E, KANJI_LEVEL4, // 閎 + 0x959F, KANJI_LEVEL4, // 閟 + 0x95A6, KANJI_LEVEL4, // 閩 + 0x95A9, KANJI_LEVEL4, // 閩 + 0x95AC, KANJI_LEVEL4, // 閬 + 0x95B6, KANJI_LEVEL4, // 閶 + 0x95BD, KANJI_LEVEL4, // é–œ + 0x95CB, KANJI_LEVEL4, // 闋 + 0x95D0, KANJI_LEVEL4, // 闐 + 0x95D3, KANJI_LEVEL4, // 闓 + 0x49B0, KANJI_LEVEL4, // 䊰 + 0x95DA, KANJI_LEVEL4, // 闚 + 0x95DE, KANJI_LEVEL4, // 闞 + 0x9658, KANJI_LEVEL4, // 陘 + 0x9684, KANJI_LEVEL4, // 隄 + 0xF9DC, KANJI_LEVEL4, // 隆 + 0x969D, KANJI_LEVEL4, // 隝 + 0x96A4, KANJI_LEVEL4, // 隀 + 0x96A5, KANJI_LEVEL4, // 隥 + 0x96D2, KANJI_LEVEL4, // 雒 + 0x96DE, KANJI_LEVEL4, // 雞 + 0xFA68, KANJI_LEVEL4, // 署 + 0x96E9, KANJI_LEVEL4, // 雩 + 0x96EF, KANJI_LEVEL4, // 雯 + 0x9733, KANJI_LEVEL4, // 霳 + 0x973B, KANJI_LEVEL4, // 霻 + 0x974D, KANJI_LEVEL4, // 靍 + 0x974E, KANJI_LEVEL4, // 靎 + 0x974F, KANJI_LEVEL4, // 靏 + 0x975A, KANJI_LEVEL4, // 靚 + 0x976E, KANJI_LEVEL4, // 靮 + 0x9773, KANJI_LEVEL4, // 靳 + 0x9795, KANJI_LEVEL4, // 鞕 + 0x97AE, KANJI_LEVEL4, // 鞮 + 0x97BA, KANJI_LEVEL4, // 鞺 + 0x97C1, KANJI_LEVEL4, // 韁 + 0x97C9, KANJI_LEVEL4, // 韉 + 0x97DE, KANJI_LEVEL4, // 韞 + 0x97DB, KANJI_LEVEL4, // 韛 + 0x97F4, KANJI_LEVEL4, // 韮 + 0xFA69, KANJI_LEVEL4, // ï©© + 0x980A, KANJI_LEVEL4, // 頊 + 0x981E, KANJI_LEVEL4, // 頞 + 0x982B, KANJI_LEVEL4, // é « + 0x9830, KANJI_LEVEL4, // é ° + 0xFA6A, KANJI_LEVEL4, // 頻 + 0x9852, KANJI_LEVEL4, // 顒 + 0x9853, KANJI_LEVEL4, // 顓 + 0x9856, KANJI_LEVEL4, // 顖 + 0x9857, KANJI_LEVEL4, // 顗 + 0x9859, KANJI_LEVEL4, // 顙 + 0x985A, KANJI_LEVEL4, // 顚 + 0xF9D0, KANJI_LEVEL4, // 類 + 0x9865, KANJI_LEVEL4, // é¡¥ + 0x986C, KANJI_LEVEL4, // 顬 + 0x98BA, KANJI_LEVEL4, // 颺 + 0x98C8, KANJI_LEVEL4, // 飈 + 0x98E7, KANJI_LEVEL4, // 飧 + 0x9958, KANJI_LEVEL4, // 饘 + 0x999E, KANJI_LEVEL4, // 銞 + 0x9A02, KANJI_LEVEL4, // 鹂 + 0x9A03, KANJI_LEVEL4, // 隃 + 0x9A24, KANJI_LEVEL4, // 隀 + 0x9A2D, KANJI_LEVEL4, // éš­ + 0x9A2E, KANJI_LEVEL4, // éš® + 0x9A38, KANJI_LEVEL4, // éšž + 0x9A4A, KANJI_LEVEL4, // 驊 + 0x9A4E, KANJI_LEVEL4, // 驎 + 0x9A52, KANJI_LEVEL4, // 驒 + 0x9AB6, KANJI_LEVEL4, // 骶 + 0x9AC1, KANJI_LEVEL4, // 髁 + 0x9AC3, KANJI_LEVEL4, // 髃 + 0x9ACE, KANJI_LEVEL4, // 髎 + 0x9AD6, KANJI_LEVEL4, // 髖 + 0x9AF9, KANJI_LEVEL4, // 髹 + 0x9B02, KANJI_LEVEL4, // 鬂 + 0x9B08, KANJI_LEVEL4, // 鬈 + 0x9B20, KANJI_LEVEL4, // 鬠 + 0x4C17, KANJI_LEVEL4, // 䰗 + 0x9B2D, KANJI_LEVEL4, // 鬭 + 0x9B5E, KANJI_LEVEL4, // 魞 + 0x9B79, KANJI_LEVEL4, // é­¹ + 0x9B66, KANJI_LEVEL4, // é­Š + 0x9B72, KANJI_LEVEL4, // é­² + 0x9B75, KANJI_LEVEL4, // é­µ + 0x9B84, KANJI_LEVEL4, // 鮄 + 0x9B8A, KANJI_LEVEL4, // 鮊 + 0x9B8F, KANJI_LEVEL4, // 鮏 + 0x9B9E, KANJI_LEVEL4, // 鮞 + 0x9BA7, KANJI_LEVEL4, // é®§ + 0x9BC1, KANJI_LEVEL4, // 鯁 + 0x9BCE, KANJI_LEVEL4, // 鯎 + 0x9BE5, KANJI_LEVEL4, // 鯥 + 0x9BF8, KANJI_LEVEL4, // 鯞 + 0x9BFD, KANJI_LEVEL4, // 鯜 + 0x9C00, KANJI_LEVEL4, // 鰀 + 0x9C23, KANJI_LEVEL4, // é°£ + 0x9C41, KANJI_LEVEL4, // 鱁 + 0x9C4F, KANJI_LEVEL4, // 鱏 + 0x9C50, KANJI_LEVEL4, // 鱐 + 0x9C53, KANJI_LEVEL4, // 鱓 + 0x9C63, KANJI_LEVEL4, // é±£ + 0x9C65, KANJI_LEVEL4, // é±¥ + 0x9C77, KANJI_LEVEL4, // é±· + 0x9D1D, KANJI_LEVEL4, // 鎝 + 0x9D1E, KANJI_LEVEL4, // 鮞 + 0x9D43, KANJI_LEVEL4, // 鵃 + 0x9D47, KANJI_LEVEL4, // 鵇 + 0x9D52, KANJI_LEVEL4, // 鵒 + 0x9D63, KANJI_LEVEL4, // éµ£ + 0x9D70, KANJI_LEVEL4, // éµ° + 0x9D7C, KANJI_LEVEL4, // 鵌 + 0x9D8A, KANJI_LEVEL4, // 鶊 + 0x9D96, KANJI_LEVEL4, // 鶖 + 0x9DC0, KANJI_LEVEL4, // 鷀 + 0x9DAC, KANJI_LEVEL4, // 鶬 + 0x9DBC, KANJI_LEVEL4, // é¶Œ + 0x9DD7, KANJI_LEVEL4, // 鷗 + 0xD868, KANJI_LEVEL4, // ᅵ + 0xDD90, KANJI_LEVEL4, // ᅵ + 0x9DE7, KANJI_LEVEL4, // é·§ + 0x9E07, KANJI_LEVEL4, // 龇 + 0x9E15, KANJI_LEVEL4, // 龕 + 0x9E7C, KANJI_LEVEL4, // 鹌 + 0x9E9E, KANJI_LEVEL4, // 麞 + 0x9EA4, KANJI_LEVEL4, // 麀 + 0x9EAC, KANJI_LEVEL4, // 麬 + 0x9EAF, KANJI_LEVEL4, // 麯 + 0x9EB4, KANJI_LEVEL4, // 麎 + 0x9EB5, KANJI_LEVEL4, // 麵 + 0x9EC3, KANJI_LEVEL4, // 黃 + 0x9ED1, KANJI_LEVEL4, // 黑 + 0x9F10, KANJI_LEVEL4, // 錐 + 0x9F39, KANJI_LEVEL4, // 錹 + 0x9F57, KANJI_LEVEL4, // 霗 + 0x9F90, KANJI_LEVEL4, // 韐 + 0x9F94, KANJI_LEVEL4, // 韔 + 0x9F97, KANJI_LEVEL4, // 韗 + 0x9FA2, KANJI_LEVEL4, // 韢 + 0x59F8, KANJI_LEVEL4, // å§ž + 0x5C5B, KANJI_LEVEL4, // 屛 + 0x5E77, KANJI_LEVEL4, // å¹· + 0x7626, KANJI_LEVEL4, // 瘊 + 0x7E6B, KANJI_LEVEL4, // 繫 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDC89, KANJI_LEVEL4, // ᅵ + 0x4E02, KANJI_LEVEL4, // 侂 + 0x4E0F, KANJI_LEVEL4, // 䞏 + 0x4E12, KANJI_LEVEL4, // 侒 + 0x4E29, KANJI_LEVEL4, // äž© + 0x4E2B, KANJI_LEVEL4, // äž« + 0x4E2E, KANJI_LEVEL4, // äž® + 0x4E40, KANJI_LEVEL4, // 乀 + 0x4E47, KANJI_LEVEL4, // 乇 + 0x4E48, KANJI_LEVEL4, // 么 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDCA2, KANJI_LEVEL4, // ᅵ + 0x4E51, KANJI_LEVEL4, // 乑 + 0x3406, KANJI_LEVEL4, // 㐆 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDCA4, KANJI_LEVEL4, // ᅵ + 0x4E5A, KANJI_LEVEL4, // 乚 + 0x4E69, KANJI_LEVEL4, // 乩 + 0x4E9D, KANJI_LEVEL4, // 亝 + 0x342C, KANJI_LEVEL4, // 㐬 + 0x342E, KANJI_LEVEL4, // 㐮 + 0x4EB9, KANJI_LEVEL4, // 亹 + 0x4EBB, KANJI_LEVEL4, // 亻 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDDA2, KANJI_LEVEL4, // ᅵ + 0x4EBC, KANJI_LEVEL4, // 二 + 0x4EC3, KANJI_LEVEL4, // 仃 + 0x4EC8, KANJI_LEVEL4, // 仈 + 0x4ED0, KANJI_LEVEL4, // 仐 + 0x4EEB, KANJI_LEVEL4, // 仫 + 0x4EDA, KANJI_LEVEL4, // 仚 + 0x4EF1, KANJI_LEVEL4, // ä»± + 0x4EF5, KANJI_LEVEL4, // 仵 + 0x4F00, KANJI_LEVEL4, // 䌀 + 0x4F16, KANJI_LEVEL4, // 䌖 + 0x4F64, KANJI_LEVEL4, // 䜀 + 0x4F37, KANJI_LEVEL4, // 䌷 + 0x4F3E, KANJI_LEVEL4, // 䌟 + 0x4F54, KANJI_LEVEL4, // 䜔 + 0x4F58, KANJI_LEVEL4, // 䜘 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDE13, KANJI_LEVEL4, // ᅵ + 0x4F77, KANJI_LEVEL4, // 䜷 + 0x4F78, KANJI_LEVEL4, // 䜞 + 0x4F7A, KANJI_LEVEL4, // 䜺 + 0x4F7D, KANJI_LEVEL4, // 䜜 + 0x4F82, KANJI_LEVEL4, // 䟂 + 0x4F85, KANJI_LEVEL4, // 䟅 + 0x4F92, KANJI_LEVEL4, // 䟒 + 0x4F9A, KANJI_LEVEL4, // 䟚 + 0x4FE6, KANJI_LEVEL4, // 俊 + 0x4FB2, KANJI_LEVEL4, // 䟲 + 0x4FBE, KANJI_LEVEL4, // 䟟 + 0x4FC5, KANJI_LEVEL4, // 俅 + 0x4FCB, KANJI_LEVEL4, // 俋 + 0x4FCF, KANJI_LEVEL4, // 俏 + 0x4FD2, KANJI_LEVEL4, // 俒 + 0x346A, KANJI_LEVEL4, // 㑪 + 0x4FF2, KANJI_LEVEL4, // 俲 + 0x5000, KANJI_LEVEL4, // 倀 + 0x5010, KANJI_LEVEL4, // 倐 + 0x5013, KANJI_LEVEL4, // 倓 + 0x501C, KANJI_LEVEL4, // 倜 + 0x501E, KANJI_LEVEL4, // 倞 + 0x5022, KANJI_LEVEL4, // 倢 + 0x3468, KANJI_LEVEL4, // 㑚 + 0x5042, KANJI_LEVEL4, // 偂 + 0x5046, KANJI_LEVEL4, // 偆 + 0x504E, KANJI_LEVEL4, // 偎 + 0x5053, KANJI_LEVEL4, // 偓 + 0x5057, KANJI_LEVEL4, // 偗 + 0x5063, KANJI_LEVEL4, // 偣 + 0x5066, KANJI_LEVEL4, // 偊 + 0x506A, KANJI_LEVEL4, // 偪 + 0x5070, KANJI_LEVEL4, // 偰 + 0x50A3, KANJI_LEVEL4, // 傣 + 0x5088, KANJI_LEVEL4, // 傈 + 0x5092, KANJI_LEVEL4, // 傒 + 0x5093, KANJI_LEVEL4, // 傓 + 0x5095, KANJI_LEVEL4, // 傕 + 0x5096, KANJI_LEVEL4, // 傖 + 0x509C, KANJI_LEVEL4, // 傜 + 0x50AA, KANJI_LEVEL4, // 傪 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDF2B, KANJI_LEVEL4, // ᅵ + 0x50B1, KANJI_LEVEL4, // 傱 + 0x50BA, KANJI_LEVEL4, // 傺 + 0x50BB, KANJI_LEVEL4, // 傻 + 0x50C4, KANJI_LEVEL4, // 僄 + 0x50C7, KANJI_LEVEL4, // 僇 + 0x50F3, KANJI_LEVEL4, // 僳 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDF81, KANJI_LEVEL4, // ᅵ + 0x50CE, KANJI_LEVEL4, // 僎 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDF71, KANJI_LEVEL4, // ᅵ + 0x50D4, KANJI_LEVEL4, // 僔 + 0x50D9, KANJI_LEVEL4, // 僙 + 0x50E1, KANJI_LEVEL4, // 僡 + 0x50E9, KANJI_LEVEL4, // 僩 + 0x3492, KANJI_LEVEL4, // 㒒 + 0x5108, KANJI_LEVEL4, // 儈 + 0xD840, KANJI_LEVEL4, // ᅵ + 0xDFF9, KANJI_LEVEL4, // ᅵ + 0x5117, KANJI_LEVEL4, // 儗 + 0x511B, KANJI_LEVEL4, // 儛 + 0xD841, KANJI_LEVEL4, // ᅵ + 0xDC4A, KANJI_LEVEL4, // ᅵ + 0x5160, KANJI_LEVEL4, // 兠 + 0xD841, KANJI_LEVEL4, // ᅵ + 0xDD09, KANJI_LEVEL4, // ᅵ + 0x5173, KANJI_LEVEL4, // 关 + 0x5183, KANJI_LEVEL4, // 冃 + 0x518B, KANJI_LEVEL4, // 冋 + 0x34BC, KANJI_LEVEL4, // ã’Œ + 0x5198, KANJI_LEVEL4, // 冘 + 0x51A3, KANJI_LEVEL4, // 冣 + 0x51AD, KANJI_LEVEL4, // 冭 + 0x34C7, KANJI_LEVEL4, // 㓇 + 0x51BC, KANJI_LEVEL4, // 册 + 0xD841, KANJI_LEVEL4, // ᅵ + 0xDDD6, KANJI_LEVEL4, // ᅵ + 0xD841, KANJI_LEVEL4, // ᅵ + 0xDE28, KANJI_LEVEL4, // ᅵ + 0x51F3, KANJI_LEVEL4, // 凳 + 0x51F4, KANJI_LEVEL4, // 凎 + 0x5202, KANJI_LEVEL4, // 刂 + 0x5212, KANJI_LEVEL4, // 划 + 0x5216, KANJI_LEVEL4, // 刖 + 0xD841, KANJI_LEVEL4, // ᅵ + 0xDF4F, KANJI_LEVEL4, // ᅵ + 0x5255, KANJI_LEVEL4, // 剕 + 0x525C, KANJI_LEVEL4, // 剜 + 0x526C, KANJI_LEVEL4, // 剬 + 0x5277, KANJI_LEVEL4, // 剷 + 0x5284, KANJI_LEVEL4, // 劄 + 0x5282, KANJI_LEVEL4, // 劂 + 0xD842, KANJI_LEVEL4, // ᅵ + 0xDC07, KANJI_LEVEL4, // ᅵ + 0x5298, KANJI_LEVEL4, // 劘 + 0xD842, KANJI_LEVEL4, // ᅵ + 0xDC3A, KANJI_LEVEL4, // ᅵ + 0x52A4, KANJI_LEVEL4, // 劀 + 0x52A6, KANJI_LEVEL4, // 劊 + 0x52AF, KANJI_LEVEL4, // 劯 + 0x52BA, KANJI_LEVEL4, // 劺 + 0x52BB, KANJI_LEVEL4, // 劻 + 0x52CA, KANJI_LEVEL4, // 勊 + 0x351F, KANJI_LEVEL4, // 㔟 + 0x52D1, KANJI_LEVEL4, // 勑 + 0xD842, KANJI_LEVEL4, // ᅵ + 0xDCB9, KANJI_LEVEL4, // ᅵ + 0x52F7, KANJI_LEVEL4, // 勷 + 0x530A, KANJI_LEVEL4, // 匊 + 0x530B, KANJI_LEVEL4, // 匋 + 0x5324, KANJI_LEVEL4, // 匀 + 0x5335, KANJI_LEVEL4, // 匵 + 0x533E, KANJI_LEVEL4, // 匟 + 0x5342, KANJI_LEVEL4, // 卂 + 0xD842, KANJI_LEVEL4, // ᅵ + 0xDD7C, KANJI_LEVEL4, // ᅵ + 0xD842, KANJI_LEVEL4, // ᅵ + 0xDD9D, KANJI_LEVEL4, // ᅵ + 0x5367, KANJI_LEVEL4, // 卧 + 0x536C, KANJI_LEVEL4, // 卬 + 0x537A, KANJI_LEVEL4, // 卺 + 0x53A4, KANJI_LEVEL4, // 厀 + 0x53B4, KANJI_LEVEL4, // 厎 + 0xD842, KANJI_LEVEL4, // ᅵ + 0xDED3, KANJI_LEVEL4, // ᅵ + 0x53B7, KANJI_LEVEL4, // 厷 + 0x53C0, KANJI_LEVEL4, // 叀 + 0xD842, KANJI_LEVEL4, // ᅵ + 0xDF1D, KANJI_LEVEL4, // ᅵ + 0x355D, KANJI_LEVEL4, // 㕝 + 0x355E, KANJI_LEVEL4, // 㕞 + 0x53D5, KANJI_LEVEL4, // 叕 + 0x53DA, KANJI_LEVEL4, // 叚 + 0x3563, KANJI_LEVEL4, // 㕣 + 0x53F4, KANJI_LEVEL4, // 収 + 0x53F5, KANJI_LEVEL4, // 叵 + 0x5455, KANJI_LEVEL4, // 呕 + 0x5424, KANJI_LEVEL4, // 吀 + 0x5428, KANJI_LEVEL4, // 吚 + 0x356E, KANJI_LEVEL4, // 㕮 + 0x5443, KANJI_LEVEL4, // 呃 + 0x5462, KANJI_LEVEL4, // 呢 + 0x5466, KANJI_LEVEL4, // 告 + 0x546C, KANJI_LEVEL4, // 呬 + 0x548A, KANJI_LEVEL4, // 咊 + 0x548D, KANJI_LEVEL4, // 咍 + 0x5495, KANJI_LEVEL4, // 咕 + 0x54A0, KANJI_LEVEL4, // 咠 + 0x54A6, KANJI_LEVEL4, // å’Š + 0x54AD, KANJI_LEVEL4, // 咭 + 0x54AE, KANJI_LEVEL4, // 咮 + 0x54B7, KANJI_LEVEL4, // 咷 + 0x54BA, KANJI_LEVEL4, // 咺 + 0x54BF, KANJI_LEVEL4, // 咿 + 0x54C3, KANJI_LEVEL4, // 哃 + 0xD843, KANJI_LEVEL4, // ᅵ + 0xDD45, KANJI_LEVEL4, // ᅵ + 0x54EC, KANJI_LEVEL4, // 哬 + 0x54EF, KANJI_LEVEL4, // 哯 + 0x54F1, KANJI_LEVEL4, // 哱 + 0x54F3, KANJI_LEVEL4, // 哳 + 0x5500, KANJI_LEVEL4, // 唀 + 0x5501, KANJI_LEVEL4, // 唁 + 0x5509, KANJI_LEVEL4, // 唉 + 0x553C, KANJI_LEVEL4, // 唌 + 0x5541, KANJI_LEVEL4, // 啁 + 0x35A6, KANJI_LEVEL4, // ã–Š + 0x5547, KANJI_LEVEL4, // 啇 + 0x554A, KANJI_LEVEL4, // 啊 + 0x35A8, KANJI_LEVEL4, // ã–š + 0x5560, KANJI_LEVEL4, // 啠 + 0x5561, KANJI_LEVEL4, // 啡 + 0x5564, KANJI_LEVEL4, // å•€ + 0xD843, KANJI_LEVEL4, // ᅵ + 0xDDE1, KANJI_LEVEL4, // ᅵ + 0x557D, KANJI_LEVEL4, // 啜 + 0x5582, KANJI_LEVEL4, // 喂 + 0x5588, KANJI_LEVEL4, // 喈 + 0x5591, KANJI_LEVEL4, // 喑 + 0x35C5, KANJI_LEVEL4, // 㗅 + 0x55D2, KANJI_LEVEL4, // 嗒 + 0xD843, KANJI_LEVEL4, // ᅵ + 0xDE95, KANJI_LEVEL4, // ᅵ + 0xD843, KANJI_LEVEL4, // ᅵ + 0xDE6D, KANJI_LEVEL4, // ᅵ + 0x55BF, KANJI_LEVEL4, // 喿 + 0x55C9, KANJI_LEVEL4, // 嗉 + 0x55CC, KANJI_LEVEL4, // 嗌 + 0x55D1, KANJI_LEVEL4, // 嗑 + 0x55DD, KANJI_LEVEL4, // 嗝 + 0x35DA, KANJI_LEVEL4, // 㗚 + 0x55E2, KANJI_LEVEL4, // 嗢 + 0xD843, KANJI_LEVEL4, // ᅵ + 0xDE64, KANJI_LEVEL4, // ᅵ + 0x55E9, KANJI_LEVEL4, // 嗩 + 0x5628, KANJI_LEVEL4, // 嘚 + 0xD843, KANJI_LEVEL4, // ᅵ + 0xDF5F, KANJI_LEVEL4, // ᅵ + 0x5607, KANJI_LEVEL4, // 嘇 + 0x5610, KANJI_LEVEL4, // 嘐 + 0x5630, KANJI_LEVEL4, // 嘰 + 0x5637, KANJI_LEVEL4, // 嘷 + 0x35F4, KANJI_LEVEL4, // ã—Ž + 0x563D, KANJI_LEVEL4, // 嘜 + 0x563F, KANJI_LEVEL4, // 嘿 + 0x5640, KANJI_LEVEL4, // 噀 + 0x5647, KANJI_LEVEL4, // 噇 + 0x565E, KANJI_LEVEL4, // 噞 + 0x5660, KANJI_LEVEL4, // 噠 + 0x566D, KANJI_LEVEL4, // 噭 + 0x3605, KANJI_LEVEL4, // 㘅 + 0x5688, KANJI_LEVEL4, // 嚈 + 0x568C, KANJI_LEVEL4, // 嚌 + 0x5695, KANJI_LEVEL4, // 嚕 + 0x569A, KANJI_LEVEL4, // 嚚 + 0x569D, KANJI_LEVEL4, // 嚝 + 0x56A8, KANJI_LEVEL4, // åšš + 0x56AD, KANJI_LEVEL4, // 嚭 + 0x56B2, KANJI_LEVEL4, // 嚲 + 0x56C5, KANJI_LEVEL4, // 囅 + 0x56CD, KANJI_LEVEL4, // 囍 + 0x56DF, KANJI_LEVEL4, // 囟 + 0x56E8, KANJI_LEVEL4, // 囚 + 0x56F6, KANJI_LEVEL4, // 囶 + 0x56F7, KANJI_LEVEL4, // 囷 + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDE01, KANJI_LEVEL4, // ᅵ + 0x5715, KANJI_LEVEL4, // 圕 + 0x5723, KANJI_LEVEL4, // 圣 + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDE55, KANJI_LEVEL4, // ᅵ + 0x5729, KANJI_LEVEL4, // 圩 + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDE7B, KANJI_LEVEL4, // ᅵ + 0x5745, KANJI_LEVEL4, // 坅 + 0x5746, KANJI_LEVEL4, // 坆 + 0x574C, KANJI_LEVEL4, // 坌 + 0x574D, KANJI_LEVEL4, // 坍 + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDE74, KANJI_LEVEL4, // ᅵ + 0x5768, KANJI_LEVEL4, // 坚 + 0x576F, KANJI_LEVEL4, // 坯 + 0x5773, KANJI_LEVEL4, // 坳 + 0x5774, KANJI_LEVEL4, // 坎 + 0x5775, KANJI_LEVEL4, // 坵 + 0x577B, KANJI_LEVEL4, // 坻 + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDEE4, KANJI_LEVEL4, // ᅵ + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDED7, KANJI_LEVEL4, // ᅵ + 0x57AC, KANJI_LEVEL4, // 垬 + 0x579A, KANJI_LEVEL4, // 垚 + 0x579D, KANJI_LEVEL4, // 垝 + 0x579E, KANJI_LEVEL4, // 垞 + 0x57A8, KANJI_LEVEL4, // 垚 + 0x57D7, KANJI_LEVEL4, // 埗 + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDEFD, KANJI_LEVEL4, // ᅵ + 0x57CC, KANJI_LEVEL4, // 埌 + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDF36, KANJI_LEVEL4, // ᅵ + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDF44, KANJI_LEVEL4, // ᅵ + 0x57DE, KANJI_LEVEL4, // 埞 + 0x57E6, KANJI_LEVEL4, // 埊 + 0x57F0, KANJI_LEVEL4, // 埰 + 0x364A, KANJI_LEVEL4, // 㙊 + 0x57F8, KANJI_LEVEL4, // 埞 + 0x57FB, KANJI_LEVEL4, // 埻 + 0x57FD, KANJI_LEVEL4, // 埜 + 0x5804, KANJI_LEVEL4, // 堄 + 0x581E, KANJI_LEVEL4, // 堞 + 0x5820, KANJI_LEVEL4, // å   + 0x5827, KANJI_LEVEL4, // å § + 0x5832, KANJI_LEVEL4, // å ² + 0x5839, KANJI_LEVEL4, // å ¹ + 0xD844, KANJI_LEVEL4, // ᅵ + 0xDFC4, KANJI_LEVEL4, // ᅵ + 0x5849, KANJI_LEVEL4, // 塉 + 0x584C, KANJI_LEVEL4, // 塌 + 0x5867, KANJI_LEVEL4, // å¡§ + 0x588A, KANJI_LEVEL4, // 墊 + 0x588B, KANJI_LEVEL4, // 墋 + 0x588D, KANJI_LEVEL4, // 墍 + 0x588F, KANJI_LEVEL4, // 墏 + 0x5890, KANJI_LEVEL4, // 墐 + 0x5894, KANJI_LEVEL4, // 墔 + 0x589D, KANJI_LEVEL4, // 墝 + 0x58AA, KANJI_LEVEL4, // 墪 + 0x58B1, KANJI_LEVEL4, // 墱 + 0xD845, KANJI_LEVEL4, // ᅵ + 0xDC6D, KANJI_LEVEL4, // ᅵ + 0x58C3, KANJI_LEVEL4, // 壃 + 0x58CD, KANJI_LEVEL4, // 壍 + 0x58E2, KANJI_LEVEL4, // 壢 + 0x58F3, KANJI_LEVEL4, // 壳 + 0x58F4, KANJI_LEVEL4, // 壎 + 0x5905, KANJI_LEVEL4, // 倅 + 0x5906, KANJI_LEVEL4, // 倆 + 0x590B, KANJI_LEVEL4, // 個 + 0x590D, KANJI_LEVEL4, // 倍 + 0x5914, KANJI_LEVEL4, // 倔 + 0x5924, KANJI_LEVEL4, // 倀 + 0xD845, KANJI_LEVEL4, // ᅵ + 0xDDD7, KANJI_LEVEL4, // ᅵ + 0x3691, KANJI_LEVEL4, // 㚑 + 0x593D, KANJI_LEVEL4, // 倜 + 0x3699, KANJI_LEVEL4, // 㚙 + 0x5946, KANJI_LEVEL4, // 奆 + 0x3696, KANJI_LEVEL4, // 㚖 + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDC29, KANJI_LEVEL4, // ᅵ + 0x595B, KANJI_LEVEL4, // 奛 + 0x595F, KANJI_LEVEL4, // 奟 + 0xD845, KANJI_LEVEL4, // ᅵ + 0xDE47, KANJI_LEVEL4, // ᅵ + 0x5975, KANJI_LEVEL4, // 奵 + 0x5976, KANJI_LEVEL4, // 奶 + 0x597C, KANJI_LEVEL4, // 奌 + 0x599F, KANJI_LEVEL4, // 功 + 0x59AE, KANJI_LEVEL4, // 劮 + 0x59BC, KANJI_LEVEL4, // 劌 + 0x59C8, KANJI_LEVEL4, // 姈 + 0x59CD, KANJI_LEVEL4, // 姍 + 0x59DE, KANJI_LEVEL4, // 姞 + 0x59E3, KANJI_LEVEL4, // å§£ + 0x59E4, KANJI_LEVEL4, // å§€ + 0x59E7, KANJI_LEVEL4, // å§§ + 0x59EE, KANJI_LEVEL4, // å§® + 0xD845, KANJI_LEVEL4, // ᅵ + 0xDF06, KANJI_LEVEL4, // ᅵ + 0xD845, KANJI_LEVEL4, // ᅵ + 0xDF42, KANJI_LEVEL4, // ᅵ + 0x36CF, KANJI_LEVEL4, // 㛏 + 0x5A0C, KANJI_LEVEL4, // 嚌 + 0x5A0D, KANJI_LEVEL4, // 嚍 + 0x5A17, KANJI_LEVEL4, // åš— + 0x5A27, KANJI_LEVEL4, // åš§ + 0x5A2D, KANJI_LEVEL4, // åš­ + 0x5A55, KANJI_LEVEL4, // 婕 + 0x5A65, KANJI_LEVEL4, // å©¥ + 0x5A7A, KANJI_LEVEL4, // 婺 + 0x5A8B, KANJI_LEVEL4, // 媋 + 0x5A9C, KANJI_LEVEL4, // 媜 + 0x5A9F, KANJI_LEVEL4, // 媟 + 0x5AA0, KANJI_LEVEL4, // 媠 + 0x5AA2, KANJI_LEVEL4, // 媢 + 0x5AB1, KANJI_LEVEL4, // 媱 + 0x5AB3, KANJI_LEVEL4, // 媳 + 0x5AB5, KANJI_LEVEL4, // 媵 + 0x5ABA, KANJI_LEVEL4, // 媺 + 0x5ABF, KANJI_LEVEL4, // 媿 + 0x5ADA, KANJI_LEVEL4, // 嫚 + 0x5ADC, KANJI_LEVEL4, // 嫜 + 0x5AE0, KANJI_LEVEL4, // å«  + 0x5AE5, KANJI_LEVEL4, // å«¥ + 0x5AF0, KANJI_LEVEL4, // å«° + 0x5AEE, KANJI_LEVEL4, // å«® + 0x5AF5, KANJI_LEVEL4, // 嫵 + 0x5B00, KANJI_LEVEL4, // 嬀 + 0x5B08, KANJI_LEVEL4, // 嬈 + 0x5B17, KANJI_LEVEL4, // 嬗 + 0x5B34, KANJI_LEVEL4, // 嬎 + 0x5B2D, KANJI_LEVEL4, // 嬭 + 0x5B4C, KANJI_LEVEL4, // 孌 + 0x5B52, KANJI_LEVEL4, // 孒 + 0x5B68, KANJI_LEVEL4, // å­š + 0x5B6F, KANJI_LEVEL4, // å­¯ + 0x5B7C, KANJI_LEVEL4, // å­Œ + 0x5B7F, KANJI_LEVEL4, // å­¿ + 0x5B81, KANJI_LEVEL4, // 宁 + 0x5B84, KANJI_LEVEL4, // 宄 + 0xD846, KANJI_LEVEL4, // ᅵ + 0xDDC3, KANJI_LEVEL4, // ᅵ + 0x5B96, KANJI_LEVEL4, // 宖 + 0x5BAC, KANJI_LEVEL4, // 宬 + 0x3761, KANJI_LEVEL4, // 㝡 + 0x5BC0, KANJI_LEVEL4, // 寀 + 0x3762, KANJI_LEVEL4, // 㝢 + 0x5BCE, KANJI_LEVEL4, // 寎 + 0x5BD6, KANJI_LEVEL4, // 寖 + 0x376C, KANJI_LEVEL4, // 㝬 + 0x376B, KANJI_LEVEL4, // 㝫 + 0x5BF1, KANJI_LEVEL4, // 寱 + 0x5BFD, KANJI_LEVEL4, // 寜 + 0x3775, KANJI_LEVEL4, // 㝵 + 0x5C03, KANJI_LEVEL4, // 尃 + 0x5C29, KANJI_LEVEL4, // å°© + 0x5C30, KANJI_LEVEL4, // å°° + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDC56, KANJI_LEVEL4, // ᅵ + 0x5C5F, KANJI_LEVEL4, // 屟 + 0x5C63, KANJI_LEVEL4, // å±£ + 0x5C67, KANJI_LEVEL4, // å±§ + 0x5C68, KANJI_LEVEL4, // 屚 + 0x5C69, KANJI_LEVEL4, // 屩 + 0x5C70, KANJI_LEVEL4, // å±° + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDD2D, KANJI_LEVEL4, // ᅵ + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDD45, KANJI_LEVEL4, // ᅵ + 0x5C7C, KANJI_LEVEL4, // 屌 + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDD78, KANJI_LEVEL4, // ᅵ + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDD62, KANJI_LEVEL4, // ᅵ + 0x5C88, KANJI_LEVEL4, // 岈 + 0x5C8A, KANJI_LEVEL4, // 岊 + 0x37C1, KANJI_LEVEL4, // 㟁 + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDDA1, KANJI_LEVEL4, // ᅵ + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDD9C, KANJI_LEVEL4, // ᅵ + 0x5CA0, KANJI_LEVEL4, // å²  + 0x5CA2, KANJI_LEVEL4, // å²¢ + 0x5CA6, KANJI_LEVEL4, // 岊 + 0x5CA7, KANJI_LEVEL4, // å²§ + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDD92, KANJI_LEVEL4, // ᅵ + 0x5CAD, KANJI_LEVEL4, // å²­ + 0x5CB5, KANJI_LEVEL4, // å²µ + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDDB7, KANJI_LEVEL4, // ᅵ + 0x5CC9, KANJI_LEVEL4, // 峉 + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDDE0, KANJI_LEVEL4, // ᅵ + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDE33, KANJI_LEVEL4, // ᅵ + 0x5D06, KANJI_LEVEL4, // 历 + 0x5D10, KANJI_LEVEL4, // 厐 + 0x5D2B, KANJI_LEVEL4, // 厫 + 0x5D1D, KANJI_LEVEL4, // 厝 + 0x5D20, KANJI_LEVEL4, // 厠 + 0x5D24, KANJI_LEVEL4, // 厀 + 0x5D26, KANJI_LEVEL4, // 厊 + 0x5D31, KANJI_LEVEL4, // 厱 + 0x5D39, KANJI_LEVEL4, // 厹 + 0x5D42, KANJI_LEVEL4, // 嵂 + 0x37E8, KANJI_LEVEL4, // 㟚 + 0x5D61, KANJI_LEVEL4, // 嵡 + 0x5D6A, KANJI_LEVEL4, // 嵪 + 0x37F4, KANJI_LEVEL4, // 㟎 + 0x5D70, KANJI_LEVEL4, // åµ° + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDF1E, KANJI_LEVEL4, // ᅵ + 0x37FD, KANJI_LEVEL4, // 㟜 + 0x5D88, KANJI_LEVEL4, // 嶈 + 0x3800, KANJI_LEVEL4, // 㠀 + 0x5D92, KANJI_LEVEL4, // 嶒 + 0x5D94, KANJI_LEVEL4, // 嶔 + 0x5D97, KANJI_LEVEL4, // 嶗 + 0x5D99, KANJI_LEVEL4, // 嶙 + 0x5DB0, KANJI_LEVEL4, // å¶° + 0x5DB2, KANJI_LEVEL4, // å¶² + 0x5DB4, KANJI_LEVEL4, // å¶Ž + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDF76, KANJI_LEVEL4, // ᅵ + 0x5DB9, KANJI_LEVEL4, // å¶¹ + 0x5DD1, KANJI_LEVEL4, // 巑 + 0x5DD7, KANJI_LEVEL4, // 巗 + 0x5DD8, KANJI_LEVEL4, // 巘 + 0x5DE0, KANJI_LEVEL4, // å·  + 0xD847, KANJI_LEVEL4, // ᅵ + 0xDFFA, KANJI_LEVEL4, // ᅵ + 0x5DE4, KANJI_LEVEL4, // å·€ + 0x5DE9, KANJI_LEVEL4, // å·© + 0x382F, KANJI_LEVEL4, // ã ¯ + 0x5E00, KANJI_LEVEL4, // 垀 + 0x3836, KANJI_LEVEL4, // ã ¶ + 0x5E12, KANJI_LEVEL4, // åž’ + 0x5E15, KANJI_LEVEL4, // åž• + 0x3840, KANJI_LEVEL4, // 㡀 + 0x5E1F, KANJI_LEVEL4, // 垟 + 0x5E2E, KANJI_LEVEL4, // åž® + 0x5E3E, KANJI_LEVEL4, // 垟 + 0x5E49, KANJI_LEVEL4, // 幉 + 0x385C, KANJI_LEVEL4, // 㡜 + 0x5E56, KANJI_LEVEL4, // 幖 + 0x3861, KANJI_LEVEL4, // ã¡¡ + 0x5E6B, KANJI_LEVEL4, // 幫 + 0x5E6C, KANJI_LEVEL4, // 幬 + 0x5E6D, KANJI_LEVEL4, // å¹­ + 0x5E6E, KANJI_LEVEL4, // å¹® + 0xD848, KANJI_LEVEL4, // ᅵ + 0xDD7B, KANJI_LEVEL4, // ᅵ + 0x5EA5, KANJI_LEVEL4, // 庥 + 0x5EAA, KANJI_LEVEL4, // 庪 + 0x5EAC, KANJI_LEVEL4, // 庬 + 0x5EB9, KANJI_LEVEL4, // 庹 + 0x5EBF, KANJI_LEVEL4, // 庿 + 0x5EC6, KANJI_LEVEL4, // 廆 + 0x5ED2, KANJI_LEVEL4, // 廒 + 0x5ED9, KANJI_LEVEL4, // 廙 + 0xD848, KANJI_LEVEL4, // ᅵ + 0xDF1E, KANJI_LEVEL4, // ᅵ + 0x5EFD, KANJI_LEVEL4, // 廜 + 0x5F08, KANJI_LEVEL4, // 匈 + 0x5F0E, KANJI_LEVEL4, // 匎 + 0x5F1C, KANJI_LEVEL4, // 匜 + 0xD848, KANJI_LEVEL4, // ᅵ + 0xDFAD, KANJI_LEVEL4, // ᅵ + 0x5F1E, KANJI_LEVEL4, // 匞 + 0x5F47, KANJI_LEVEL4, // 圇 + 0x5F63, KANJI_LEVEL4, // 圣 + 0x5F72, KANJI_LEVEL4, // 圲 + 0x5F7E, KANJI_LEVEL4, // 土 + 0x5F8F, KANJI_LEVEL4, // 埏 + 0x5FA2, KANJI_LEVEL4, // 埢 + 0x5FA4, KANJI_LEVEL4, // 埀 + 0x5FB8, KANJI_LEVEL4, // 埞 + 0x5FC4, KANJI_LEVEL4, // 忄 + 0x38FA, KANJI_LEVEL4, // 㣺 + 0x5FC7, KANJI_LEVEL4, // 忇 + 0x5FCB, KANJI_LEVEL4, // 忋 + 0x5FD2, KANJI_LEVEL4, // 忒 + 0x5FD3, KANJI_LEVEL4, // 忓 + 0x5FD4, KANJI_LEVEL4, // 忔 + 0x5FE2, KANJI_LEVEL4, // å¿¢ + 0x5FEE, KANJI_LEVEL4, // å¿® + 0x5FEF, KANJI_LEVEL4, // 忯 + 0x5FF3, KANJI_LEVEL4, // 忳 + 0x5FFC, KANJI_LEVEL4, // 忌 + 0x3917, KANJI_LEVEL4, // 〗 + 0x6017, KANJI_LEVEL4, // 怗 + 0x6022, KANJI_LEVEL4, // 怢 + 0x6024, KANJI_LEVEL4, // 怀 + 0x391A, KANJI_LEVEL4, // 〚 + 0x604C, KANJI_LEVEL4, // 恌 + 0x607F, KANJI_LEVEL4, // 恿 + 0x608A, KANJI_LEVEL4, // 悊 + 0x6095, KANJI_LEVEL4, // 悕 + 0x60A8, KANJI_LEVEL4, // 悚 + 0xD849, KANJI_LEVEL4, // ᅵ + 0xDEF3, KANJI_LEVEL4, // ᅵ + 0x60B0, KANJI_LEVEL4, // 悰 + 0x60B1, KANJI_LEVEL4, // 悱 + 0x60BE, KANJI_LEVEL4, // 悟 + 0x60C8, KANJI_LEVEL4, // 惈 + 0x60D9, KANJI_LEVEL4, // 惙 + 0x60DB, KANJI_LEVEL4, // 惛 + 0x60EE, KANJI_LEVEL4, // 惮 + 0x60F2, KANJI_LEVEL4, // 惲 + 0x60F5, KANJI_LEVEL4, // 惵 + 0x6110, KANJI_LEVEL4, // 愐 + 0x6112, KANJI_LEVEL4, // 愒 + 0x6113, KANJI_LEVEL4, // 愓 + 0x6119, KANJI_LEVEL4, // 愙 + 0x611E, KANJI_LEVEL4, // 愞 + 0x613A, KANJI_LEVEL4, // 愺 + 0x396F, KANJI_LEVEL4, // 㥯 + 0x6141, KANJI_LEVEL4, // 慁 + 0x6146, KANJI_LEVEL4, // 慆 + 0x6160, KANJI_LEVEL4, // 慠 + 0x617C, KANJI_LEVEL4, // æ…Œ + 0xD84A, KANJI_LEVEL4, // ᅵ + 0xDC5B, KANJI_LEVEL4, // ᅵ + 0x6192, KANJI_LEVEL4, // 憒 + 0x6193, KANJI_LEVEL4, // 憓 + 0x6197, KANJI_LEVEL4, // 憗 + 0x6198, KANJI_LEVEL4, // 憘 + 0x61A5, KANJI_LEVEL4, // 憥 + 0x61A8, KANJI_LEVEL4, // 憚 + 0x61AD, KANJI_LEVEL4, // 憭 + 0xD84A, KANJI_LEVEL4, // ᅵ + 0xDCAB, KANJI_LEVEL4, // ᅵ + 0x61D5, KANJI_LEVEL4, // 懕 + 0x61DD, KANJI_LEVEL4, // 懝 + 0x61DF, KANJI_LEVEL4, // 懟 + 0x61F5, KANJI_LEVEL4, // 懵 + 0xD84A, KANJI_LEVEL4, // ᅵ + 0xDD8F, KANJI_LEVEL4, // ᅵ + 0x6215, KANJI_LEVEL4, // 戕 + 0x6223, KANJI_LEVEL4, // 戣 + 0x6229, KANJI_LEVEL4, // 戩 + 0x6246, KANJI_LEVEL4, // 扆 + 0x624C, KANJI_LEVEL4, // 扌 + 0x6251, KANJI_LEVEL4, // 扑 + 0x6252, KANJI_LEVEL4, // 扒 + 0x6261, KANJI_LEVEL4, // 扡 + 0x6264, KANJI_LEVEL4, // 所 + 0x627B, KANJI_LEVEL4, // 扻 + 0x626D, KANJI_LEVEL4, // 扭 + 0x6273, KANJI_LEVEL4, // 扳 + 0x6299, KANJI_LEVEL4, // 抙 + 0x62A6, KANJI_LEVEL4, // 把 + 0x62D5, KANJI_LEVEL4, // 拕 + 0xD84A, KANJI_LEVEL4, // ᅵ + 0xDEB8, KANJI_LEVEL4, // ᅵ + 0x62FD, KANJI_LEVEL4, // 拜 + 0x6303, KANJI_LEVEL4, // 挃 + 0x630D, KANJI_LEVEL4, // 挍 + 0x6310, KANJI_LEVEL4, // 挐 + 0xD84A, KANJI_LEVEL4, // ᅵ + 0xDF4F, KANJI_LEVEL4, // ᅵ + 0xD84A, KANJI_LEVEL4, // ᅵ + 0xDF50, KANJI_LEVEL4, // ᅵ + 0x6332, KANJI_LEVEL4, // 挲 + 0x6335, KANJI_LEVEL4, // 挵 + 0x633B, KANJI_LEVEL4, // 挻 + 0x633C, KANJI_LEVEL4, // 挌 + 0x6341, KANJI_LEVEL4, // 捁 + 0x6344, KANJI_LEVEL4, // 捄 + 0x634E, KANJI_LEVEL4, // 捎 + 0xD84A, KANJI_LEVEL4, // ᅵ + 0xDF46, KANJI_LEVEL4, // ᅵ + 0x6359, KANJI_LEVEL4, // 捙 + 0xD84B, KANJI_LEVEL4, // ᅵ + 0xDC1D, KANJI_LEVEL4, // ᅵ + 0xD84A, KANJI_LEVEL4, // ᅵ + 0xDFA6, KANJI_LEVEL4, // ᅵ + 0x636C, KANJI_LEVEL4, // 捬 + 0x6384, KANJI_LEVEL4, // 掄 + 0x6399, KANJI_LEVEL4, // 掙 + 0xD84B, KANJI_LEVEL4, // ᅵ + 0xDC24, KANJI_LEVEL4, // ᅵ + 0x6394, KANJI_LEVEL4, // 掔 + 0x63BD, KANJI_LEVEL4, // 掜 + 0x63F7, KANJI_LEVEL4, // 揷 + 0x63D4, KANJI_LEVEL4, // 揔 + 0x63D5, KANJI_LEVEL4, // 揕 + 0x63DC, KANJI_LEVEL4, // 揜 + 0x63E0, KANJI_LEVEL4, // 揠 + 0x63EB, KANJI_LEVEL4, // 揫 + 0x63EC, KANJI_LEVEL4, // 揬 + 0x63F2, KANJI_LEVEL4, // 揲 + 0x6409, KANJI_LEVEL4, // 搉 + 0x641E, KANJI_LEVEL4, // 搞 + 0x6425, KANJI_LEVEL4, // 搥 + 0x6429, KANJI_LEVEL4, // 搩 + 0x642F, KANJI_LEVEL4, // 搯 + 0x645A, KANJI_LEVEL4, // 摚 + 0x645B, KANJI_LEVEL4, // 摛 + 0x645D, KANJI_LEVEL4, // 摝 + 0x6473, KANJI_LEVEL4, // 摳 + 0x647D, KANJI_LEVEL4, // 摜 + 0x6487, KANJI_LEVEL4, // 撇 + 0x6491, KANJI_LEVEL4, // 撑 + 0x649D, KANJI_LEVEL4, // 撝 + 0x649F, KANJI_LEVEL4, // 撟 + 0x64CB, KANJI_LEVEL4, // 擋 + 0x64CC, KANJI_LEVEL4, // 擌 + 0x64D5, KANJI_LEVEL4, // 擕 + 0x64D7, KANJI_LEVEL4, // 擗 + 0xD84B, KANJI_LEVEL4, // ᅵ + 0xDDE1, KANJI_LEVEL4, // ᅵ + 0x64E4, KANJI_LEVEL4, // æ“€ + 0x64E5, KANJI_LEVEL4, // 擥 + 0x64FF, KANJI_LEVEL4, // 擿 + 0x6504, KANJI_LEVEL4, // 攄 + 0x3A6E, KANJI_LEVEL4, // ã©® + 0x650F, KANJI_LEVEL4, // 攏 + 0x6514, KANJI_LEVEL4, // 攔 + 0x6516, KANJI_LEVEL4, // 攖 + 0x3A73, KANJI_LEVEL4, // 㩳 + 0x651E, KANJI_LEVEL4, // 攞 + 0x6532, KANJI_LEVEL4, // 攲 + 0x6544, KANJI_LEVEL4, // 敄 + 0x6554, KANJI_LEVEL4, // 敔 + 0x656B, KANJI_LEVEL4, // 敫 + 0x657A, KANJI_LEVEL4, // 敺 + 0x6581, KANJI_LEVEL4, // 斁 + 0x6584, KANJI_LEVEL4, // 斄 + 0x6585, KANJI_LEVEL4, // 斅 + 0x658A, KANJI_LEVEL4, // 斊 + 0x65B2, KANJI_LEVEL4, // 斲 + 0x65B5, KANJI_LEVEL4, // 斵 + 0x65B8, KANJI_LEVEL4, // æ–ž + 0x65BF, KANJI_LEVEL4, // 斿 + 0x65C2, KANJI_LEVEL4, // 旂 + 0x65C9, KANJI_LEVEL4, // 旉 + 0x65D4, KANJI_LEVEL4, // 旔 + 0x3AD6, KANJI_LEVEL4, // 㫖 + 0x65F2, KANJI_LEVEL4, // 旲 + 0x65F9, KANJI_LEVEL4, // 旹 + 0x65FC, KANJI_LEVEL4, // æ—Œ + 0x6604, KANJI_LEVEL4, // 昄 + 0x6608, KANJI_LEVEL4, // 昈 + 0x6621, KANJI_LEVEL4, // 昡 + 0x662A, KANJI_LEVEL4, // 昪 + 0x6645, KANJI_LEVEL4, // 晅 + 0x6651, KANJI_LEVEL4, // 晑 + 0x664E, KANJI_LEVEL4, // 晎 + 0x3AEA, KANJI_LEVEL4, // 㫪 + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDDC3, KANJI_LEVEL4, // ᅵ + 0x6657, KANJI_LEVEL4, // 晗 + 0x665B, KANJI_LEVEL4, // 晛 + 0x6663, KANJI_LEVEL4, // 晣 + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDDF5, KANJI_LEVEL4, // ᅵ + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDDB6, KANJI_LEVEL4, // ᅵ + 0x666A, KANJI_LEVEL4, // 晪 + 0x666B, KANJI_LEVEL4, // 晫 + 0x666C, KANJI_LEVEL4, // 晬 + 0x666D, KANJI_LEVEL4, // 晭 + 0x667B, KANJI_LEVEL4, // 晻 + 0x6680, KANJI_LEVEL4, // 暀 + 0x6690, KANJI_LEVEL4, // 暐 + 0x6692, KANJI_LEVEL4, // 暒 + 0x6699, KANJI_LEVEL4, // 暙 + 0x3B0E, KANJI_LEVEL4, // 㬎 + 0x66AD, KANJI_LEVEL4, // 暭 + 0x66B1, KANJI_LEVEL4, // 暱 + 0x66B5, KANJI_LEVEL4, // 暵 + 0x3B1A, KANJI_LEVEL4, // 㬚 + 0x66BF, KANJI_LEVEL4, // 暿 + 0x3B1C, KANJI_LEVEL4, // 㬜 + 0x66EC, KANJI_LEVEL4, // 曬 + 0x3AD7, KANJI_LEVEL4, // 㫗 + 0x6701, KANJI_LEVEL4, // 朁 + 0x6705, KANJI_LEVEL4, // 朅 + 0x6712, KANJI_LEVEL4, // 朒 + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDF72, KANJI_LEVEL4, // ᅵ + 0x6719, KANJI_LEVEL4, // 朙 + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDFD3, KANJI_LEVEL4, // ᅵ + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDFD2, KANJI_LEVEL4, // ᅵ + 0x674C, KANJI_LEVEL4, // 杌 + 0x674D, KANJI_LEVEL4, // 杍 + 0x6754, KANJI_LEVEL4, // 杔 + 0x675D, KANJI_LEVEL4, // 杝 + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDFD0, KANJI_LEVEL4, // ᅵ + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDFE4, KANJI_LEVEL4, // ᅵ + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDFD5, KANJI_LEVEL4, // ᅵ + 0x6774, KANJI_LEVEL4, // 李 + 0x6776, KANJI_LEVEL4, // 杶 + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDFDA, KANJI_LEVEL4, // ᅵ + 0x6792, KANJI_LEVEL4, // 枒 + 0xD84C, KANJI_LEVEL4, // ᅵ + 0xDFDF, KANJI_LEVEL4, // ᅵ + 0x8363, KANJI_LEVEL4, // 荣 + 0x6810, KANJI_LEVEL4, // 栐 + 0x67B0, KANJI_LEVEL4, // 枰 + 0x67B2, KANJI_LEVEL4, // 枲 + 0x67C3, KANJI_LEVEL4, // 柃 + 0x67C8, KANJI_LEVEL4, // 柈 + 0x67D2, KANJI_LEVEL4, // 柒 + 0x67D9, KANJI_LEVEL4, // 柙 + 0x67DB, KANJI_LEVEL4, // 柛 + 0x67F0, KANJI_LEVEL4, // 柰 + 0x67F7, KANJI_LEVEL4, // 柷 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDC4A, KANJI_LEVEL4, // ᅵ + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDC51, KANJI_LEVEL4, // ᅵ + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDC4B, KANJI_LEVEL4, // ᅵ + 0x6818, KANJI_LEVEL4, // 栘 + 0x681F, KANJI_LEVEL4, // 栟 + 0x682D, KANJI_LEVEL4, // æ ­ + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDC65, KANJI_LEVEL4, // ᅵ + 0x6833, KANJI_LEVEL4, // æ ³ + 0x683B, KANJI_LEVEL4, // æ » + 0x683E, KANJI_LEVEL4, // æ Ÿ + 0x6844, KANJI_LEVEL4, // 桄 + 0x6845, KANJI_LEVEL4, // 桅 + 0x6849, KANJI_LEVEL4, // 桉 + 0x684C, KANJI_LEVEL4, // 桌 + 0x6855, KANJI_LEVEL4, // 桕 + 0x6857, KANJI_LEVEL4, // 桗 + 0x3B77, KANJI_LEVEL4, // ã­· + 0x686B, KANJI_LEVEL4, // æ¡« + 0x686E, KANJI_LEVEL4, // æ¡® + 0x687A, KANJI_LEVEL4, // 桺 + 0x687C, KANJI_LEVEL4, // 桌 + 0x6882, KANJI_LEVEL4, // 梂 + 0x6890, KANJI_LEVEL4, // 梐 + 0x6896, KANJI_LEVEL4, // 梖 + 0x3B6D, KANJI_LEVEL4, // ã­­ + 0x6898, KANJI_LEVEL4, // 梘 + 0x6899, KANJI_LEVEL4, // 梙 + 0x689A, KANJI_LEVEL4, // 梚 + 0x689C, KANJI_LEVEL4, // 梜 + 0x68AA, KANJI_LEVEL4, // 梪 + 0x68AB, KANJI_LEVEL4, // 梫 + 0x68B4, KANJI_LEVEL4, // 梎 + 0x68BB, KANJI_LEVEL4, // 梻 + 0x68FB, KANJI_LEVEL4, // 棻 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDCE4, KANJI_LEVEL4, // ᅵ + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDD5A, KANJI_LEVEL4, // ᅵ + 0xFA13, KANJI_LEVEL4, // ïš“ + 0x68C3, KANJI_LEVEL4, // 棃 + 0x68C5, KANJI_LEVEL4, // 棅 + 0x68CC, KANJI_LEVEL4, // 棌 + 0x68CF, KANJI_LEVEL4, // 棏 + 0x68D6, KANJI_LEVEL4, // 棖 + 0x68D9, KANJI_LEVEL4, // 棙 + 0x68E4, KANJI_LEVEL4, // 检 + 0x68E5, KANJI_LEVEL4, // 棥 + 0x68EC, KANJI_LEVEL4, // 棬 + 0x68F7, KANJI_LEVEL4, // 棷 + 0x6903, KANJI_LEVEL4, // 怃 + 0x6907, KANJI_LEVEL4, // 怇 + 0x3B87, KANJI_LEVEL4, // 㮇 + 0x3B88, KANJI_LEVEL4, // 㮈 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDD94, KANJI_LEVEL4, // ᅵ + 0x693B, KANJI_LEVEL4, // 总 + 0x3B8D, KANJI_LEVEL4, // 㮍 + 0x6946, KANJI_LEVEL4, // 楆 + 0x6969, KANJI_LEVEL4, // 楩 + 0x696C, KANJI_LEVEL4, // 楬 + 0x6972, KANJI_LEVEL4, // 楲 + 0x697A, KANJI_LEVEL4, // 楺 + 0x697F, KANJI_LEVEL4, // 楿 + 0x6992, KANJI_LEVEL4, // 抒 + 0x3BA4, KANJI_LEVEL4, // 㮀 + 0x6996, KANJI_LEVEL4, // 抖 + 0x6998, KANJI_LEVEL4, // 折 + 0x69A6, KANJI_LEVEL4, // 把 + 0x69B0, KANJI_LEVEL4, // 抰 + 0x69B7, KANJI_LEVEL4, // 抷 + 0x69BA, KANJI_LEVEL4, // 抺 + 0x69BC, KANJI_LEVEL4, // 抌 + 0x69C0, KANJI_LEVEL4, // 槀 + 0x69D1, KANJI_LEVEL4, // 槑 + 0x69D6, KANJI_LEVEL4, // 槖 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDE39, KANJI_LEVEL4, // ᅵ + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDE47, KANJI_LEVEL4, // ᅵ + 0x6A30, KANJI_LEVEL4, // æš° + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDE38, KANJI_LEVEL4, // ᅵ + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDE3A, KANJI_LEVEL4, // ᅵ + 0x69E3, KANJI_LEVEL4, // æ§£ + 0x69EE, KANJI_LEVEL4, // æ§® + 0x69EF, KANJI_LEVEL4, // 槯 + 0x69F3, KANJI_LEVEL4, // æ§³ + 0x3BCD, KANJI_LEVEL4, // 㯍 + 0x69F4, KANJI_LEVEL4, // æ§Ž + 0x69FE, KANJI_LEVEL4, // æ§Ÿ + 0x6A11, KANJI_LEVEL4, // æš‘ + 0x6A1A, KANJI_LEVEL4, // æšš + 0x6A1D, KANJI_LEVEL4, // 暝 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDF1C, KANJI_LEVEL4, // ᅵ + 0x6A32, KANJI_LEVEL4, // æš² + 0x6A33, KANJI_LEVEL4, // æš³ + 0x6A34, KANJI_LEVEL4, // 暎 + 0x6A3F, KANJI_LEVEL4, // æš¿ + 0x6A46, KANJI_LEVEL4, // 橆 + 0x6A49, KANJI_LEVEL4, // 橉 + 0x6A7A, KANJI_LEVEL4, // 橺 + 0x6A4E, KANJI_LEVEL4, // 橎 + 0x6A52, KANJI_LEVEL4, // 橒 + 0x6A64, KANJI_LEVEL4, // æ©€ + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDF0C, KANJI_LEVEL4, // ᅵ + 0x6A7E, KANJI_LEVEL4, // 機 + 0x6A83, KANJI_LEVEL4, // 檃 + 0x6A8B, KANJI_LEVEL4, // 檋 + 0x3BF0, KANJI_LEVEL4, // 㯰 + 0x6A91, KANJI_LEVEL4, // 檑 + 0x6A9F, KANJI_LEVEL4, // 檟 + 0x6AA1, KANJI_LEVEL4, // 檡 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDF64, KANJI_LEVEL4, // ᅵ + 0x6AAB, KANJI_LEVEL4, // 檫 + 0x6ABD, KANJI_LEVEL4, // 檜 + 0x6AC6, KANJI_LEVEL4, // 櫆 + 0x6AD4, KANJI_LEVEL4, // 櫔 + 0x6AD0, KANJI_LEVEL4, // 櫐 + 0x6ADC, KANJI_LEVEL4, // 櫜 + 0x6ADD, KANJI_LEVEL4, // 櫝 + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDFFF, KANJI_LEVEL4, // ᅵ + 0xD84D, KANJI_LEVEL4, // ᅵ + 0xDFE7, KANJI_LEVEL4, // ᅵ + 0x6AEC, KANJI_LEVEL4, // 櫬 + 0x6AF1, KANJI_LEVEL4, // 櫱 + 0x6AF2, KANJI_LEVEL4, // 櫲 + 0x6AF3, KANJI_LEVEL4, // 櫳 + 0x6AFD, KANJI_LEVEL4, // 櫜 + 0xD84E, KANJI_LEVEL4, // ᅵ + 0xDC24, KANJI_LEVEL4, // ᅵ + 0x6B0B, KANJI_LEVEL4, // 欋 + 0x6B0F, KANJI_LEVEL4, // 欏 + 0x6B10, KANJI_LEVEL4, // 欐 + 0x6B11, KANJI_LEVEL4, // 欑 + 0xD84E, KANJI_LEVEL4, // ᅵ + 0xDC3D, KANJI_LEVEL4, // ᅵ + 0x6B17, KANJI_LEVEL4, // 欗 + 0x3C26, KANJI_LEVEL4, // ã°Š + 0x6B2F, KANJI_LEVEL4, // 欯 + 0x6B4A, KANJI_LEVEL4, // 歊 + 0x6B58, KANJI_LEVEL4, // 歘 + 0x6B6C, KANJI_LEVEL4, // æ­¬ + 0x6B75, KANJI_LEVEL4, // æ­µ + 0x6B7A, KANJI_LEVEL4, // æ­º + 0x6B81, KANJI_LEVEL4, // 殁 + 0x6B9B, KANJI_LEVEL4, // 殛 + 0x6BAE, KANJI_LEVEL4, // æ®® + 0xD84E, KANJI_LEVEL4, // ᅵ + 0xDE98, KANJI_LEVEL4, // ᅵ + 0x6BBD, KANJI_LEVEL4, // 殜 + 0x6BBE, KANJI_LEVEL4, // 殟 + 0x6BC7, KANJI_LEVEL4, // 毇 + 0x6BC8, KANJI_LEVEL4, // 毈 + 0x6BC9, KANJI_LEVEL4, // 毉 + 0x6BDA, KANJI_LEVEL4, // 毚 + 0x6BE6, KANJI_LEVEL4, // 毊 + 0x6BE7, KANJI_LEVEL4, // 毧 + 0x6BEE, KANJI_LEVEL4, // 毮 + 0x6BF1, KANJI_LEVEL4, // 毱 + 0x6C02, KANJI_LEVEL4, // 氂 + 0x6C0A, KANJI_LEVEL4, // 氊 + 0x6C0E, KANJI_LEVEL4, // 氎 + 0x6C35, KANJI_LEVEL4, // æ°µ + 0x6C36, KANJI_LEVEL4, // æ°¶ + 0x6C3A, KANJI_LEVEL4, // æ°º + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDC7F, KANJI_LEVEL4, // ᅵ + 0x6C3F, KANJI_LEVEL4, // æ°¿ + 0x6C4D, KANJI_LEVEL4, // 汍 + 0x6C5B, KANJI_LEVEL4, // 汛 + 0x6C6D, KANJI_LEVEL4, // æ±­ + 0x6C84, KANJI_LEVEL4, // 沄 + 0x6C89, KANJI_LEVEL4, // 沉 + 0x3CC3, KANJI_LEVEL4, // 㳃 + 0x6C94, KANJI_LEVEL4, // 沔 + 0x6C95, KANJI_LEVEL4, // 沕 + 0x6C97, KANJI_LEVEL4, // 沗 + 0x6CAD, KANJI_LEVEL4, // æ²­ + 0x6CC2, KANJI_LEVEL4, // 泂 + 0x6CD0, KANJI_LEVEL4, // 泐 + 0x3CD2, KANJI_LEVEL4, // 㳒 + 0x6CD6, KANJI_LEVEL4, // 泖 + 0x6CDA, KANJI_LEVEL4, // 泚 + 0x6CDC, KANJI_LEVEL4, // 泜 + 0x6CE9, KANJI_LEVEL4, // 泩 + 0x6CEC, KANJI_LEVEL4, // 泬 + 0x6CED, KANJI_LEVEL4, // æ³­ + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDD00, KANJI_LEVEL4, // ᅵ + 0x6D00, KANJI_LEVEL4, // 掀 + 0x6D0A, KANJI_LEVEL4, // 掊 + 0x6D24, KANJI_LEVEL4, // 掀 + 0x6D26, KANJI_LEVEL4, // 掊 + 0x6D27, KANJI_LEVEL4, // 控 + 0x6C67, KANJI_LEVEL4, // æ±§ + 0x6D2F, KANJI_LEVEL4, // 掯 + 0x6D3C, KANJI_LEVEL4, // 掌 + 0x6D5B, KANJI_LEVEL4, // 浛 + 0x6D5E, KANJI_LEVEL4, // 浞 + 0x6D60, KANJI_LEVEL4, // æµ  + 0x6D70, KANJI_LEVEL4, // æµ° + 0x6D80, KANJI_LEVEL4, // 涀 + 0x6D81, KANJI_LEVEL4, // 涁 + 0x6D8A, KANJI_LEVEL4, // 涊 + 0x6D8D, KANJI_LEVEL4, // 涍 + 0x6D91, KANJI_LEVEL4, // 涑 + 0x6D98, KANJI_LEVEL4, // 涘 + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDD40, KANJI_LEVEL4, // ᅵ + 0x6E17, KANJI_LEVEL4, // æž— + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDDFA, KANJI_LEVEL4, // ᅵ + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDDF9, KANJI_LEVEL4, // ᅵ + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDDD3, KANJI_LEVEL4, // ᅵ + 0x6DAB, KANJI_LEVEL4, // æ¶« + 0x6DAE, KANJI_LEVEL4, // æ¶® + 0x6DB4, KANJI_LEVEL4, // æ¶Ž + 0x6DC2, KANJI_LEVEL4, // 淂 + 0x6D34, KANJI_LEVEL4, // 掎 + 0x6DC8, KANJI_LEVEL4, // 淈 + 0x6DCE, KANJI_LEVEL4, // 淎 + 0x6DCF, KANJI_LEVEL4, // 淏 + 0x6DD0, KANJI_LEVEL4, // 淐 + 0x6DDF, KANJI_LEVEL4, // 淟 + 0x6DE9, KANJI_LEVEL4, // æ·© + 0x6DF6, KANJI_LEVEL4, // æ·¶ + 0x6E36, KANJI_LEVEL4, // æž¶ + 0x6E1E, KANJI_LEVEL4, // æžž + 0x6E22, KANJI_LEVEL4, // 枢 + 0x6E27, KANJI_LEVEL4, // æž§ + 0x3D11, KANJI_LEVEL4, // ㎑ + 0x6E32, KANJI_LEVEL4, // æž² + 0x6E3C, KANJI_LEVEL4, // 枌 + 0x6E48, KANJI_LEVEL4, // 湈 + 0x6E49, KANJI_LEVEL4, // 湉 + 0x6E4B, KANJI_LEVEL4, // 湋 + 0x6E4C, KANJI_LEVEL4, // 湌 + 0x6E4F, KANJI_LEVEL4, // 湏 + 0x6E51, KANJI_LEVEL4, // 湑 + 0x6E53, KANJI_LEVEL4, // 湓 + 0x6E54, KANJI_LEVEL4, // 湔 + 0x6E57, KANJI_LEVEL4, // 湗 + 0x6E63, KANJI_LEVEL4, // æ¹£ + 0x3D1E, KANJI_LEVEL4, // ㎞ + 0x6E93, KANJI_LEVEL4, // 溓 + 0x6EA7, KANJI_LEVEL4, // 溧 + 0x6EB4, KANJI_LEVEL4, // 溎 + 0x6EBF, KANJI_LEVEL4, // 溿 + 0x6EC3, KANJI_LEVEL4, // 滃 + 0x6ECA, KANJI_LEVEL4, // 滊 + 0x6ED9, KANJI_LEVEL4, // 滙 + 0x6F35, KANJI_LEVEL4, // 挵 + 0x6EEB, KANJI_LEVEL4, // 滫 + 0x6EF9, KANJI_LEVEL4, // 滹 + 0x6EFB, KANJI_LEVEL4, // æ»» + 0x6F0A, KANJI_LEVEL4, // 挊 + 0x6F0C, KANJI_LEVEL4, // 挌 + 0x6F18, KANJI_LEVEL4, // 挘 + 0x6F25, KANJI_LEVEL4, // 挥 + 0x6F36, KANJI_LEVEL4, // 挶 + 0x6F3C, KANJI_LEVEL4, // 挌 + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDF7E, KANJI_LEVEL4, // ᅵ + 0x6F52, KANJI_LEVEL4, // 朒 + 0x6F57, KANJI_LEVEL4, // 朗 + 0x6F5A, KANJI_LEVEL4, // 朚 + 0x6F60, KANJI_LEVEL4, // 朠 + 0x6F68, KANJI_LEVEL4, // 朚 + 0x6F98, KANJI_LEVEL4, // 柘 + 0x6F7D, KANJI_LEVEL4, // 朜 + 0x6F90, KANJI_LEVEL4, // 某 + 0x6F96, KANJI_LEVEL4, // 柖 + 0x6FBE, KANJI_LEVEL4, // 柟 + 0x6F9F, KANJI_LEVEL4, // 柟 + 0x6FA5, KANJI_LEVEL4, // 查 + 0x6FAF, KANJI_LEVEL4, // 柯 + 0x3D64, KANJI_LEVEL4, // ãµ€ + 0x6FB5, KANJI_LEVEL4, // 柵 + 0x6FC8, KANJI_LEVEL4, // 濈 + 0x6FC9, KANJI_LEVEL4, // 濉 + 0x6FDA, KANJI_LEVEL4, // 濚 + 0x6FDE, KANJI_LEVEL4, // 濞 + 0x6FE9, KANJI_LEVEL4, // æ¿© + 0xD850, KANJI_LEVEL4, // ᅵ + 0xDC96, KANJI_LEVEL4, // ᅵ + 0x6FFC, KANJI_LEVEL4, // 濌 + 0x7000, KANJI_LEVEL4, // 瀀 + 0x7007, KANJI_LEVEL4, // 瀇 + 0x700A, KANJI_LEVEL4, // 瀊 + 0x7023, KANJI_LEVEL4, // 瀣 + 0xD850, KANJI_LEVEL4, // ᅵ + 0xDD03, KANJI_LEVEL4, // ᅵ + 0x7039, KANJI_LEVEL4, // 瀹 + 0x703A, KANJI_LEVEL4, // 瀺 + 0x703C, KANJI_LEVEL4, // 瀌 + 0x7043, KANJI_LEVEL4, // 灃 + 0x7047, KANJI_LEVEL4, // 灇 + 0x704B, KANJI_LEVEL4, // 灋 + 0x3D9A, KANJI_LEVEL4, // 㶚 + 0x7054, KANJI_LEVEL4, // 灔 + 0x7065, KANJI_LEVEL4, // 灥 + 0x7069, KANJI_LEVEL4, // 灩 + 0x706C, KANJI_LEVEL4, // 灬 + 0x706E, KANJI_LEVEL4, // 灮 + 0x7076, KANJI_LEVEL4, // 灶 + 0x707E, KANJI_LEVEL4, // 灟 + 0x7081, KANJI_LEVEL4, // 炁 + 0x7086, KANJI_LEVEL4, // 炆 + 0x7095, KANJI_LEVEL4, // 炕 + 0x7097, KANJI_LEVEL4, // 炗 + 0x70BB, KANJI_LEVEL4, // 炻 + 0xD850, KANJI_LEVEL4, // ᅵ + 0xDDC6, KANJI_LEVEL4, // ᅵ + 0x709F, KANJI_LEVEL4, // 炟 + 0x70B1, KANJI_LEVEL4, // 炱 + 0xD850, KANJI_LEVEL4, // ᅵ + 0xDDFE, KANJI_LEVEL4, // ᅵ + 0x70EC, KANJI_LEVEL4, // 烬 + 0x70CA, KANJI_LEVEL4, // 烊 + 0x70D1, KANJI_LEVEL4, // 烑 + 0x70D3, KANJI_LEVEL4, // 烓 + 0x70DC, KANJI_LEVEL4, // 烜 + 0x7103, KANJI_LEVEL4, // 焃 + 0x7104, KANJI_LEVEL4, // 焄 + 0x7106, KANJI_LEVEL4, // 焆 + 0x7107, KANJI_LEVEL4, // 焇 + 0x7108, KANJI_LEVEL4, // 焈 + 0x710C, KANJI_LEVEL4, // 焌 + 0x3DC0, KANJI_LEVEL4, // 㷀 + 0x712F, KANJI_LEVEL4, // 焯 + 0x7131, KANJI_LEVEL4, // 焱 + 0x7150, KANJI_LEVEL4, // 煐 + 0x714A, KANJI_LEVEL4, // 煊 + 0x7153, KANJI_LEVEL4, // 煓 + 0x715E, KANJI_LEVEL4, // 煞 + 0x3DD4, KANJI_LEVEL4, // 㷔 + 0x7196, KANJI_LEVEL4, // 熖 + 0x7180, KANJI_LEVEL4, // 熀 + 0x719B, KANJI_LEVEL4, // 熛 + 0x71A0, KANJI_LEVEL4, // 熠 + 0x71A2, KANJI_LEVEL4, // 熢 + 0x71AE, KANJI_LEVEL4, // 熮 + 0x71AF, KANJI_LEVEL4, // 熯 + 0x71B3, KANJI_LEVEL4, // 熳 + 0xD850, KANJI_LEVEL4, // ᅵ + 0xDFBC, KANJI_LEVEL4, // ᅵ + 0x71CB, KANJI_LEVEL4, // 燋 + 0x71D3, KANJI_LEVEL4, // 燓 + 0x71D9, KANJI_LEVEL4, // 燙 + 0x71DC, KANJI_LEVEL4, // 燜 + 0x7207, KANJI_LEVEL4, // 爇 + 0x3E05, KANJI_LEVEL4, // ãž… + 0xFA49, KANJI_LEVEL4, // 爫 + 0x722B, KANJI_LEVEL4, // 爫 + 0x7234, KANJI_LEVEL4, // 爎 + 0x7238, KANJI_LEVEL4, // 爞 + 0x7239, KANJI_LEVEL4, // 爹 + 0x4E2C, KANJI_LEVEL4, // 䞬 + 0x7242, KANJI_LEVEL4, // 牂 + 0x7253, KANJI_LEVEL4, // 牓 + 0x7257, KANJI_LEVEL4, // 牗 + 0x7263, KANJI_LEVEL4, // 牣 + 0xD851, KANJI_LEVEL4, // ᅵ + 0xDE29, KANJI_LEVEL4, // ᅵ + 0x726E, KANJI_LEVEL4, // 牮 + 0x726F, KANJI_LEVEL4, // 牯 + 0x7278, KANJI_LEVEL4, // 牾 + 0x727F, KANJI_LEVEL4, // 牿 + 0x728E, KANJI_LEVEL4, // 犎 + 0xD851, KANJI_LEVEL4, // ᅵ + 0xDEA5, KANJI_LEVEL4, // ᅵ + 0x72AD, KANJI_LEVEL4, // 犭 + 0x72AE, KANJI_LEVEL4, // 犮 + 0x72B0, KANJI_LEVEL4, // 犰 + 0x72B1, KANJI_LEVEL4, // 犱 + 0x72C1, KANJI_LEVEL4, // 狁 + 0x3E60, KANJI_LEVEL4, // ã¹  + 0x72CC, KANJI_LEVEL4, // 狌 + 0x3E66, KANJI_LEVEL4, // 㹊 + 0x3E68, KANJI_LEVEL4, // 㹚 + 0x72F3, KANJI_LEVEL4, // 狳 + 0x72FA, KANJI_LEVEL4, // 狺 + 0x7307, KANJI_LEVEL4, // 猇 + 0x7312, KANJI_LEVEL4, // 猒 + 0x7318, KANJI_LEVEL4, // 猘 + 0x7319, KANJI_LEVEL4, // 猙 + 0x3E83, KANJI_LEVEL4, // 㺃 + 0x7339, KANJI_LEVEL4, // 猹 + 0x732C, KANJI_LEVEL4, // 猬 + 0x7331, KANJI_LEVEL4, // 猱 + 0x7333, KANJI_LEVEL4, // 猳 + 0x733D, KANJI_LEVEL4, // 猜 + 0x7352, KANJI_LEVEL4, // 獒 + 0x3E94, KANJI_LEVEL4, // 㺔 + 0x736B, KANJI_LEVEL4, // 獫 + 0x736C, KANJI_LEVEL4, // 獬 + 0xD852, KANJI_LEVEL4, // ᅵ + 0xDC96, KANJI_LEVEL4, // ᅵ + 0x736E, KANJI_LEVEL4, // 獮 + 0x736F, KANJI_LEVEL4, // 獯 + 0x7371, KANJI_LEVEL4, // 獱 + 0x7377, KANJI_LEVEL4, // 獷 + 0x7381, KANJI_LEVEL4, // 玁 + 0x7385, KANJI_LEVEL4, // 玅 + 0x738A, KANJI_LEVEL4, // 玊 + 0x7394, KANJI_LEVEL4, // 玔 + 0x7398, KANJI_LEVEL4, // 玘 + 0x739C, KANJI_LEVEL4, // 玜 + 0x739E, KANJI_LEVEL4, // 玞 + 0x73A5, KANJI_LEVEL4, // 玥 + 0x73A8, KANJI_LEVEL4, // 玚 + 0x73B5, KANJI_LEVEL4, // 玵 + 0x73B7, KANJI_LEVEL4, // 玷 + 0x73B9, KANJI_LEVEL4, // 玹 + 0x73BC, KANJI_LEVEL4, // 玌 + 0x73BF, KANJI_LEVEL4, // 玿 + 0x73C5, KANJI_LEVEL4, // 珅 + 0x73CB, KANJI_LEVEL4, // 珋 + 0x73E1, KANJI_LEVEL4, // 珡 + 0x73E7, KANJI_LEVEL4, // 珧 + 0x73F9, KANJI_LEVEL4, // 珹 + 0x7413, KANJI_LEVEL4, // 琓 + 0x73FA, KANJI_LEVEL4, // 珺 + 0x7401, KANJI_LEVEL4, // 琁 + 0x7424, KANJI_LEVEL4, // 琀 + 0x7431, KANJI_LEVEL4, // 琱 + 0x7439, KANJI_LEVEL4, // 琹 + 0x7453, KANJI_LEVEL4, // 瑓 + 0x7440, KANJI_LEVEL4, // 瑀 + 0x7443, KANJI_LEVEL4, // 瑃 + 0x744D, KANJI_LEVEL4, // 瑍 + 0x7452, KANJI_LEVEL4, // 瑒 + 0x745D, KANJI_LEVEL4, // 瑝 + 0x7471, KANJI_LEVEL4, // 瑱 + 0x7481, KANJI_LEVEL4, // 璁 + 0x7485, KANJI_LEVEL4, // 璅 + 0x7488, KANJI_LEVEL4, // 璈 + 0xD852, KANJI_LEVEL4, // ᅵ + 0xDE4D, KANJI_LEVEL4, // ᅵ + 0x7492, KANJI_LEVEL4, // 璒 + 0x7497, KANJI_LEVEL4, // 璗 + 0x7499, KANJI_LEVEL4, // 璙 + 0x74A0, KANJI_LEVEL4, // 璠 + 0x74A1, KANJI_LEVEL4, // 璡 + 0x74A5, KANJI_LEVEL4, // 璥 + 0x74AA, KANJI_LEVEL4, // 璪 + 0x74AB, KANJI_LEVEL4, // 璫 + 0x74B9, KANJI_LEVEL4, // 璹 + 0x74BB, KANJI_LEVEL4, // 璻 + 0x74BA, KANJI_LEVEL4, // 璺 + 0x74D6, KANJI_LEVEL4, // 瓖 + 0x74D8, KANJI_LEVEL4, // 瓘 + 0x74DE, KANJI_LEVEL4, // 瓞 + 0x74EF, KANJI_LEVEL4, // 瓯 + 0x74EB, KANJI_LEVEL4, // 瓫 + 0xD852, KANJI_LEVEL4, // ᅵ + 0xDF56, KANJI_LEVEL4, // ᅵ + 0x74FA, KANJI_LEVEL4, // 瓺 + 0xD852, KANJI_LEVEL4, // ᅵ + 0xDF6F, KANJI_LEVEL4, // ᅵ + 0x7520, KANJI_LEVEL4, // 甠 + 0x7524, KANJI_LEVEL4, // 甀 + 0x752A, KANJI_LEVEL4, // 甪 + 0x3F57, KANJI_LEVEL4, // 㜗 + 0xD853, KANJI_LEVEL4, // ᅵ + 0xDC16, KANJI_LEVEL4, // ᅵ + 0x753D, KANJI_LEVEL4, // 甜 + 0x753E, KANJI_LEVEL4, // 生 + 0x7540, KANJI_LEVEL4, // 畀 + 0x7548, KANJI_LEVEL4, // 畈 + 0x754E, KANJI_LEVEL4, // 畎 + 0x7550, KANJI_LEVEL4, // 畐 + 0x7552, KANJI_LEVEL4, // 畒 + 0x756C, KANJI_LEVEL4, // 畬 + 0x7572, KANJI_LEVEL4, // 畲 + 0x7571, KANJI_LEVEL4, // 畱 + 0x757A, KANJI_LEVEL4, // 畺 + 0x757D, KANJI_LEVEL4, // 畜 + 0x757E, KANJI_LEVEL4, // 畟 + 0x7581, KANJI_LEVEL4, // 疁 + 0xD853, KANJI_LEVEL4, // ᅵ + 0xDD14, KANJI_LEVEL4, // ᅵ + 0x758C, KANJI_LEVEL4, // 疌 + 0x3F75, KANJI_LEVEL4, // 㜵 + 0x75A2, KANJI_LEVEL4, // 疢 + 0x3F77, KANJI_LEVEL4, // 㜷 + 0x75B0, KANJI_LEVEL4, // 疰 + 0x75B7, KANJI_LEVEL4, // 疷 + 0x75BF, KANJI_LEVEL4, // 疿 + 0x75C0, KANJI_LEVEL4, // 痀 + 0x75C6, KANJI_LEVEL4, // 痆 + 0x75CF, KANJI_LEVEL4, // 痏 + 0x75D3, KANJI_LEVEL4, // 痓 + 0x75DD, KANJI_LEVEL4, // 痝 + 0x75DF, KANJI_LEVEL4, // 痟 + 0x75E0, KANJI_LEVEL4, // 痠 + 0x75E7, KANJI_LEVEL4, // 痧 + 0x75EC, KANJI_LEVEL4, // 痬 + 0x75EE, KANJI_LEVEL4, // 痮 + 0x75F1, KANJI_LEVEL4, // 痱 + 0x75F9, KANJI_LEVEL4, // 痹 + 0x7603, KANJI_LEVEL4, // 瘃 + 0x7618, KANJI_LEVEL4, // 瘘 + 0x7607, KANJI_LEVEL4, // 瘇 + 0x760F, KANJI_LEVEL4, // 瘏 + 0x3FAE, KANJI_LEVEL4, // 㟮 + 0xD853, KANJI_LEVEL4, // ᅵ + 0xDE0E, KANJI_LEVEL4, // ᅵ + 0x7613, KANJI_LEVEL4, // 瘓 + 0x761B, KANJI_LEVEL4, // 瘛 + 0x761C, KANJI_LEVEL4, // 瘜 + 0xD853, KANJI_LEVEL4, // ᅵ + 0xDE37, KANJI_LEVEL4, // ᅵ + 0x7625, KANJI_LEVEL4, // 瘥 + 0x7628, KANJI_LEVEL4, // 瘚 + 0x763C, KANJI_LEVEL4, // 瘌 + 0x7633, KANJI_LEVEL4, // 瘳 + 0xD853, KANJI_LEVEL4, // ᅵ + 0xDE6A, KANJI_LEVEL4, // ᅵ + 0x3FC9, KANJI_LEVEL4, // 㿉 + 0x7641, KANJI_LEVEL4, // 癁 + 0xD853, KANJI_LEVEL4, // ᅵ + 0xDE8B, KANJI_LEVEL4, // ᅵ + 0x7649, KANJI_LEVEL4, // 癉 + 0x7655, KANJI_LEVEL4, // 癕 + 0x3FD7, KANJI_LEVEL4, // 㿗 + 0x766E, KANJI_LEVEL4, // 癮 + 0x7695, KANJI_LEVEL4, // 皕 + 0x769C, KANJI_LEVEL4, // 皜 + 0x76A1, KANJI_LEVEL4, // 皡 + 0x76A0, KANJI_LEVEL4, // 皠 + 0x76A7, KANJI_LEVEL4, // 皧 + 0x76A8, KANJI_LEVEL4, // 皹 + 0x76AF, KANJI_LEVEL4, // 皯 + 0xD854, KANJI_LEVEL4, // ᅵ + 0xDC4A, KANJI_LEVEL4, // ᅵ + 0x76C9, KANJI_LEVEL4, // 盉 + 0xD854, KANJI_LEVEL4, // ᅵ + 0xDC55, KANJI_LEVEL4, // ᅵ + 0x76E8, KANJI_LEVEL4, // 盹 + 0x76EC, KANJI_LEVEL4, // 盬 + 0xD854, KANJI_LEVEL4, // ᅵ + 0xDD22, KANJI_LEVEL4, // ᅵ + 0x7717, KANJI_LEVEL4, // 眗 + 0x771A, KANJI_LEVEL4, // 眚 + 0x772D, KANJI_LEVEL4, // 眭 + 0x7735, KANJI_LEVEL4, // 眵 + 0xD854, KANJI_LEVEL4, // ᅵ + 0xDDA9, KANJI_LEVEL4, // ᅵ + 0x4039, KANJI_LEVEL4, // 䀹 + 0xD854, KANJI_LEVEL4, // ᅵ + 0xDDE5, KANJI_LEVEL4, // ᅵ + 0xD854, KANJI_LEVEL4, // ᅵ + 0xDDCD, KANJI_LEVEL4, // ᅵ + 0x7758, KANJI_LEVEL4, // 睘 + 0x7760, KANJI_LEVEL4, // 睠 + 0x776A, KANJI_LEVEL4, // 睪 + 0xD854, KANJI_LEVEL4, // ᅵ + 0xDE1E, KANJI_LEVEL4, // ᅵ + 0x7772, KANJI_LEVEL4, // 睲 + 0x777C, KANJI_LEVEL4, // 睌 + 0x777D, KANJI_LEVEL4, // 睜 + 0xD854, KANJI_LEVEL4, // ᅵ + 0xDE4C, KANJI_LEVEL4, // ᅵ + 0x4058, KANJI_LEVEL4, // 䁘 + 0x779A, KANJI_LEVEL4, // 瞚 + 0x779F, KANJI_LEVEL4, // 瞟 + 0x77A2, KANJI_LEVEL4, // 瞢 + 0x77A4, KANJI_LEVEL4, // 瞀 + 0x77A9, KANJI_LEVEL4, // 瞩 + 0x77DE, KANJI_LEVEL4, // 矞 + 0x77DF, KANJI_LEVEL4, // 矟 + 0x77E4, KANJI_LEVEL4, // 矀 + 0x77E6, KANJI_LEVEL4, // 矩 + 0x77EA, KANJI_LEVEL4, // 矪 + 0x77EC, KANJI_LEVEL4, // 矬 + 0x4093, KANJI_LEVEL4, // 䂓 + 0x77F0, KANJI_LEVEL4, // 矰 + 0x77F4, KANJI_LEVEL4, // 矮 + 0x77FB, KANJI_LEVEL4, // 矻 + 0xD855, KANJI_LEVEL4, // ᅵ + 0xDC2E, KANJI_LEVEL4, // ᅵ + 0x7805, KANJI_LEVEL4, // 砅 + 0x7806, KANJI_LEVEL4, // 砆 + 0x7809, KANJI_LEVEL4, // 砉 + 0x780D, KANJI_LEVEL4, // 砍 + 0x7819, KANJI_LEVEL4, // 砙 + 0x7821, KANJI_LEVEL4, // ç ¡ + 0x782C, KANJI_LEVEL4, // ç ¬ + 0x7847, KANJI_LEVEL4, // 硇 + 0x7864, KANJI_LEVEL4, // ç¡€ + 0x786A, KANJI_LEVEL4, // 硪 + 0xD855, KANJI_LEVEL4, // ᅵ + 0xDCD9, KANJI_LEVEL4, // ᅵ + 0x788A, KANJI_LEVEL4, // 碊 + 0x7894, KANJI_LEVEL4, // 碔 + 0x78A4, KANJI_LEVEL4, // 碀 + 0x789D, KANJI_LEVEL4, // 碝 + 0x789E, KANJI_LEVEL4, // 碞 + 0x789F, KANJI_LEVEL4, // 碟 + 0x78BB, KANJI_LEVEL4, // 碻 + 0x78C8, KANJI_LEVEL4, // 磈 + 0x78CC, KANJI_LEVEL4, // 磌 + 0x78CE, KANJI_LEVEL4, // 磎 + 0x78D5, KANJI_LEVEL4, // 磕 + 0x78E0, KANJI_LEVEL4, // 磠 + 0x78E1, KANJI_LEVEL4, // 磡 + 0x78E6, KANJI_LEVEL4, // 磊 + 0x78F9, KANJI_LEVEL4, // 磹 + 0x78FA, KANJI_LEVEL4, // 磺 + 0x78FB, KANJI_LEVEL4, // 磻 + 0x78FE, KANJI_LEVEL4, // 磟 + 0xD855, KANJI_LEVEL4, // ᅵ + 0xDDA7, KANJI_LEVEL4, // ᅵ + 0x7910, KANJI_LEVEL4, // 瀐 + 0x791B, KANJI_LEVEL4, // 瀛 + 0x7930, KANJI_LEVEL4, // 瀰 + 0x7925, KANJI_LEVEL4, // 瀥 + 0x793B, KANJI_LEVEL4, // 瀻 + 0x794A, KANJI_LEVEL4, // 祊 + 0x7958, KANJI_LEVEL4, // 祘 + 0x795B, KANJI_LEVEL4, // 祛 + 0x4105, KANJI_LEVEL4, // 䄅 + 0x7967, KANJI_LEVEL4, // 祧 + 0x7972, KANJI_LEVEL4, // 祲 + 0x7994, KANJI_LEVEL4, // 穔 + 0x7995, KANJI_LEVEL4, // 穕 + 0x7996, KANJI_LEVEL4, // 穖 + 0x799B, KANJI_LEVEL4, // 穛 + 0x79A1, KANJI_LEVEL4, // 犡 + 0x79A9, KANJI_LEVEL4, // 犩 + 0x79B4, KANJI_LEVEL4, // 犎 + 0x79BB, KANJI_LEVEL4, // 犻 + 0x79C2, KANJI_LEVEL4, // 秂 + 0x79C7, KANJI_LEVEL4, // 秇 + 0x79CC, KANJI_LEVEL4, // 秌 + 0x79CD, KANJI_LEVEL4, // 种 + 0x79D6, KANJI_LEVEL4, // 秖 + 0x4148, KANJI_LEVEL4, // 䅈 + 0xD855, KANJI_LEVEL4, // ᅵ + 0xDFA9, KANJI_LEVEL4, // ᅵ + 0xD855, KANJI_LEVEL4, // ᅵ + 0xDFB4, KANJI_LEVEL4, // ᅵ + 0x414F, KANJI_LEVEL4, // 䅏 + 0x7A0A, KANJI_LEVEL4, // 繊 + 0x7A11, KANJI_LEVEL4, // 繑 + 0x7A15, KANJI_LEVEL4, // 繕 + 0x7A1B, KANJI_LEVEL4, // 繛 + 0x7A1E, KANJI_LEVEL4, // 皞 + 0x4163, KANJI_LEVEL4, // 䅣 + 0x7A2D, KANJI_LEVEL4, // çš­ + 0x7A38, KANJI_LEVEL4, // çšž + 0x7A47, KANJI_LEVEL4, // 穇 + 0x7A4C, KANJI_LEVEL4, // 穌 + 0x7A56, KANJI_LEVEL4, // 穖 + 0x7A59, KANJI_LEVEL4, // 穙 + 0x7A5C, KANJI_LEVEL4, // 穜 + 0x7A5F, KANJI_LEVEL4, // 穟 + 0x7A60, KANJI_LEVEL4, // ç©  + 0x7A67, KANJI_LEVEL4, // ç©§ + 0x7A6A, KANJI_LEVEL4, // 穪 + 0x7A75, KANJI_LEVEL4, // 穵 + 0x7A78, KANJI_LEVEL4, // 穞 + 0x7A82, KANJI_LEVEL4, // 窂 + 0x7A8A, KANJI_LEVEL4, // 窊 + 0x7A90, KANJI_LEVEL4, // 窐 + 0x7AA3, KANJI_LEVEL4, // 窣 + 0x7AAC, KANJI_LEVEL4, // 窬 + 0xD856, KANJI_LEVEL4, // ᅵ + 0xDDD4, KANJI_LEVEL4, // ᅵ + 0x41B4, KANJI_LEVEL4, // 䆮 + 0x7AB9, KANJI_LEVEL4, // 窹 + 0x7ABC, KANJI_LEVEL4, // 窌 + 0x7ABE, KANJI_LEVEL4, // 窟 + 0x41BF, KANJI_LEVEL4, // 䆿 + 0x7ACC, KANJI_LEVEL4, // 竌 + 0x7AD1, KANJI_LEVEL4, // 竑 + 0x7AE7, KANJI_LEVEL4, // ç«§ + 0x7AE8, KANJI_LEVEL4, // 竚 + 0x7AF4, KANJI_LEVEL4, // 竎 + 0xD856, KANJI_LEVEL4, // ᅵ + 0xDEE4, KANJI_LEVEL4, // ᅵ + 0xD856, KANJI_LEVEL4, // ᅵ + 0xDEE3, KANJI_LEVEL4, // ᅵ + 0x7B07, KANJI_LEVEL4, // 笇 + 0xD856, KANJI_LEVEL4, // ᅵ + 0xDEF1, KANJI_LEVEL4, // ᅵ + 0x7B3D, KANJI_LEVEL4, // 笜 + 0x7B27, KANJI_LEVEL4, // 笧 + 0x7B2A, KANJI_LEVEL4, // 笪 + 0x7B2E, KANJI_LEVEL4, // 笮 + 0x7B2F, KANJI_LEVEL4, // 笯 + 0x7B31, KANJI_LEVEL4, // 笱 + 0x41E6, KANJI_LEVEL4, // 䇩 + 0x41F3, KANJI_LEVEL4, // 䇳 + 0x7B7F, KANJI_LEVEL4, // ç­¿ + 0x7B41, KANJI_LEVEL4, // 筁 + 0x41EE, KANJI_LEVEL4, // 䇮 + 0x7B55, KANJI_LEVEL4, // 筕 + 0x7B79, KANJI_LEVEL4, // ç­¹ + 0x7B64, KANJI_LEVEL4, // ç­€ + 0x7B66, KANJI_LEVEL4, // ç­Š + 0x7B69, KANJI_LEVEL4, // ç­© + 0x7B73, KANJI_LEVEL4, // ç­³ + 0xD856, KANJI_LEVEL4, // ᅵ + 0xDFB2, KANJI_LEVEL4, // ᅵ + 0x4207, KANJI_LEVEL4, // 䈇 + 0x7B90, KANJI_LEVEL4, // 箐 + 0x7B91, KANJI_LEVEL4, // 箑 + 0x7B9B, KANJI_LEVEL4, // 箛 + 0x420E, KANJI_LEVEL4, // 䈎 + 0x7BAF, KANJI_LEVEL4, // 箯 + 0x7BB5, KANJI_LEVEL4, // 箵 + 0x7BBC, KANJI_LEVEL4, // 箌 + 0x7BC5, KANJI_LEVEL4, // 篅 + 0x7BCA, KANJI_LEVEL4, // 篊 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDC4B, KANJI_LEVEL4, // ᅵ + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDC64, KANJI_LEVEL4, // ᅵ + 0x7BD4, KANJI_LEVEL4, // 篔 + 0x7BD6, KANJI_LEVEL4, // 篖 + 0x7BDA, KANJI_LEVEL4, // 篚 + 0x7BEA, KANJI_LEVEL4, // 篪 + 0x7BF0, KANJI_LEVEL4, // 篰 + 0x7C03, KANJI_LEVEL4, // 簃 + 0x7C0B, KANJI_LEVEL4, // 簋 + 0x7C0E, KANJI_LEVEL4, // 簎 + 0x7C0F, KANJI_LEVEL4, // 簏 + 0x7C26, KANJI_LEVEL4, // ç°Š + 0x7C45, KANJI_LEVEL4, // 籅 + 0x7C4A, KANJI_LEVEL4, // 籊 + 0x7C51, KANJI_LEVEL4, // 籑 + 0x7C57, KANJI_LEVEL4, // 籗 + 0x7C5E, KANJI_LEVEL4, // 籞 + 0x7C61, KANJI_LEVEL4, // 籡 + 0x7C69, KANJI_LEVEL4, // 籩 + 0x7C6E, KANJI_LEVEL4, // ç±® + 0x7C6F, KANJI_LEVEL4, // 籯 + 0x7C70, KANJI_LEVEL4, // ç±° + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDE2E, KANJI_LEVEL4, // ᅵ + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDE56, KANJI_LEVEL4, // ᅵ + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDE65, KANJI_LEVEL4, // ᅵ + 0x7CA6, KANJI_LEVEL4, // 粊 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDE62, KANJI_LEVEL4, // ᅵ + 0x7CB6, KANJI_LEVEL4, // ç²¶ + 0x7CB7, KANJI_LEVEL4, // ç²· + 0x7CBF, KANJI_LEVEL4, // 粿 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDED8, KANJI_LEVEL4, // ᅵ + 0x7CC4, KANJI_LEVEL4, // 糄 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDEC2, KANJI_LEVEL4, // ᅵ + 0x7CC8, KANJI_LEVEL4, // 糈 + 0x7CCD, KANJI_LEVEL4, // 糍 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDEE8, KANJI_LEVEL4, // ᅵ + 0x7CD7, KANJI_LEVEL4, // 糗 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDF23, KANJI_LEVEL4, // ᅵ + 0x7CE6, KANJI_LEVEL4, // 糊 + 0x7CEB, KANJI_LEVEL4, // 糫 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDF5C, KANJI_LEVEL4, // ᅵ + 0x7CF5, KANJI_LEVEL4, // ç³µ + 0x7D03, KANJI_LEVEL4, // 玃 + 0x7D09, KANJI_LEVEL4, // 箉 + 0x42C6, KANJI_LEVEL4, // 䋆 + 0x7D12, KANJI_LEVEL4, // 箒 + 0x7D1E, KANJI_LEVEL4, // 箞 + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDFE0, KANJI_LEVEL4, // ᅵ + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDFD4, KANJI_LEVEL4, // ᅵ + 0x7D3D, KANJI_LEVEL4, // 玜 + 0x7D3E, KANJI_LEVEL4, // 玟 + 0x7D40, KANJI_LEVEL4, // 絀 + 0x7D47, KANJI_LEVEL4, // 絇 + 0xD858, KANJI_LEVEL4, // ᅵ + 0xDC0C, KANJI_LEVEL4, // ᅵ + 0xD857, KANJI_LEVEL4, // ᅵ + 0xDFFB, KANJI_LEVEL4, // ᅵ + 0x42D6, KANJI_LEVEL4, // 䋖 + 0x7D59, KANJI_LEVEL4, // 絙 + 0x7D5A, KANJI_LEVEL4, // 絚 + 0x7D6A, KANJI_LEVEL4, // 絪 + 0x7D70, KANJI_LEVEL4, // çµ° + 0x42DD, KANJI_LEVEL4, // 䋝 + 0x7D7F, KANJI_LEVEL4, // 絿 + 0xD858, KANJI_LEVEL4, // ᅵ + 0xDC17, KANJI_LEVEL4, // ᅵ + 0x7D86, KANJI_LEVEL4, // 綆 + 0x7D88, KANJI_LEVEL4, // 綈 + 0x7D8C, KANJI_LEVEL4, // 綌 + 0x7D97, KANJI_LEVEL4, // 綗 + 0xD858, KANJI_LEVEL4, // ᅵ + 0xDC60, KANJI_LEVEL4, // ᅵ + 0x7D9D, KANJI_LEVEL4, // 綝 + 0x7DA7, KANJI_LEVEL4, // ç¶§ + 0x7DAA, KANJI_LEVEL4, // 綪 + 0x7DB6, KANJI_LEVEL4, // ç¶¶ + 0x7DB7, KANJI_LEVEL4, // ç¶· + 0x7DC0, KANJI_LEVEL4, // 緀 + 0x7DD7, KANJI_LEVEL4, // 緗 + 0x7DD9, KANJI_LEVEL4, // 緙 + 0x7DE6, KANJI_LEVEL4, // ç·Š + 0x7DF1, KANJI_LEVEL4, // ç·± + 0x7DF9, KANJI_LEVEL4, // ç·¹ + 0x4302, KANJI_LEVEL4, // 䌂 + 0xD858, KANJI_LEVEL4, // ᅵ + 0xDCED, KANJI_LEVEL4, // ᅵ + 0xFA58, KANJI_LEVEL4, // 縉 + 0x7E10, KANJI_LEVEL4, // 瞐 + 0x7E17, KANJI_LEVEL4, // 羗 + 0x7E1D, KANJI_LEVEL4, // 瞝 + 0x7E20, KANJI_LEVEL4, // çž  + 0x7E27, KANJI_LEVEL4, // çž§ + 0x7E2C, KANJI_LEVEL4, // 瞬 + 0x7E45, KANJI_LEVEL4, // 繅 + 0x7E73, KANJI_LEVEL4, // ç¹³ + 0x7E75, KANJI_LEVEL4, // ç¹µ + 0x7E7E, KANJI_LEVEL4, // 繟 + 0x7E86, KANJI_LEVEL4, // 纆 + 0x7E87, KANJI_LEVEL4, // 纇 + 0x432B, KANJI_LEVEL4, // 䌫 + 0x7E91, KANJI_LEVEL4, // 纑 + 0x7E98, KANJI_LEVEL4, // 纘 + 0x7E9A, KANJI_LEVEL4, // 纚 + 0x4343, KANJI_LEVEL4, // 䍃 + 0x7F3C, KANJI_LEVEL4, // 猌 + 0x7F3B, KANJI_LEVEL4, // 猻 + 0x7F3E, KANJI_LEVEL4, // 猟 + 0x7F43, KANJI_LEVEL4, // 眃 + 0x7F44, KANJI_LEVEL4, // 眄 + 0x7F4F, KANJI_LEVEL4, // 眏 + 0x34C1, KANJI_LEVEL4, // 㓁 + 0xD858, KANJI_LEVEL4, // ᅵ + 0xDE70, KANJI_LEVEL4, // ᅵ + 0x7F52, KANJI_LEVEL4, // 眒 + 0xD858, KANJI_LEVEL4, // ᅵ + 0xDE86, KANJI_LEVEL4, // ᅵ + 0x7F61, KANJI_LEVEL4, // 眡 + 0x7F63, KANJI_LEVEL4, // 眣 + 0x7F64, KANJI_LEVEL4, // 眀 + 0x7F6D, KANJI_LEVEL4, // 眭 + 0x7F7D, KANJI_LEVEL4, // 眜 + 0x7F7E, KANJI_LEVEL4, // 真 + 0xD858, KANJI_LEVEL4, // ᅵ + 0xDF4C, KANJI_LEVEL4, // ᅵ + 0x7F90, KANJI_LEVEL4, // 矐 + 0x517B, KANJI_LEVEL4, // 养 + 0xD84F, KANJI_LEVEL4, // ᅵ + 0xDD0E, KANJI_LEVEL4, // ᅵ + 0x7F96, KANJI_LEVEL4, // 矖 + 0x7F9C, KANJI_LEVEL4, // 矜 + 0x7FAD, KANJI_LEVEL4, // 短 + 0xD859, KANJI_LEVEL4, // ᅵ + 0xDC02, KANJI_LEVEL4, // ᅵ + 0x7FC3, KANJI_LEVEL4, // 翃 + 0x7FCF, KANJI_LEVEL4, // 翏 + 0x7FE3, KANJI_LEVEL4, // ç¿£ + 0x7FE5, KANJI_LEVEL4, // ç¿¥ + 0x7FEF, KANJI_LEVEL4, // 翯 + 0x7FF2, KANJI_LEVEL4, // 翲 + 0x8002, KANJI_LEVEL4, // 耂 + 0x800A, KANJI_LEVEL4, // 耊 + 0x8008, KANJI_LEVEL4, // 耈 + 0x800E, KANJI_LEVEL4, // 耎 + 0x8011, KANJI_LEVEL4, // 耑 + 0x8016, KANJI_LEVEL4, // 耖 + 0x8024, KANJI_LEVEL4, // 耀 + 0x802C, KANJI_LEVEL4, // 耬 + 0x8030, KANJI_LEVEL4, // 耰 + 0x8043, KANJI_LEVEL4, // 聃 + 0x8066, KANJI_LEVEL4, // 聊 + 0x8071, KANJI_LEVEL4, // 聱 + 0x8075, KANJI_LEVEL4, // 聵 + 0x807B, KANJI_LEVEL4, // 聻 + 0x8099, KANJI_LEVEL4, // 肙 + 0x809C, KANJI_LEVEL4, // 肜 + 0x80A4, KANJI_LEVEL4, // è‚€ + 0x80A7, KANJI_LEVEL4, // 肧 + 0x80B8, KANJI_LEVEL4, // 肞 + 0xD859, KANJI_LEVEL4, // ᅵ + 0xDE7E, KANJI_LEVEL4, // ᅵ + 0x80C5, KANJI_LEVEL4, // 胅 + 0x80D5, KANJI_LEVEL4, // 胕 + 0x80D8, KANJI_LEVEL4, // 胘 + 0x80E6, KANJI_LEVEL4, // 胊 + 0xD859, KANJI_LEVEL4, // ᅵ + 0xDEB0, KANJI_LEVEL4, // ᅵ + 0x810D, KANJI_LEVEL4, // 脍 + 0x80F5, KANJI_LEVEL4, // 胵 + 0x80FB, KANJI_LEVEL4, // 胻 + 0x43EE, KANJI_LEVEL4, // 䏮 + 0x8135, KANJI_LEVEL4, // 脵 + 0x8116, KANJI_LEVEL4, // 脖 + 0x811E, KANJI_LEVEL4, // 脞 + 0x43F0, KANJI_LEVEL4, // 䏰 + 0x8124, KANJI_LEVEL4, // è„€ + 0x8127, KANJI_LEVEL4, // 脧 + 0x812C, KANJI_LEVEL4, // 脬 + 0xD859, KANJI_LEVEL4, // ᅵ + 0xDF1D, KANJI_LEVEL4, // ᅵ + 0x813D, KANJI_LEVEL4, // 脜 + 0x4408, KANJI_LEVEL4, // 䐈 + 0x8169, KANJI_LEVEL4, // 腩 + 0x4417, KANJI_LEVEL4, // 䐗 + 0x8181, KANJI_LEVEL4, // 膁 + 0x441C, KANJI_LEVEL4, // 䐜 + 0x8184, KANJI_LEVEL4, // 膄 + 0x8185, KANJI_LEVEL4, // 膅 + 0x4422, KANJI_LEVEL4, // 䐢 + 0x8198, KANJI_LEVEL4, // 膘 + 0x81B2, KANJI_LEVEL4, // 膲 + 0x81C1, KANJI_LEVEL4, // 臁 + 0x81C3, KANJI_LEVEL4, // 臃 + 0x81D6, KANJI_LEVEL4, // 臖 + 0x81DB, KANJI_LEVEL4, // 臛 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDCDD, KANJI_LEVEL4, // ᅵ + 0x81E4, KANJI_LEVEL4, // 臀 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDCEA, KANJI_LEVEL4, // ᅵ + 0x81EC, KANJI_LEVEL4, // 臬 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDD51, KANJI_LEVEL4, // ᅵ + 0x81FD, KANJI_LEVEL4, // 臜 + 0x81FF, KANJI_LEVEL4, // 臿 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDD6F, KANJI_LEVEL4, // ᅵ + 0x8204, KANJI_LEVEL4, // 舄 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDDDD, KANJI_LEVEL4, // ᅵ + 0x8219, KANJI_LEVEL4, // 舙 + 0x8221, KANJI_LEVEL4, // 舡 + 0x8222, KANJI_LEVEL4, // 舢 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDE1E, KANJI_LEVEL4, // ᅵ + 0x8232, KANJI_LEVEL4, // 舲 + 0x8234, KANJI_LEVEL4, // 舎 + 0x823C, KANJI_LEVEL4, // 舌 + 0x8246, KANJI_LEVEL4, // 艆 + 0x8249, KANJI_LEVEL4, // 艉 + 0x8245, KANJI_LEVEL4, // 艅 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDE58, KANJI_LEVEL4, // ᅵ + 0x824B, KANJI_LEVEL4, // 艋 + 0x4476, KANJI_LEVEL4, // 䑶 + 0x824F, KANJI_LEVEL4, // 艏 + 0x447A, KANJI_LEVEL4, // 䑺 + 0x8257, KANJI_LEVEL4, // 艗 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDE8C, KANJI_LEVEL4, // ᅵ + 0x825C, KANJI_LEVEL4, // 艜 + 0x8263, KANJI_LEVEL4, // 艣 + 0xD85A, KANJI_LEVEL4, // ᅵ + 0xDEB7, KANJI_LEVEL4, // ᅵ + 0xFA5D, KANJI_LEVEL4, // 艹 + 0xFA5E, KANJI_LEVEL4, // 艹 + 0x8279, KANJI_LEVEL4, // 艹 + 0x4491, KANJI_LEVEL4, // 䒑 + 0x827D, KANJI_LEVEL4, // 艜 + 0x827F, KANJI_LEVEL4, // 艿 + 0x8283, KANJI_LEVEL4, // 芃 + 0x828A, KANJI_LEVEL4, // 芊 + 0x8293, KANJI_LEVEL4, // 芓 + 0x82A7, KANJI_LEVEL4, // 芧 + 0x82A8, KANJI_LEVEL4, // 芚 + 0x82B2, KANJI_LEVEL4, // 芲 + 0x82B4, KANJI_LEVEL4, // 芎 + 0x82BA, KANJI_LEVEL4, // 芺 + 0x82BC, KANJI_LEVEL4, // 芌 + 0x82E2, KANJI_LEVEL4, // 苢 + 0x82E8, KANJI_LEVEL4, // 苚 + 0x82F7, KANJI_LEVEL4, // 苷 + 0x8307, KANJI_LEVEL4, // 茇 + 0x8308, KANJI_LEVEL4, // 茈 + 0x830C, KANJI_LEVEL4, // 茌 + 0x8354, KANJI_LEVEL4, // 荔 + 0x831B, KANJI_LEVEL4, // 茛 + 0x831D, KANJI_LEVEL4, // 茝 + 0x8330, KANJI_LEVEL4, // 茰 + 0x833C, KANJI_LEVEL4, // 茌 + 0x8344, KANJI_LEVEL4, // 荄 + 0x8357, KANJI_LEVEL4, // 荗 + 0x44BE, KANJI_LEVEL4, // ä’Ÿ + 0x837F, KANJI_LEVEL4, // 荿 + 0x44D4, KANJI_LEVEL4, // 䓔 + 0x44B3, KANJI_LEVEL4, // 䒳 + 0x838D, KANJI_LEVEL4, // 莍 + 0x8394, KANJI_LEVEL4, // 莔 + 0x8395, KANJI_LEVEL4, // 莕 + 0x839B, KANJI_LEVEL4, // 莛 + 0x839D, KANJI_LEVEL4, // 莝 + 0x83C9, KANJI_LEVEL4, // 菉 + 0x83D0, KANJI_LEVEL4, // 菐 + 0x83D4, KANJI_LEVEL4, // 菔 + 0x83DD, KANJI_LEVEL4, // 菝 + 0x83E5, KANJI_LEVEL4, // 菥 + 0x83F9, KANJI_LEVEL4, // 菹 + 0x840F, KANJI_LEVEL4, // 萏 + 0x8411, KANJI_LEVEL4, // 萑 + 0x8415, KANJI_LEVEL4, // 萕 + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDC73, KANJI_LEVEL4, // ᅵ + 0x8417, KANJI_LEVEL4, // 萗 + 0x8439, KANJI_LEVEL4, // 萹 + 0x844A, KANJI_LEVEL4, // 葊 + 0x844F, KANJI_LEVEL4, // 葏 + 0x8451, KANJI_LEVEL4, // 葑 + 0x8452, KANJI_LEVEL4, // 葒 + 0x8459, KANJI_LEVEL4, // 葙 + 0x845A, KANJI_LEVEL4, // 葚 + 0x845C, KANJI_LEVEL4, // 葜 + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDCDD, KANJI_LEVEL4, // ᅵ + 0x8465, KANJI_LEVEL4, // 葥 + 0x8476, KANJI_LEVEL4, // 葶 + 0x8478, KANJI_LEVEL4, // 葞 + 0x847C, KANJI_LEVEL4, // 葌 + 0x8481, KANJI_LEVEL4, // 蒁 + 0x450D, KANJI_LEVEL4, // 䔍 + 0x84DC, KANJI_LEVEL4, // 蓜 + 0x8497, KANJI_LEVEL4, // 蒗 + 0x84A6, KANJI_LEVEL4, // è’Š + 0x84BE, KANJI_LEVEL4, // è’Ÿ + 0x4508, KANJI_LEVEL4, // 䔈 + 0x84CE, KANJI_LEVEL4, // 蓎 + 0x84CF, KANJI_LEVEL4, // 蓏 + 0x84D3, KANJI_LEVEL4, // 蓓 + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDE65, KANJI_LEVEL4, // ᅵ + 0x84E7, KANJI_LEVEL4, // 蓧 + 0x84EA, KANJI_LEVEL4, // 蓪 + 0x84EF, KANJI_LEVEL4, // 蓯 + 0x84F0, KANJI_LEVEL4, // 蓰 + 0x84F1, KANJI_LEVEL4, // 蓱 + 0x84FA, KANJI_LEVEL4, // 蓺 + 0x84FD, KANJI_LEVEL4, // 蓜 + 0x850C, KANJI_LEVEL4, // 蔌 + 0x851B, KANJI_LEVEL4, // 蔛 + 0x8524, KANJI_LEVEL4, // 蔀 + 0x8525, KANJI_LEVEL4, // 蔥 + 0x852B, KANJI_LEVEL4, // 蔫 + 0x8534, KANJI_LEVEL4, // 蔎 + 0x854F, KANJI_LEVEL4, // 蕏 + 0x856F, KANJI_LEVEL4, // 蕯 + 0x4525, KANJI_LEVEL4, // 䔥 + 0x4543, KANJI_LEVEL4, // 䕃 + 0x853E, KANJI_LEVEL4, // 蔟 + 0x8551, KANJI_LEVEL4, // 蕑 + 0x8553, KANJI_LEVEL4, // 蕓 + 0x855E, KANJI_LEVEL4, // 蕞 + 0x8561, KANJI_LEVEL4, // 蕡 + 0x8562, KANJI_LEVEL4, // 蕢 + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDF94, KANJI_LEVEL4, // ᅵ + 0x857B, KANJI_LEVEL4, // 蕻 + 0x857D, KANJI_LEVEL4, // 蕜 + 0x857F, KANJI_LEVEL4, // 蕿 + 0x8581, KANJI_LEVEL4, // 薁 + 0x8586, KANJI_LEVEL4, // 薆 + 0x8593, KANJI_LEVEL4, // 薓 + 0x859D, KANJI_LEVEL4, // 薝 + 0x859F, KANJI_LEVEL4, // 薟 + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDFF8, KANJI_LEVEL4, // ᅵ + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDFF6, KANJI_LEVEL4, // ᅵ + 0xD85B, KANJI_LEVEL4, // ᅵ + 0xDFF7, KANJI_LEVEL4, // ᅵ + 0x85B7, KANJI_LEVEL4, // 薷 + 0x85BC, KANJI_LEVEL4, // è–Œ + 0x85C7, KANJI_LEVEL4, // 藇 + 0x85CA, KANJI_LEVEL4, // 藊 + 0x85D8, KANJI_LEVEL4, // 藘 + 0x85D9, KANJI_LEVEL4, // 藙 + 0x85DF, KANJI_LEVEL4, // 藟 + 0x85E1, KANJI_LEVEL4, // 藡 + 0x85E6, KANJI_LEVEL4, // è—Š + 0x85F6, KANJI_LEVEL4, // 藶 + 0x8600, KANJI_LEVEL4, // 蘀 + 0x8611, KANJI_LEVEL4, // 蘑 + 0x861E, KANJI_LEVEL4, // 蘞 + 0x8621, KANJI_LEVEL4, // 蘡 + 0x8624, KANJI_LEVEL4, // 蘀 + 0x8627, KANJI_LEVEL4, // 蘧 + 0xD85C, KANJI_LEVEL4, // ᅵ + 0xDD0D, KANJI_LEVEL4, // ᅵ + 0x8639, KANJI_LEVEL4, // 蘹 + 0x863C, KANJI_LEVEL4, // 蘌 + 0xD85C, KANJI_LEVEL4, // ᅵ + 0xDD39, KANJI_LEVEL4, // ᅵ + 0x8640, KANJI_LEVEL4, // 虀 + 0xFA20, KANJI_LEVEL4, // ïš  + 0x8653, KANJI_LEVEL4, // 虓 + 0x8656, KANJI_LEVEL4, // 虖 + 0x866F, KANJI_LEVEL4, // 虯 + 0x8677, KANJI_LEVEL4, // 虷 + 0x867A, KANJI_LEVEL4, // 虺 + 0x8687, KANJI_LEVEL4, // 蚇 + 0x8689, KANJI_LEVEL4, // 蚉 + 0x868D, KANJI_LEVEL4, // 蚍 + 0x8691, KANJI_LEVEL4, // 蚑 + 0x869C, KANJI_LEVEL4, // 蚜 + 0x869D, KANJI_LEVEL4, // 蚝 + 0x86A8, KANJI_LEVEL4, // èšš + 0xFA21, KANJI_LEVEL4, // ïš¡ + 0x86B1, KANJI_LEVEL4, // 蚱 + 0x86B3, KANJI_LEVEL4, // 蚳 + 0x86C1, KANJI_LEVEL4, // 蛁 + 0x86C3, KANJI_LEVEL4, // 蛃 + 0x86D1, KANJI_LEVEL4, // 蛑 + 0x86D5, KANJI_LEVEL4, // 蛕 + 0x86D7, KANJI_LEVEL4, // 蛗 + 0x86E3, KANJI_LEVEL4, // 蛣 + 0x86E6, KANJI_LEVEL4, // 蛊 + 0x45B8, KANJI_LEVEL4, // 䖾 + 0x8705, KANJI_LEVEL4, // 蜅 + 0x8707, KANJI_LEVEL4, // 蜇 + 0x870E, KANJI_LEVEL4, // 蜎 + 0x8710, KANJI_LEVEL4, // 蜐 + 0x8713, KANJI_LEVEL4, // 蜓 + 0x8719, KANJI_LEVEL4, // 蜙 + 0x871F, KANJI_LEVEL4, // 蜟 + 0x8721, KANJI_LEVEL4, // 蜡 + 0x8723, KANJI_LEVEL4, // 蜣 + 0x8731, KANJI_LEVEL4, // 蜱 + 0x873A, KANJI_LEVEL4, // 蜺 + 0x873E, KANJI_LEVEL4, // 蜟 + 0x8740, KANJI_LEVEL4, // 蝀 + 0x8743, KANJI_LEVEL4, // 蝃 + 0x8751, KANJI_LEVEL4, // 蝑 + 0x8758, KANJI_LEVEL4, // 蝘 + 0x8764, KANJI_LEVEL4, // 蝀 + 0x8765, KANJI_LEVEL4, // 蝥 + 0x8772, KANJI_LEVEL4, // 蝲 + 0x877C, KANJI_LEVEL4, // 蝌 + 0xD85C, KANJI_LEVEL4, // ᅵ + 0xDFDB, KANJI_LEVEL4, // ᅵ + 0xD85C, KANJI_LEVEL4, // ᅵ + 0xDFDA, KANJI_LEVEL4, // ᅵ + 0x87A7, KANJI_LEVEL4, // 螧 + 0x8789, KANJI_LEVEL4, // 螉 + 0x878B, KANJI_LEVEL4, // 螋 + 0x8793, KANJI_LEVEL4, // 螓 + 0x87A0, KANJI_LEVEL4, // 螠 + 0xD85C, KANJI_LEVEL4, // ᅵ + 0xDFFE, KANJI_LEVEL4, // ᅵ + 0x45E5, KANJI_LEVEL4, // 䗥 + 0x87BE, KANJI_LEVEL4, // 螟 + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDC10, KANJI_LEVEL4, // ᅵ + 0x87C1, KANJI_LEVEL4, // 蟁 + 0x87CE, KANJI_LEVEL4, // 蟎 + 0x87F5, KANJI_LEVEL4, // 蟵 + 0x87DF, KANJI_LEVEL4, // 蟟 + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDC49, KANJI_LEVEL4, // ᅵ + 0x87E3, KANJI_LEVEL4, // 蟣 + 0x87E5, KANJI_LEVEL4, // 蟥 + 0x87E6, KANJI_LEVEL4, // 蟊 + 0x87EA, KANJI_LEVEL4, // 蟪 + 0x87EB, KANJI_LEVEL4, // 蟫 + 0x87ED, KANJI_LEVEL4, // 蟭 + 0x8801, KANJI_LEVEL4, // 蠁 + 0x8803, KANJI_LEVEL4, // 蠃 + 0x880B, KANJI_LEVEL4, // 蠋 + 0x8813, KANJI_LEVEL4, // 蠓 + 0x8828, KANJI_LEVEL4, // è š + 0x882E, KANJI_LEVEL4, // è ® + 0x8832, KANJI_LEVEL4, // è ² + 0x883C, KANJI_LEVEL4, // è Œ + 0x460F, KANJI_LEVEL4, // 䘏 + 0x884A, KANJI_LEVEL4, // 衊 + 0x8858, KANJI_LEVEL4, // 衘 + 0x885F, KANJI_LEVEL4, // 衟 + 0x8864, KANJI_LEVEL4, // è¡€ + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDE15, KANJI_LEVEL4, // ᅵ + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDE14, KANJI_LEVEL4, // ᅵ + 0x8869, KANJI_LEVEL4, // è¡© + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDE31, KANJI_LEVEL4, // ᅵ + 0x886F, KANJI_LEVEL4, // 衯 + 0x88A0, KANJI_LEVEL4, // 袠 + 0x88BC, KANJI_LEVEL4, // 袌 + 0x88BD, KANJI_LEVEL4, // 袜 + 0x88BE, KANJI_LEVEL4, // 袟 + 0x88C0, KANJI_LEVEL4, // 裀 + 0x88D2, KANJI_LEVEL4, // 裒 + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDE93, KANJI_LEVEL4, // ᅵ + 0x88D1, KANJI_LEVEL4, // 裑 + 0x88D3, KANJI_LEVEL4, // 裓 + 0x88DB, KANJI_LEVEL4, // 裛 + 0x88F0, KANJI_LEVEL4, // 裰 + 0x88F1, KANJI_LEVEL4, // 裱 + 0x4641, KANJI_LEVEL4, // 䙁 + 0x8901, KANJI_LEVEL4, // 老 + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDF0E, KANJI_LEVEL4, // ᅵ + 0x8937, KANJI_LEVEL4, // 耷 + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDF23, KANJI_LEVEL4, // ᅵ + 0x8942, KANJI_LEVEL4, // 襂 + 0x8945, KANJI_LEVEL4, // 襅 + 0x8949, KANJI_LEVEL4, // 襉 + 0xD85D, KANJI_LEVEL4, // ᅵ + 0xDF52, KANJI_LEVEL4, // ᅵ + 0x4665, KANJI_LEVEL4, // 䙥 + 0x8962, KANJI_LEVEL4, // 襢 + 0x8980, KANJI_LEVEL4, // 芀 + 0x8989, KANJI_LEVEL4, // 芉 + 0x8990, KANJI_LEVEL4, // 芐 + 0x899F, KANJI_LEVEL4, // 芟 + 0x89B0, KANJI_LEVEL4, // 芰 + 0x89B7, KANJI_LEVEL4, // 芷 + 0x89D6, KANJI_LEVEL4, // 觖 + 0x89D8, KANJI_LEVEL4, // 觘 + 0x89EB, KANJI_LEVEL4, // è§« + 0x46A1, KANJI_LEVEL4, // 䚡 + 0x89F1, KANJI_LEVEL4, // è§± + 0x89F3, KANJI_LEVEL4, // è§³ + 0x89FD, KANJI_LEVEL4, // è§œ + 0x89FF, KANJI_LEVEL4, // è§¿ + 0x46AF, KANJI_LEVEL4, // 䚯 + 0x8A11, KANJI_LEVEL4, // èš‘ + 0x8A14, KANJI_LEVEL4, // èš” + 0xD85E, KANJI_LEVEL4, // ᅵ + 0xDD85, KANJI_LEVEL4, // ᅵ + 0x8A21, KANJI_LEVEL4, // èš¡ + 0x8A35, KANJI_LEVEL4, // èšµ + 0x8A3E, KANJI_LEVEL4, // 蚟 + 0x8A45, KANJI_LEVEL4, // 詅 + 0x8A4D, KANJI_LEVEL4, // 詍 + 0x8A58, KANJI_LEVEL4, // 詘 + 0x8AAE, KANJI_LEVEL4, // 誮 + 0x8A90, KANJI_LEVEL4, // 誐 + 0x8AB7, KANJI_LEVEL4, // 誷 + 0x8ABE, KANJI_LEVEL4, // 誟 + 0x8AD7, KANJI_LEVEL4, // 諗 + 0x8AFC, KANJI_LEVEL4, // 諌 + 0xD85E, KANJI_LEVEL4, // ᅵ + 0xDE84, KANJI_LEVEL4, // ᅵ + 0x8B0A, KANJI_LEVEL4, // 謊 + 0x8B05, KANJI_LEVEL4, // 謅 + 0x8B0D, KANJI_LEVEL4, // 謍 + 0x8B1C, KANJI_LEVEL4, // 謜 + 0x8B1F, KANJI_LEVEL4, // 謟 + 0x8B2D, KANJI_LEVEL4, // 謭 + 0x8B43, KANJI_LEVEL4, // 譃 + 0x470C, KANJI_LEVEL4, // 䜌 + 0x8B51, KANJI_LEVEL4, // 譑 + 0x8B5E, KANJI_LEVEL4, // 譞 + 0x8B76, KANJI_LEVEL4, // è­¶ + 0x8B7F, KANJI_LEVEL4, // è­¿ + 0x8B81, KANJI_LEVEL4, // 讁 + 0x8B8B, KANJI_LEVEL4, // 讋 + 0x8B94, KANJI_LEVEL4, // 讔 + 0x8B95, KANJI_LEVEL4, // 讕 + 0x8B9C, KANJI_LEVEL4, // 讜 + 0x8B9E, KANJI_LEVEL4, // 讞 + 0x8C39, KANJI_LEVEL4, // è°¹ + 0xD85E, KANJI_LEVEL4, // ᅵ + 0xDFB3, KANJI_LEVEL4, // ᅵ + 0x8C3D, KANJI_LEVEL4, // è°œ + 0xD85E, KANJI_LEVEL4, // ᅵ + 0xDFBE, KANJI_LEVEL4, // ᅵ + 0xD85E, KANJI_LEVEL4, // ᅵ + 0xDFC7, KANJI_LEVEL4, // ᅵ + 0x8C45, KANJI_LEVEL4, // 豅 + 0x8C47, KANJI_LEVEL4, // 豇 + 0x8C4F, KANJI_LEVEL4, // 豏 + 0x8C54, KANJI_LEVEL4, // 豔 + 0x8C57, KANJI_LEVEL4, // 豗 + 0x8C69, KANJI_LEVEL4, // 豩 + 0x8C6D, KANJI_LEVEL4, // è±­ + 0x8C73, KANJI_LEVEL4, // è±³ + 0xD85F, KANJI_LEVEL4, // ᅵ + 0xDCB8, KANJI_LEVEL4, // ᅵ + 0x8C93, KANJI_LEVEL4, // 貓 + 0x8C92, KANJI_LEVEL4, // 貒 + 0x8C99, KANJI_LEVEL4, // 貙 + 0x4764, KANJI_LEVEL4, // 䝀 + 0x8C9B, KANJI_LEVEL4, // 貛 + 0x8CA4, KANJI_LEVEL4, // è²€ + 0x8CD6, KANJI_LEVEL4, // 賖 + 0x8CD5, KANJI_LEVEL4, // 賕 + 0x8CD9, KANJI_LEVEL4, // 賙 + 0xD85F, KANJI_LEVEL4, // ᅵ + 0xDDA0, KANJI_LEVEL4, // ᅵ + 0x8CF0, KANJI_LEVEL4, // è³° + 0x8CF1, KANJI_LEVEL4, // è³± + 0xD85F, KANJI_LEVEL4, // ᅵ + 0xDE10, KANJI_LEVEL4, // ᅵ + 0x8D09, KANJI_LEVEL4, // 莉 + 0x8D0E, KANJI_LEVEL4, // 莎 + 0x8D6C, KANJI_LEVEL4, // 赬 + 0x8D84, KANJI_LEVEL4, // 趄 + 0x8D95, KANJI_LEVEL4, // 趕 + 0x8DA6, KANJI_LEVEL4, // è¶Š + 0xD85F, KANJI_LEVEL4, // ᅵ + 0xDFB7, KANJI_LEVEL4, // ᅵ + 0x8DC6, KANJI_LEVEL4, // 跆 + 0x8DC8, KANJI_LEVEL4, // 跈 + 0x8DD9, KANJI_LEVEL4, // 跙 + 0x8DEC, KANJI_LEVEL4, // è·¬ + 0x8E0C, KANJI_LEVEL4, // 螌 + 0x47FD, KANJI_LEVEL4, // 䟜 + 0x8DFD, KANJI_LEVEL4, // è·œ + 0x8E06, KANJI_LEVEL4, // 螆 + 0xD860, KANJI_LEVEL4, // ᅵ + 0xDC8A, KANJI_LEVEL4, // ᅵ + 0x8E14, KANJI_LEVEL4, // èž” + 0x8E16, KANJI_LEVEL4, // èž– + 0x8E21, KANJI_LEVEL4, // èž¡ + 0x8E22, KANJI_LEVEL4, // 螢 + 0x8E27, KANJI_LEVEL4, // èž§ + 0xD860, KANJI_LEVEL4, // ᅵ + 0xDCBB, KANJI_LEVEL4, // ᅵ + 0x4816, KANJI_LEVEL4, // 䠖 + 0x8E36, KANJI_LEVEL4, // èž¶ + 0x8E39, KANJI_LEVEL4, // èž¹ + 0x8E4B, KANJI_LEVEL4, // 蹋 + 0x8E54, KANJI_LEVEL4, // 蹔 + 0x8E62, KANJI_LEVEL4, // è¹¢ + 0x8E6C, KANJI_LEVEL4, // 蹬 + 0x8E6D, KANJI_LEVEL4, // è¹­ + 0x8E6F, KANJI_LEVEL4, // 蹯 + 0x8E98, KANJI_LEVEL4, // 躘 + 0x8E9E, KANJI_LEVEL4, // 躞 + 0x8EAE, KANJI_LEVEL4, // 躮 + 0x8EB3, KANJI_LEVEL4, // 躳 + 0x8EB5, KANJI_LEVEL4, // 躵 + 0x8EB6, KANJI_LEVEL4, // 躶 + 0x8EBB, KANJI_LEVEL4, // 躻 + 0xD860, KANJI_LEVEL4, // ᅵ + 0xDE82, KANJI_LEVEL4, // ᅵ + 0x8ED1, KANJI_LEVEL4, // 軑 + 0x8ED4, KANJI_LEVEL4, // 軔 + 0x484E, KANJI_LEVEL4, // 䡎 + 0x8EF9, KANJI_LEVEL4, // 軹 + 0xD860, KANJI_LEVEL4, // ᅵ + 0xDEF3, KANJI_LEVEL4, // ᅵ + 0x8F00, KANJI_LEVEL4, // 茀 + 0x8F08, KANJI_LEVEL4, // 茈 + 0x8F17, KANJI_LEVEL4, // 茗 + 0x8F2B, KANJI_LEVEL4, // 茫 + 0x8F40, KANJI_LEVEL4, // 蜀 + 0x8F4A, KANJI_LEVEL4, // 蜊 + 0x8F58, KANJI_LEVEL4, // 蜘 + 0xD861, KANJI_LEVEL4, // ᅵ + 0xDC0C, KANJI_LEVEL4, // ᅵ + 0x8FA4, KANJI_LEVEL4, // 蟀 + 0x8FB4, KANJI_LEVEL4, // 蟎 + 0xFA66, KANJI_LEVEL4, // 琢 + 0x8FB6, KANJI_LEVEL4, // 蟶 + 0xD861, KANJI_LEVEL4, // ᅵ + 0xDC55, KANJI_LEVEL4, // ᅵ + 0x8FC1, KANJI_LEVEL4, // 迁 + 0x8FC6, KANJI_LEVEL4, // 迆 + 0xFA24, KANJI_LEVEL4, //  + 0x8FCA, KANJI_LEVEL4, // 迊 + 0x8FCD, KANJI_LEVEL4, // 迍 + 0x8FD3, KANJI_LEVEL4, // 迓 + 0x8FD5, KANJI_LEVEL4, // 迕 + 0x8FE0, KANJI_LEVEL4, // è¿  + 0x8FF1, KANJI_LEVEL4, // 迱 + 0x8FF5, KANJI_LEVEL4, // 迵 + 0x8FFB, KANJI_LEVEL4, // è¿» + 0x9002, KANJI_LEVEL4, // 适 + 0x900C, KANJI_LEVEL4, // 逌 + 0x9037, KANJI_LEVEL4, // 逷 + 0xD861, KANJI_LEVEL4, // ᅵ + 0xDD6B, KANJI_LEVEL4, // ᅵ + 0x9043, KANJI_LEVEL4, // 遃 + 0x9044, KANJI_LEVEL4, // 遄 + 0x905D, KANJI_LEVEL4, // 遝 + 0xD861, KANJI_LEVEL4, // ᅵ + 0xDDC8, KANJI_LEVEL4, // ᅵ + 0xD861, KANJI_LEVEL4, // ᅵ + 0xDDC9, KANJI_LEVEL4, // ᅵ + 0x9085, KANJI_LEVEL4, // 邅 + 0x908C, KANJI_LEVEL4, // 邌 + 0x9090, KANJI_LEVEL4, // 邐 + 0x961D, KANJI_LEVEL4, // 阝 + 0x90A1, KANJI_LEVEL4, // 邡 + 0x48B5, KANJI_LEVEL4, // 䢵 + 0x90B0, KANJI_LEVEL4, // 邰 + 0x90B6, KANJI_LEVEL4, // 邶 + 0x90C3, KANJI_LEVEL4, // 郃 + 0x90C8, KANJI_LEVEL4, // 郈 + 0xD861, KANJI_LEVEL4, // ᅵ + 0xDED7, KANJI_LEVEL4, // ᅵ + 0x90DC, KANJI_LEVEL4, // 郜 + 0x90DF, KANJI_LEVEL4, // 郟 + 0xD861, KANJI_LEVEL4, // ᅵ + 0xDEFA, KANJI_LEVEL4, // ᅵ + 0x90F6, KANJI_LEVEL4, // 郶 + 0x90F2, KANJI_LEVEL4, // 郲 + 0x9100, KANJI_LEVEL4, // 鄀 + 0x90EB, KANJI_LEVEL4, // 郫 + 0x90FE, KANJI_LEVEL4, // 郟 + 0x90FF, KANJI_LEVEL4, // 郿 + 0x9104, KANJI_LEVEL4, // 鄄 + 0x9106, KANJI_LEVEL4, // 鄆 + 0x9118, KANJI_LEVEL4, // 鄘 + 0x911C, KANJI_LEVEL4, // 鄜 + 0x911E, KANJI_LEVEL4, // 鄞 + 0x9137, KANJI_LEVEL4, // 鄷 + 0x9139, KANJI_LEVEL4, // 鄹 + 0x913A, KANJI_LEVEL4, // 鄺 + 0x9146, KANJI_LEVEL4, // 酆 + 0x9147, KANJI_LEVEL4, // 酇 + 0x9157, KANJI_LEVEL4, // 酗 + 0x9159, KANJI_LEVEL4, // 酙 + 0x9161, KANJI_LEVEL4, // 酡 + 0x9164, KANJI_LEVEL4, // é…€ + 0x9174, KANJI_LEVEL4, // 酮 + 0x9179, KANJI_LEVEL4, // 酹 + 0x9185, KANJI_LEVEL4, // 醅 + 0x918E, KANJI_LEVEL4, // 醎 + 0x91A8, KANJI_LEVEL4, // 醹 + 0x91AE, KANJI_LEVEL4, // 醮 + 0x91B3, KANJI_LEVEL4, // 醳 + 0x91B6, KANJI_LEVEL4, // 醶 + 0x91C3, KANJI_LEVEL4, // 釃 + 0x91C4, KANJI_LEVEL4, // 釄 + 0x91DA, KANJI_LEVEL4, // 釚 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDD49, KANJI_LEVEL4, // ᅵ + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDD46, KANJI_LEVEL4, // ᅵ + 0x91EC, KANJI_LEVEL4, // 釬 + 0x91EE, KANJI_LEVEL4, // 釮 + 0x9201, KANJI_LEVEL4, // 鈁 + 0x920A, KANJI_LEVEL4, // 鈊 + 0x9216, KANJI_LEVEL4, // 鈖 + 0x9217, KANJI_LEVEL4, // 鈗 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDD6B, KANJI_LEVEL4, // ᅵ + 0x9233, KANJI_LEVEL4, // 鈳 + 0x9242, KANJI_LEVEL4, // 鉂 + 0x9247, KANJI_LEVEL4, // 鉇 + 0x924A, KANJI_LEVEL4, // 鉊 + 0x924E, KANJI_LEVEL4, // 鉎 + 0x9251, KANJI_LEVEL4, // 鉑 + 0x9256, KANJI_LEVEL4, // 鉖 + 0x9259, KANJI_LEVEL4, // 鉙 + 0x9260, KANJI_LEVEL4, // 鉠 + 0x9261, KANJI_LEVEL4, // 鉡 + 0x9265, KANJI_LEVEL4, // 鉥 + 0x9267, KANJI_LEVEL4, // 鉧 + 0x9268, KANJI_LEVEL4, // 鉹 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDD87, KANJI_LEVEL4, // ᅵ + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDD88, KANJI_LEVEL4, // ᅵ + 0x927C, KANJI_LEVEL4, // 鉌 + 0x927D, KANJI_LEVEL4, // 鉜 + 0x927F, KANJI_LEVEL4, // 鉿 + 0x9289, KANJI_LEVEL4, // 銉 + 0x928D, KANJI_LEVEL4, // 銍 + 0x9297, KANJI_LEVEL4, // 銗 + 0x9299, KANJI_LEVEL4, // 銙 + 0x929F, KANJI_LEVEL4, // 銟 + 0x92A7, KANJI_LEVEL4, // 銧 + 0x92AB, KANJI_LEVEL4, // 銫 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDDBA, KANJI_LEVEL4, // ᅵ + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDDBB, KANJI_LEVEL4, // ᅵ + 0x92B2, KANJI_LEVEL4, // 銲 + 0x92BF, KANJI_LEVEL4, // 銿 + 0x92C0, KANJI_LEVEL4, // 鋀 + 0x92C6, KANJI_LEVEL4, // 鋆 + 0x92CE, KANJI_LEVEL4, // 鋎 + 0x92D0, KANJI_LEVEL4, // 鋐 + 0x92D7, KANJI_LEVEL4, // 鋗 + 0x92D9, KANJI_LEVEL4, // 鋙 + 0x92E5, KANJI_LEVEL4, // 鋥 + 0x92E7, KANJI_LEVEL4, // 鋧 + 0x9311, KANJI_LEVEL4, // 錑 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDE1E, KANJI_LEVEL4, // ᅵ + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDE29, KANJI_LEVEL4, // ᅵ + 0x92F7, KANJI_LEVEL4, // 鋷 + 0x92F9, KANJI_LEVEL4, // 鋹 + 0x92FB, KANJI_LEVEL4, // 鋻 + 0x9302, KANJI_LEVEL4, // 錂 + 0x930D, KANJI_LEVEL4, // 錍 + 0x9315, KANJI_LEVEL4, // 錕 + 0x931D, KANJI_LEVEL4, // 錝 + 0x931E, KANJI_LEVEL4, // 錞 + 0x9327, KANJI_LEVEL4, // 錧 + 0x9329, KANJI_LEVEL4, // 錩 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDE71, KANJI_LEVEL4, // ᅵ + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDE43, KANJI_LEVEL4, // ᅵ + 0x9347, KANJI_LEVEL4, // 鍇 + 0x9351, KANJI_LEVEL4, // 鍑 + 0x9357, KANJI_LEVEL4, // 鍗 + 0x935A, KANJI_LEVEL4, // 鍚 + 0x936B, KANJI_LEVEL4, // 鍫 + 0x9371, KANJI_LEVEL4, // 鍱 + 0x9373, KANJI_LEVEL4, // 鍳 + 0x93A1, KANJI_LEVEL4, // 鎡 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDE99, KANJI_LEVEL4, // ᅵ + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDECD, KANJI_LEVEL4, // ᅵ + 0x9388, KANJI_LEVEL4, // 鎈 + 0x938B, KANJI_LEVEL4, // 鎋 + 0x938F, KANJI_LEVEL4, // 鎏 + 0x939E, KANJI_LEVEL4, // 鎞 + 0x93F5, KANJI_LEVEL4, // 鏵 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDEE4, KANJI_LEVEL4, // ᅵ + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDEDD, KANJI_LEVEL4, // ᅵ + 0x93F1, KANJI_LEVEL4, // 鏱 + 0x93C1, KANJI_LEVEL4, // 鏁 + 0x93C7, KANJI_LEVEL4, // 鏇 + 0x93DC, KANJI_LEVEL4, // 鏜 + 0x93E2, KANJI_LEVEL4, // 鏢 + 0x93E7, KANJI_LEVEL4, // 鏧 + 0x9409, KANJI_LEVEL4, // 鐉 + 0x940F, KANJI_LEVEL4, // 鐏 + 0x9416, KANJI_LEVEL4, // 鐖 + 0x9417, KANJI_LEVEL4, // 鐗 + 0x93FB, KANJI_LEVEL4, // 鏻 + 0x9432, KANJI_LEVEL4, // 鐲 + 0x9434, KANJI_LEVEL4, // 鐎 + 0x943B, KANJI_LEVEL4, // 鐻 + 0x9445, KANJI_LEVEL4, // 鑅 + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDFC1, KANJI_LEVEL4, // ᅵ + 0xD862, KANJI_LEVEL4, // ᅵ + 0xDFEF, KANJI_LEVEL4, // ᅵ + 0x946D, KANJI_LEVEL4, // 鑭 + 0x946F, KANJI_LEVEL4, // 鑯 + 0x9578, KANJI_LEVEL4, // 镾 + 0x9579, KANJI_LEVEL4, // 镹 + 0x9586, KANJI_LEVEL4, // 閆 + 0x958C, KANJI_LEVEL4, // 閌 + 0x958D, KANJI_LEVEL4, // 閍 + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDD10, KANJI_LEVEL4, // ᅵ + 0x95AB, KANJI_LEVEL4, // 閫 + 0x95B4, KANJI_LEVEL4, // 閮 + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDD71, KANJI_LEVEL4, // ᅵ + 0x95C8, KANJI_LEVEL4, // 闈 + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDDFB, KANJI_LEVEL4, // ᅵ + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDE1F, KANJI_LEVEL4, // ᅵ + 0x962C, KANJI_LEVEL4, // 阬 + 0x9633, KANJI_LEVEL4, // 阳 + 0x9634, KANJI_LEVEL4, // 阎 + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDE36, KANJI_LEVEL4, // ᅵ + 0x963C, KANJI_LEVEL4, // 阌 + 0x9641, KANJI_LEVEL4, // 陁 + 0x9661, KANJI_LEVEL4, // 陡 + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDE89, KANJI_LEVEL4, // ᅵ + 0x9682, KANJI_LEVEL4, // 隂 + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDEEB, KANJI_LEVEL4, // ᅵ + 0x969A, KANJI_LEVEL4, // 隚 + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDF32, KANJI_LEVEL4, // ᅵ + 0x49E7, KANJI_LEVEL4, // ä§§ + 0x96A9, KANJI_LEVEL4, // 隩 + 0x96AF, KANJI_LEVEL4, // 隯 + 0x96B3, KANJI_LEVEL4, // 隳 + 0x96BA, KANJI_LEVEL4, // 隺 + 0x96BD, KANJI_LEVEL4, // éšœ + 0x49FA, KANJI_LEVEL4, // 䧺 + 0xD863, KANJI_LEVEL4, // ᅵ + 0xDFF8, KANJI_LEVEL4, // ᅵ + 0x96D8, KANJI_LEVEL4, // 雘 + 0x96DA, KANJI_LEVEL4, // 雚 + 0x96DD, KANJI_LEVEL4, // 雝 + 0x4A04, KANJI_LEVEL4, // 乄 + 0x9714, KANJI_LEVEL4, // 霔 + 0x9723, KANJI_LEVEL4, // 霣 + 0x4A29, KANJI_LEVEL4, // äš© + 0x9736, KANJI_LEVEL4, // 霶 + 0x9741, KANJI_LEVEL4, // 靁 + 0x9747, KANJI_LEVEL4, // 靇 + 0x9755, KANJI_LEVEL4, // 靕 + 0x9757, KANJI_LEVEL4, // 靗 + 0x975B, KANJI_LEVEL4, // 靛 + 0x976A, KANJI_LEVEL4, // 靪 + 0xD864, KANJI_LEVEL4, // ᅵ + 0xDEA0, KANJI_LEVEL4, // ᅵ + 0xD864, KANJI_LEVEL4, // ᅵ + 0xDEB1, KANJI_LEVEL4, // ᅵ + 0x9796, KANJI_LEVEL4, // 鞖 + 0x979A, KANJI_LEVEL4, // 鞚 + 0x979E, KANJI_LEVEL4, // 鞞 + 0x97A2, KANJI_LEVEL4, // 鞢 + 0x97B1, KANJI_LEVEL4, // 鞱 + 0x97B2, KANJI_LEVEL4, // 鞲 + 0x97BE, KANJI_LEVEL4, // 鞟 + 0x97CC, KANJI_LEVEL4, // 韌 + 0x97D1, KANJI_LEVEL4, // 韑 + 0x97D4, KANJI_LEVEL4, // 韔 + 0x97D8, KANJI_LEVEL4, // 韘 + 0x97D9, KANJI_LEVEL4, // 韙 + 0x97E1, KANJI_LEVEL4, // 韡 + 0x97F1, KANJI_LEVEL4, // 韱 + 0x9804, KANJI_LEVEL4, // 頄 + 0x980D, KANJI_LEVEL4, // 頍 + 0x980E, KANJI_LEVEL4, // 頎 + 0x9814, KANJI_LEVEL4, // 頔 + 0x9816, KANJI_LEVEL4, // 頖 + 0x4ABC, KANJI_LEVEL4, // 䪌 + 0xD865, KANJI_LEVEL4, // ᅵ + 0xDC90, KANJI_LEVEL4, // ᅵ + 0x9823, KANJI_LEVEL4, // é £ + 0x9832, KANJI_LEVEL4, // é ² + 0x9833, KANJI_LEVEL4, // é ³ + 0x9825, KANJI_LEVEL4, // é ¥ + 0x9847, KANJI_LEVEL4, // 顇 + 0x9866, KANJI_LEVEL4, // 顊 + 0x98AB, KANJI_LEVEL4, // 颫 + 0x98AD, KANJI_LEVEL4, // 颭 + 0x98B0, KANJI_LEVEL4, // 颰 + 0xD865, KANJI_LEVEL4, // ᅵ + 0xDDCF, KANJI_LEVEL4, // ᅵ + 0x98B7, KANJI_LEVEL4, // 颷 + 0x98B8, KANJI_LEVEL4, // 颞 + 0x98BB, KANJI_LEVEL4, // 颻 + 0x98BC, KANJI_LEVEL4, // 颌 + 0x98BF, KANJI_LEVEL4, // 颿 + 0x98C2, KANJI_LEVEL4, // 飂 + 0x98C7, KANJI_LEVEL4, // 飇 + 0x98CB, KANJI_LEVEL4, // 飋 + 0x98E0, KANJI_LEVEL4, // 飠 + 0xD865, KANJI_LEVEL4, // ᅵ + 0xDE7F, KANJI_LEVEL4, // ᅵ + 0x98E1, KANJI_LEVEL4, // 飡 + 0x98E3, KANJI_LEVEL4, // 飣 + 0x98E5, KANJI_LEVEL4, // 飥 + 0x98EA, KANJI_LEVEL4, // 飪 + 0x98F0, KANJI_LEVEL4, // 飰 + 0x98F1, KANJI_LEVEL4, // 飱 + 0x98F3, KANJI_LEVEL4, // 飳 + 0x9908, KANJI_LEVEL4, // 逈 + 0x4B3B, KANJI_LEVEL4, // 䬻 + 0xD865, KANJI_LEVEL4, // ᅵ + 0xDEF0, KANJI_LEVEL4, // ᅵ + 0x9916, KANJI_LEVEL4, // 逖 + 0x9917, KANJI_LEVEL4, // 逗 + 0xD865, KANJI_LEVEL4, // ᅵ + 0xDF19, KANJI_LEVEL4, // ᅵ + 0x991A, KANJI_LEVEL4, // 通 + 0x991B, KANJI_LEVEL4, // 逛 + 0x991C, KANJI_LEVEL4, // 逜 + 0xD865, KANJI_LEVEL4, // ᅵ + 0xDF50, KANJI_LEVEL4, // ᅵ + 0x9931, KANJI_LEVEL4, // 週 + 0x9932, KANJI_LEVEL4, // 進 + 0x9933, KANJI_LEVEL4, // 逳 + 0x993A, KANJI_LEVEL4, // 逺 + 0x993B, KANJI_LEVEL4, // 逻 + 0x993C, KANJI_LEVEL4, // 逌 + 0x9940, KANJI_LEVEL4, // 饀 + 0x9941, KANJI_LEVEL4, // 饁 + 0x9946, KANJI_LEVEL4, // 饆 + 0x994D, KANJI_LEVEL4, // 饍 + 0x994E, KANJI_LEVEL4, // 饎 + 0x995C, KANJI_LEVEL4, // 饜 + 0x995F, KANJI_LEVEL4, // 饟 + 0x9960, KANJI_LEVEL4, // 饠 + 0x99A3, KANJI_LEVEL4, // 銣 + 0x99A6, KANJI_LEVEL4, // 銊 + 0x99B9, KANJI_LEVEL4, // 銹 + 0x99BD, KANJI_LEVEL4, // 銜 + 0x99BF, KANJI_LEVEL4, // 銿 + 0x99C3, KANJI_LEVEL4, // 駃 + 0x99C9, KANJI_LEVEL4, // 駉 + 0x99D4, KANJI_LEVEL4, // 駔 + 0x99D9, KANJI_LEVEL4, // 駙 + 0x99DE, KANJI_LEVEL4, // 駞 + 0xD866, KANJI_LEVEL4, // ᅵ + 0xDCC6, KANJI_LEVEL4, // ᅵ + 0x99F0, KANJI_LEVEL4, // é§° + 0x99F9, KANJI_LEVEL4, // é§¹ + 0x99FC, KANJI_LEVEL4, // é§Œ + 0x9A0A, KANJI_LEVEL4, // 鹊 + 0x9A11, KANJI_LEVEL4, // 鹑 + 0x9A16, KANJI_LEVEL4, // 鹖 + 0x9A1A, KANJI_LEVEL4, // 鹚 + 0x9A20, KANJI_LEVEL4, // éš  + 0x9A31, KANJI_LEVEL4, // éš± + 0x9A36, KANJI_LEVEL4, // éš¶ + 0x9A44, KANJI_LEVEL4, // 驄 + 0x9A4C, KANJI_LEVEL4, // 驌 + 0x9A58, KANJI_LEVEL4, // 驘 + 0x4BC2, KANJI_LEVEL4, // 䯂 + 0x9AAF, KANJI_LEVEL4, // 骯 + 0x4BCA, KANJI_LEVEL4, // 䯊 + 0x9AB7, KANJI_LEVEL4, // 骷 + 0x4BD2, KANJI_LEVEL4, // 䯒 + 0x9AB9, KANJI_LEVEL4, // 骹 + 0xD866, KANJI_LEVEL4, // ᅵ + 0xDE72, KANJI_LEVEL4, // ᅵ + 0x9AC6, KANJI_LEVEL4, // 髆 + 0x9AD0, KANJI_LEVEL4, // 髐 + 0x9AD2, KANJI_LEVEL4, // 髒 + 0x9AD5, KANJI_LEVEL4, // 髕 + 0x4BE8, KANJI_LEVEL4, // 䯚 + 0x9ADC, KANJI_LEVEL4, // 髜 + 0x9AE0, KANJI_LEVEL4, // é«  + 0x9AE5, KANJI_LEVEL4, // é«¥ + 0x9AE9, KANJI_LEVEL4, // é«© + 0x9B03, KANJI_LEVEL4, // 鬃 + 0x9B0C, KANJI_LEVEL4, // 鬌 + 0x9B10, KANJI_LEVEL4, // 鬐 + 0x9B12, KANJI_LEVEL4, // 鬒 + 0x9B16, KANJI_LEVEL4, // 鬖 + 0x9B1C, KANJI_LEVEL4, // 鬜 + 0x9B2B, KANJI_LEVEL4, // 鬫 + 0x9B33, KANJI_LEVEL4, // 鬳 + 0x9B3D, KANJI_LEVEL4, // 鬜 + 0x4C20, KANJI_LEVEL4, // ä°  + 0x9B4B, KANJI_LEVEL4, // 魋 + 0x9B63, KANJI_LEVEL4, // é­£ + 0x9B65, KANJI_LEVEL4, // é­¥ + 0x9B6B, KANJI_LEVEL4, // é­« + 0x9B6C, KANJI_LEVEL4, // é­¬ + 0x9B73, KANJI_LEVEL4, // é­³ + 0x9B76, KANJI_LEVEL4, // é­¶ + 0x9B77, KANJI_LEVEL4, // é­· + 0x9BA6, KANJI_LEVEL4, // 鮊 + 0x9BAC, KANJI_LEVEL4, // 鮬 + 0x9BB1, KANJI_LEVEL4, // é®± + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDDDB, KANJI_LEVEL4, // ᅵ + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDE3D, KANJI_LEVEL4, // ᅵ + 0x9BB2, KANJI_LEVEL4, // 鮲 + 0x9BB8, KANJI_LEVEL4, // 鮞 + 0x9BBE, KANJI_LEVEL4, // 鮟 + 0x9BC7, KANJI_LEVEL4, // 鯇 + 0x9BF3, KANJI_LEVEL4, // 鯳 + 0x9BD8, KANJI_LEVEL4, // 鯘 + 0x9BDD, KANJI_LEVEL4, // 鯝 + 0x9BE7, KANJI_LEVEL4, // 鯧 + 0x9BEA, KANJI_LEVEL4, // 鯪 + 0x9BEB, KANJI_LEVEL4, // 鯫 + 0x9BEF, KANJI_LEVEL4, // 鯯 + 0x9BEE, KANJI_LEVEL4, // 鯮 + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDE15, KANJI_LEVEL4, // ᅵ + 0x9BFA, KANJI_LEVEL4, // 鯺 + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDE8A, KANJI_LEVEL4, // ᅵ + 0x9BF7, KANJI_LEVEL4, // 鯷 + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDE49, KANJI_LEVEL4, // ᅵ + 0x9C16, KANJI_LEVEL4, // 鰖 + 0x9C18, KANJI_LEVEL4, // 鰘 + 0x9C19, KANJI_LEVEL4, // 鰙 + 0x9C1A, KANJI_LEVEL4, // 鰚 + 0x9C1D, KANJI_LEVEL4, // 鰝 + 0x9C22, KANJI_LEVEL4, // é°¢ + 0x9C27, KANJI_LEVEL4, // é°§ + 0x9C29, KANJI_LEVEL4, // é°© + 0x9C2A, KANJI_LEVEL4, // é°ª + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDEC4, KANJI_LEVEL4, // ᅵ + 0x9C31, KANJI_LEVEL4, // é°± + 0x9C36, KANJI_LEVEL4, // é°¶ + 0x9C37, KANJI_LEVEL4, // é°· + 0x9C45, KANJI_LEVEL4, // 鱅 + 0x9C5C, KANJI_LEVEL4, // 鱜 + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDEE9, KANJI_LEVEL4, // ᅵ + 0x9C49, KANJI_LEVEL4, // 鱉 + 0x9C4A, KANJI_LEVEL4, // 鱊 + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDEDB, KANJI_LEVEL4, // ᅵ + 0x9C54, KANJI_LEVEL4, // 鱔 + 0x9C58, KANJI_LEVEL4, // 鱘 + 0x9C5B, KANJI_LEVEL4, // 鱛 + 0x9C5D, KANJI_LEVEL4, // 鱝 + 0x9C5F, KANJI_LEVEL4, // 鱟 + 0x9C69, KANJI_LEVEL4, // 鱩 + 0x9C6A, KANJI_LEVEL4, // 鱪 + 0x9C6B, KANJI_LEVEL4, // 鱫 + 0x9C6D, KANJI_LEVEL4, // é±­ + 0x9C6E, KANJI_LEVEL4, // é±® + 0x9C70, KANJI_LEVEL4, // é±° + 0x9C72, KANJI_LEVEL4, // é±² + 0x9C75, KANJI_LEVEL4, // é±µ + 0x9C7A, KANJI_LEVEL4, // 鱺 + 0x9CE6, KANJI_LEVEL4, // 鳊 + 0x9CF2, KANJI_LEVEL4, // é³² + 0x9D0B, KANJI_LEVEL4, // 鮋 + 0x9D02, KANJI_LEVEL4, // 鮂 + 0xD867, KANJI_LEVEL4, // ᅵ + 0xDFCE, KANJI_LEVEL4, // ᅵ + 0x9D11, KANJI_LEVEL4, // 鮑 + 0x9D17, KANJI_LEVEL4, // 鮗 + 0x9D18, KANJI_LEVEL4, // 鎘 + 0xD868, KANJI_LEVEL4, // ᅵ + 0xDC2F, KANJI_LEVEL4, // ᅵ + 0x4CC4, KANJI_LEVEL4, // 䳄 + 0xD868, KANJI_LEVEL4, // ᅵ + 0xDC1A, KANJI_LEVEL4, // ᅵ + 0x9D32, KANJI_LEVEL4, // 鎲 + 0x4CD1, KANJI_LEVEL4, // 䳑 + 0x9D42, KANJI_LEVEL4, // 鵂 + 0x9D4A, KANJI_LEVEL4, // 鵊 + 0x9D5F, KANJI_LEVEL4, // 鵟 + 0x9D62, KANJI_LEVEL4, // éµ¢ + 0xD868, KANJI_LEVEL4, // ᅵ + 0xDCF9, KANJI_LEVEL4, // ᅵ + 0x9D69, KANJI_LEVEL4, // 鵩 + 0x9D6B, KANJI_LEVEL4, // 鵫 + 0xD868, KANJI_LEVEL4, // ᅵ + 0xDC82, KANJI_LEVEL4, // ᅵ + 0x9D73, KANJI_LEVEL4, // éµ³ + 0x9D76, KANJI_LEVEL4, // éµ¶ + 0x9D77, KANJI_LEVEL4, // éµ· + 0x9D7E, KANJI_LEVEL4, // 鵟 + 0x9D84, KANJI_LEVEL4, // 鶄 + 0x9D8D, KANJI_LEVEL4, // 鶍 + 0x9D99, KANJI_LEVEL4, // 鶙 + 0x9DA1, KANJI_LEVEL4, // é¶¡ + 0x9DBF, KANJI_LEVEL4, // é¶¿ + 0x9DB5, KANJI_LEVEL4, // é¶µ + 0x9DB9, KANJI_LEVEL4, // é¶¹ + 0x9DBD, KANJI_LEVEL4, // é¶œ + 0x9DC3, KANJI_LEVEL4, // 鷃 + 0x9DC7, KANJI_LEVEL4, // 鷇 + 0x9DC9, KANJI_LEVEL4, // 鷉 + 0x9DD6, KANJI_LEVEL4, // 鷖 + 0x9DDA, KANJI_LEVEL4, // 鷚 + 0x9DDF, KANJI_LEVEL4, // 鷟 + 0x9DE0, KANJI_LEVEL4, // é·  + 0x9DE3, KANJI_LEVEL4, // é·£ + 0x9DF4, KANJI_LEVEL4, // é·Ž + 0x4D07, KANJI_LEVEL4, // 䮇 + 0x9E0A, KANJI_LEVEL4, // 龊 + 0x9E02, KANJI_LEVEL4, // 龂 + 0x9E0D, KANJI_LEVEL4, // 鞍 + 0x9E19, KANJI_LEVEL4, // 龙 + 0x9E1C, KANJI_LEVEL4, // 龜 + 0x9E1D, KANJI_LEVEL4, // 鞝 + 0x9E7B, KANJI_LEVEL4, // é¹» + 0xD848, KANJI_LEVEL4, // ᅵ + 0xDE18, KANJI_LEVEL4, // ᅵ + 0x9E80, KANJI_LEVEL4, // 麀 + 0x9E85, KANJI_LEVEL4, // 麅 + 0x9E9B, KANJI_LEVEL4, // 麛 + 0x9EA8, KANJI_LEVEL4, // 麚 + 0xD868, KANJI_LEVEL4, // ᅵ + 0xDF8C, KANJI_LEVEL4, // ᅵ + 0x9EBD, KANJI_LEVEL4, // 麜 + 0xD869, KANJI_LEVEL4, // ᅵ + 0xDC37, KANJI_LEVEL4, // ᅵ + 0x9EDF, KANJI_LEVEL4, // 黟 + 0x9EE7, KANJI_LEVEL4, // é»§ + 0x9EEE, KANJI_LEVEL4, // é»® + 0x9EFF, KANJI_LEVEL4, // 黿 + 0x9F02, KANJI_LEVEL4, // 錂 + 0x4D77, KANJI_LEVEL4, // äµ· + 0x9F03, KANJI_LEVEL4, // 錃 + 0x9F17, KANJI_LEVEL4, // 錗 + 0x9F19, KANJI_LEVEL4, // 錙 + 0x9F2F, KANJI_LEVEL4, // 錯 + 0x9F37, KANJI_LEVEL4, // 錷 + 0x9F3A, KANJI_LEVEL4, // 錺 + 0x9F3D, KANJI_LEVEL4, // 錜 + 0x9F41, KANJI_LEVEL4, // 霁 + 0x9F45, KANJI_LEVEL4, // 霅 + 0x9F46, KANJI_LEVEL4, // 霆 + 0x9F53, KANJI_LEVEL4, // 霓 + 0x9F55, KANJI_LEVEL4, // 霕 + 0x9F58, KANJI_LEVEL4, // 霘 + 0xD869, KANJI_LEVEL4, // ᅵ + 0xDDF1, KANJI_LEVEL4, // ᅵ + 0x9F5D, KANJI_LEVEL4, // 霝 + 0xD869, KANJI_LEVEL4, // ᅵ + 0xDE02, KANJI_LEVEL4, // ᅵ + 0x9F69, KANJI_LEVEL4, // 霩 + 0xD869, KANJI_LEVEL4, // ᅵ + 0xDE1A, KANJI_LEVEL4, // ᅵ + 0x9F6D, KANJI_LEVEL4, // 霭 + 0x9F70, KANJI_LEVEL4, // 霰 + 0x9F75, KANJI_LEVEL4, // 霵 + 0xD869, KANJI_LEVEL4, // ᅵ + 0xDEB2, KANJI_LEVEL4, // ᅵ + 0x4E9C, KANJI_SJIS_L1, // 亜 + 0x5516, KANJI_SJIS_L1, // 唖 + 0x5A03, KANJI_SJIS_L1, // 嚃 + 0x963F, KANJI_SJIS_L1, // 阿 + 0x54C0, KANJI_SJIS_L1, // 哀 + 0x611B, KANJI_SJIS_L1, // 愛 + 0x6328, KANJI_SJIS_L1, // 挚 + 0x59F6, KANJI_SJIS_L1, // å§¶ + 0x9022, KANJI_SJIS_L1, // 逢 + 0x8475, KANJI_SJIS_L1, // 葵 + 0x831C, KANJI_SJIS_L1, // 茜 + 0x7A50, KANJI_SJIS_L1, // 穐 + 0x60AA, KANJI_SJIS_L1, // 悪 + 0x63E1, KANJI_SJIS_L1, // 握 + 0x6E25, KANJI_SJIS_L1, // 枥 + 0x65ED, KANJI_SJIS_L1, // 旭 + 0x8466, KANJI_SJIS_L1, // 葊 + 0x82A6, KANJI_SJIS_L1, // 芊 + 0x9BF5, KANJI_SJIS_L1, // 鯵 + 0x6893, KANJI_SJIS_L1, // 梓 + 0x5727, KANJI_SJIS_L1, // 圧 + 0x65A1, KANJI_SJIS_L1, // 斡 + 0x6271, KANJI_SJIS_L1, // 扱 + 0x5B9B, KANJI_SJIS_L1, // 宛 + 0x59D0, KANJI_SJIS_L1, // 姐 + 0x867B, KANJI_SJIS_L1, // 虻 + 0x98F4, KANJI_SJIS_L1, // 风 + 0x7D62, KANJI_SJIS_L1, // çµ¢ + 0x7DBE, KANJI_SJIS_L1, // ç¶Ÿ + 0x9B8E, KANJI_SJIS_L1, // 鮎 + 0x6216, KANJI_SJIS_L1, // 或 + 0x7C9F, KANJI_SJIS_L1, // 粟 + 0x88B7, KANJI_SJIS_L1, // 袷 + 0x5B89, KANJI_SJIS_L1, // 安 + 0x5EB5, KANJI_SJIS_L1, // 庵 + 0x6309, KANJI_SJIS_L1, // 按 + 0x6697, KANJI_SJIS_L1, // 暗 + 0x6848, KANJI_SJIS_L1, // 案 + 0x95C7, KANJI_SJIS_L1, // 闇 + 0x978D, KANJI_SJIS_L1, // 鞍 + 0x674F, KANJI_SJIS_L1, // 杏 + 0x4EE5, KANJI_SJIS_L1, // 以 + 0x4F0A, KANJI_SJIS_L1, // 䌊 + 0x4F4D, KANJI_SJIS_L1, // 䜍 + 0x4F9D, KANJI_SJIS_L1, // 䟝 + 0x5049, KANJI_SJIS_L1, // 偉 + 0x56F2, KANJI_SJIS_L1, // 囲 + 0x5937, KANJI_SJIS_L1, // 倷 + 0x59D4, KANJI_SJIS_L1, // 委 + 0x5A01, KANJI_SJIS_L1, // 嚁 + 0x5C09, KANJI_SJIS_L1, // 尉 + 0x60DF, KANJI_SJIS_L1, // 惟 + 0x610F, KANJI_SJIS_L1, // 意 + 0x6170, KANJI_SJIS_L1, // 慰 + 0x6613, KANJI_SJIS_L1, // 易 + 0x6905, KANJI_SJIS_L1, // 怅 + 0x70BA, KANJI_SJIS_L1, // 為 + 0x754F, KANJI_SJIS_L1, // 畏 + 0x7570, KANJI_SJIS_L1, // 異 + 0x79FB, KANJI_SJIS_L1, // ç§» + 0x7DAD, KANJI_SJIS_L1, // ç¶­ + 0x7DEF, KANJI_SJIS_L1, // ç·¯ + 0x80C3, KANJI_SJIS_L1, // 胃 + 0x840E, KANJI_SJIS_L1, // 萎 + 0x8863, KANJI_SJIS_L1, // è¡£ + 0x8B02, KANJI_SJIS_L1, // 謂 + 0x9055, KANJI_SJIS_L1, // 違 + 0x907A, KANJI_SJIS_L1, // 遺 + 0x533B, KANJI_SJIS_L1, // 医 + 0x4E95, KANJI_SJIS_L1, // 井 + 0x4EA5, KANJI_SJIS_L1, // 亥 + 0x57DF, KANJI_SJIS_L1, // 域 + 0x80B2, KANJI_SJIS_L1, // 育 + 0x90C1, KANJI_SJIS_L1, // 郁 + 0x78EF, KANJI_SJIS_L1, // 磯 + 0x4E00, KANJI_SJIS_L1, // 侀 + 0x58F1, KANJI_SJIS_L1, // 壱 + 0x6EA2, KANJI_SJIS_L1, // 溢 + 0x9038, KANJI_SJIS_L1, // 逾 + 0x7A32, KANJI_SJIS_L1, // çš² + 0x8328, KANJI_SJIS_L1, // 茚 + 0x828B, KANJI_SJIS_L1, // 芋 + 0x9C2F, KANJI_SJIS_L1, // é°¯ + 0x5141, KANJI_SJIS_L1, // 允 + 0x5370, KANJI_SJIS_L1, // 印 + 0x54BD, KANJI_SJIS_L1, // å’œ + 0x54E1, KANJI_SJIS_L1, // 員 + 0x56E0, KANJI_SJIS_L1, // 因 + 0x59FB, KANJI_SJIS_L1, // å§» + 0x5F15, KANJI_SJIS_L1, // 匕 + 0x98F2, KANJI_SJIS_L1, // 飲 + 0x6DEB, KANJI_SJIS_L1, // æ·« + 0x80E4, KANJI_SJIS_L1, // 胀 + 0x852D, KANJI_SJIS_L1, // 蔭 + 0x9662, KANJI_SJIS_L1, // 院 + 0x9670, KANJI_SJIS_L1, // 陰 + 0x96A0, KANJI_SJIS_L1, // 隠 + 0x97FB, KANJI_SJIS_L1, // 韻 + 0x540B, KANJI_SJIS_L1, // 吋 + 0x53F3, KANJI_SJIS_L1, // 右 + 0x5B87, KANJI_SJIS_L1, // 宇 + 0x70CF, KANJI_SJIS_L1, // 烏 + 0x7FBD, KANJI_SJIS_L1, // 矜 + 0x8FC2, KANJI_SJIS_L1, // 迂 + 0x96E8, KANJI_SJIS_L1, // 雹 + 0x536F, KANJI_SJIS_L1, // 卯 + 0x9D5C, KANJI_SJIS_L1, // 鵜 + 0x7ABA, KANJI_SJIS_L1, // 窺 + 0x4E11, KANJI_SJIS_L1, // 侑 + 0x7893, KANJI_SJIS_L1, // 碓 + 0x81FC, KANJI_SJIS_L1, // 臌 + 0x6E26, KANJI_SJIS_L1, // 枊 + 0x5618, KANJI_SJIS_L1, // 嘘 + 0x5504, KANJI_SJIS_L1, // 唄 + 0x6B1D, KANJI_SJIS_L1, // 欝 + 0x851A, KANJI_SJIS_L1, // 蔚 + 0x9C3B, KANJI_SJIS_L1, // é°» + 0x59E5, KANJI_SJIS_L1, // å§¥ + 0x53A9, KANJI_SJIS_L1, // 厩 + 0x6D66, KANJI_SJIS_L1, // 浊 + 0x74DC, KANJI_SJIS_L1, // 瓜 + 0x958F, KANJI_SJIS_L1, // 閏 + 0x5642, KANJI_SJIS_L1, // 噂 + 0x4E91, KANJI_SJIS_L1, // 云 + 0x904B, KANJI_SJIS_L1, // 運 + 0x96F2, KANJI_SJIS_L1, // 雲 + 0x834F, KANJI_SJIS_L1, // 荏 + 0x990C, KANJI_SJIS_L1, // 逌 + 0x53E1, KANJI_SJIS_L1, // 叡 + 0x55B6, KANJI_SJIS_L1, // 営 + 0x5B30, KANJI_SJIS_L1, // 嬰 + 0x5F71, KANJI_SJIS_L1, // 圱 + 0x6620, KANJI_SJIS_L1, // 映 + 0x66F3, KANJI_SJIS_L1, // 曳 + 0x6804, KANJI_SJIS_L1, // 栄 + 0x6C38, KANJI_SJIS_L1, // æ°ž + 0x6CF3, KANJI_SJIS_L1, // æ³³ + 0x6D29, KANJI_SJIS_L1, // 掩 + 0x745B, KANJI_SJIS_L1, // 瑛 + 0x76C8, KANJI_SJIS_L1, // 盈 + 0x7A4E, KANJI_SJIS_L1, // 穎 + 0x9834, KANJI_SJIS_L1, // é Ž + 0x82F1, KANJI_SJIS_L1, // 英 + 0x885B, KANJI_SJIS_L1, // 衛 + 0x8A60, KANJI_SJIS_L1, // è©  + 0x92ED, KANJI_SJIS_L1, // 鋭 + 0x6DB2, KANJI_SJIS_L1, // æ¶² + 0x75AB, KANJI_SJIS_L1, // 疫 + 0x76CA, KANJI_SJIS_L1, // 益 + 0x99C5, KANJI_SJIS_L1, // 駅 + 0x60A6, KANJI_SJIS_L1, // 悊 + 0x8B01, KANJI_SJIS_L1, // 謁 + 0x8D8A, KANJI_SJIS_L1, // 越 + 0x95B2, KANJI_SJIS_L1, // 閲 + 0x698E, KANJI_SJIS_L1, // 抎 + 0x53AD, KANJI_SJIS_L1, // 厭 + 0x5186, KANJI_SJIS_L1, // 円 + 0x3000, KANJI_SJIS_L1, //   + 0x5712, KANJI_SJIS_L1, // 園 + 0x5830, KANJI_SJIS_L1, // å ° + 0x5944, KANJI_SJIS_L1, // 奄 + 0x5BB4, KANJI_SJIS_L1, // 宎 + 0x5EF6, KANJI_SJIS_L1, // å»¶ + 0x6028, KANJI_SJIS_L1, // 怚 + 0x63A9, KANJI_SJIS_L1, // 掩 + 0x63F4, KANJI_SJIS_L1, // 揎 + 0x6CBF, KANJI_SJIS_L1, // 沿 + 0x6F14, KANJI_SJIS_L1, // 挔 + 0x708E, KANJI_SJIS_L1, // 炎 + 0x7114, KANJI_SJIS_L1, // 焔 + 0x7159, KANJI_SJIS_L1, // 煙 + 0x71D5, KANJI_SJIS_L1, // 燕 + 0x733F, KANJI_SJIS_L1, // 猿 + 0x7E01, KANJI_SJIS_L1, // 瞁 + 0x8276, KANJI_SJIS_L1, // 艶 + 0x82D1, KANJI_SJIS_L1, // 苑 + 0x8597, KANJI_SJIS_L1, // 薗 + 0x9060, KANJI_SJIS_L1, // 遠 + 0x925B, KANJI_SJIS_L1, // 鉛 + 0x9D1B, KANJI_SJIS_L1, // 鮛 + 0x5869, KANJI_SJIS_L1, // å¡© + 0x65BC, KANJI_SJIS_L1, // æ–Œ + 0x6C5A, KANJI_SJIS_L1, // 汚 + 0x7525, KANJI_SJIS_L1, // 甥 + 0x51F9, KANJI_SJIS_L1, // 凹 + 0x592E, KANJI_SJIS_L1, // 倮 + 0x5965, KANJI_SJIS_L1, // 奥 + 0x5F80, KANJI_SJIS_L1, // 埀 + 0x5FDC, KANJI_SJIS_L1, // 応 + 0x62BC, KANJI_SJIS_L1, // 抌 + 0x65FA, KANJI_SJIS_L1, // 旺 + 0x6A2A, KANJI_SJIS_L1, // 暪 + 0x6B27, KANJI_SJIS_L1, // 欧 + 0x6BB4, KANJI_SJIS_L1, // 殎 + 0x738B, KANJI_SJIS_L1, // 王 + 0x7FC1, KANJI_SJIS_L1, // 翁 + 0x8956, KANJI_SJIS_L1, // 襖 + 0x9D2C, KANJI_SJIS_L1, // 鎬 + 0x9D0E, KANJI_SJIS_L1, // 鮎 + 0x9EC4, KANJI_SJIS_L1, // 黄 + 0x5CA1, KANJI_SJIS_L1, // 岡 + 0x6C96, KANJI_SJIS_L1, // 沖 + 0x837B, KANJI_SJIS_L1, // 荻 + 0x5104, KANJI_SJIS_L1, // 億 + 0x5C4B, KANJI_SJIS_L1, // 屋 + 0x61B6, KANJI_SJIS_L1, // 憶 + 0x81C6, KANJI_SJIS_L1, // 臆 + 0x6876, KANJI_SJIS_L1, // æ¡¶ + 0x7261, KANJI_SJIS_L1, // 牡 + 0x4E59, KANJI_SJIS_L1, // 乙 + 0x4FFA, KANJI_SJIS_L1, // 俺 + 0x5378, KANJI_SJIS_L1, // 卞 + 0x6069, KANJI_SJIS_L1, // 恩 + 0x6E29, KANJI_SJIS_L1, // æž© + 0x7A4F, KANJI_SJIS_L1, // 穏 + 0x97F3, KANJI_SJIS_L1, // 音 + 0x4E0B, KANJI_SJIS_L1, // 例 + 0x5316, KANJI_SJIS_L1, // 化 + 0x4EEE, KANJI_SJIS_L1, // ä»® + 0x4F55, KANJI_SJIS_L1, // 䜕 + 0x4F3D, KANJI_SJIS_L1, // 䌜 + 0x4FA1, KANJI_SJIS_L1, // 䟡 + 0x4F73, KANJI_SJIS_L1, // 䜳 + 0x52A0, KANJI_SJIS_L1, // 加 + 0x53EF, KANJI_SJIS_L1, // 可 + 0x5609, KANJI_SJIS_L1, // 嘉 + 0x590F, KANJI_SJIS_L1, // 倏 + 0x5AC1, KANJI_SJIS_L1, // 嫁 + 0x5BB6, KANJI_SJIS_L1, // å®¶ + 0x5BE1, KANJI_SJIS_L1, // 寡 + 0x79D1, KANJI_SJIS_L1, // 科 + 0x6687, KANJI_SJIS_L1, // 暇 + 0x679C, KANJI_SJIS_L1, // 果 + 0x67B6, KANJI_SJIS_L1, // 架 + 0x6B4C, KANJI_SJIS_L1, // 歌 + 0x6CB3, KANJI_SJIS_L1, // æ²³ + 0x706B, KANJI_SJIS_L1, // 火 + 0x73C2, KANJI_SJIS_L1, // 珂 + 0x798D, KANJI_SJIS_L1, // 犍 + 0x79BE, KANJI_SJIS_L1, // 犟 + 0x7A3C, KANJI_SJIS_L1, // 皌 + 0x7B87, KANJI_SJIS_L1, // 箇 + 0x82B1, KANJI_SJIS_L1, // 花 + 0x82DB, KANJI_SJIS_L1, // 苛 + 0x8304, KANJI_SJIS_L1, // 茄 + 0x8377, KANJI_SJIS_L1, // 荷 + 0x83EF, KANJI_SJIS_L1, // 華 + 0x83D3, KANJI_SJIS_L1, // 菓 + 0x8766, KANJI_SJIS_L1, // 蝊 + 0x8AB2, KANJI_SJIS_L1, // 課 + 0x5629, KANJI_SJIS_L1, // 嘩 + 0x8CA8, KANJI_SJIS_L1, // 貚 + 0x8FE6, KANJI_SJIS_L1, // 迊 + 0x904E, KANJI_SJIS_L1, // 過 + 0x971E, KANJI_SJIS_L1, // 霞 + 0x868A, KANJI_SJIS_L1, // 蚊 + 0x4FC4, KANJI_SJIS_L1, // 俄 + 0x5CE8, KANJI_SJIS_L1, // 峚 + 0x6211, KANJI_SJIS_L1, // 我 + 0x7259, KANJI_SJIS_L1, // 牙 + 0x753B, KANJI_SJIS_L1, // 画 + 0x81E5, KANJI_SJIS_L1, // 臥 + 0x82BD, KANJI_SJIS_L1, // 芜 + 0x86FE, KANJI_SJIS_L1, // 蛟 + 0x8CC0, KANJI_SJIS_L1, // 賀 + 0x96C5, KANJI_SJIS_L1, // 雅 + 0x9913, KANJI_SJIS_L1, // 逓 + 0x99D5, KANJI_SJIS_L1, // 駕 + 0x4ECB, KANJI_SJIS_L1, // 介 + 0x4F1A, KANJI_SJIS_L1, // 䌚 + 0x89E3, KANJI_SJIS_L1, // è§£ + 0x56DE, KANJI_SJIS_L1, // 回 + 0x584A, KANJI_SJIS_L1, // 塊 + 0x58CA, KANJI_SJIS_L1, // 壊 + 0x5EFB, KANJI_SJIS_L1, // å»» + 0x5FEB, KANJI_SJIS_L1, // å¿« + 0x602A, KANJI_SJIS_L1, // 怪 + 0x6094, KANJI_SJIS_L1, // 悔 + 0x6062, KANJI_SJIS_L1, // 恢 + 0x61D0, KANJI_SJIS_L1, // 懐 + 0x6212, KANJI_SJIS_L1, // 戒 + 0x62D0, KANJI_SJIS_L1, // 拐 + 0x6539, KANJI_SJIS_L1, // 改 + 0x9B41, KANJI_SJIS_L1, // 魁 + 0x6666, KANJI_SJIS_L1, // 晊 + 0x68B0, KANJI_SJIS_L1, // 械 + 0x6D77, KANJI_SJIS_L1, // æµ· + 0x7070, KANJI_SJIS_L1, // 灰 + 0x754C, KANJI_SJIS_L1, // 界 + 0x7686, KANJI_SJIS_L1, // 皆 + 0x7D75, KANJI_SJIS_L1, // çµµ + 0x82A5, KANJI_SJIS_L1, // 芥 + 0x87F9, KANJI_SJIS_L1, // 蟹 + 0x958B, KANJI_SJIS_L1, // 開 + 0x968E, KANJI_SJIS_L1, // 階 + 0x8C9D, KANJI_SJIS_L1, // 貝 + 0x51F1, KANJI_SJIS_L1, // 凱 + 0x52BE, KANJI_SJIS_L1, // 功 + 0x5916, KANJI_SJIS_L1, // 倖 + 0x54B3, KANJI_SJIS_L1, // 咳 + 0x5BB3, KANJI_SJIS_L1, // 害 + 0x5D16, KANJI_SJIS_L1, // 厖 + 0x6168, KANJI_SJIS_L1, // æ…š + 0x6982, KANJI_SJIS_L1, // 抂 + 0x6DAF, KANJI_SJIS_L1, // 涯 + 0x788D, KANJI_SJIS_L1, // 碍 + 0x84CB, KANJI_SJIS_L1, // 蓋 + 0x8857, KANJI_SJIS_L1, // 街 + 0x8A72, KANJI_SJIS_L1, // 該 + 0x93A7, KANJI_SJIS_L1, // 鎧 + 0x9AB8, KANJI_SJIS_L1, // 骞 + 0x6D6C, KANJI_SJIS_L1, // 浬 + 0x99A8, KANJI_SJIS_L1, // 銚 + 0x86D9, KANJI_SJIS_L1, // 蛙 + 0x57A3, KANJI_SJIS_L1, // 垣 + 0x67FF, KANJI_SJIS_L1, // 柿 + 0x86CE, KANJI_SJIS_L1, // 蛎 + 0x920E, KANJI_SJIS_L1, // 鈎 + 0x5283, KANJI_SJIS_L1, // 劃 + 0x5687, KANJI_SJIS_L1, // 嚇 + 0x5404, KANJI_SJIS_L1, // 各 + 0x5ED3, KANJI_SJIS_L1, // 廓 + 0x62E1, KANJI_SJIS_L1, // 拡 + 0x64B9, KANJI_SJIS_L1, // 撹 + 0x683C, KANJI_SJIS_L1, // æ Œ + 0x6838, KANJI_SJIS_L1, // æ ž + 0x6BBB, KANJI_SJIS_L1, // æ®» + 0x7372, KANJI_SJIS_L1, // 獲 + 0x78BA, KANJI_SJIS_L1, // 確 + 0x7A6B, KANJI_SJIS_L1, // ç©« + 0x899A, KANJI_SJIS_L1, // 芚 + 0x89D2, KANJI_SJIS_L1, // 角 + 0x8D6B, KANJI_SJIS_L1, // 赫 + 0x8F03, KANJI_SJIS_L1, // 范 + 0x90ED, KANJI_SJIS_L1, // 郭 + 0x95A3, KANJI_SJIS_L1, // 閣 + 0x9694, KANJI_SJIS_L1, // 隔 + 0x9769, KANJI_SJIS_L1, // 革 + 0x5B66, KANJI_SJIS_L1, // å­Š + 0x5CB3, KANJI_SJIS_L1, // å²³ + 0x697D, KANJI_SJIS_L1, // 楜 + 0x984D, KANJI_SJIS_L1, // 額 + 0x984E, KANJI_SJIS_L1, // 顎 + 0x639B, KANJI_SJIS_L1, // 掛 + 0x7B20, KANJI_SJIS_L1, // 笠 + 0x6A2B, KANJI_SJIS_L1, // æš« + 0x3000, KANJI_SJIS_L1, //   + 0x6A7F, KANJI_SJIS_L1, // æ©¿ + 0x68B6, KANJI_SJIS_L1, // 梶 + 0x9C0D, KANJI_SJIS_L1, // 鰍 + 0x6F5F, KANJI_SJIS_L1, // 期 + 0x5272, KANJI_SJIS_L1, // 割 + 0x559D, KANJI_SJIS_L1, // 喝 + 0x6070, KANJI_SJIS_L1, // 恰 + 0x62EC, KANJI_SJIS_L1, // 括 + 0x6D3B, KANJI_SJIS_L1, // 掻 + 0x6E07, KANJI_SJIS_L1, // 枇 + 0x6ED1, KANJI_SJIS_L1, // 滑 + 0x845B, KANJI_SJIS_L1, // 葛 + 0x8910, KANJI_SJIS_L1, // 耐 + 0x8F44, KANJI_SJIS_L1, // 蜄 + 0x4E14, KANJI_SJIS_L1, // 侔 + 0x9C39, KANJI_SJIS_L1, // é°¹ + 0x53F6, KANJI_SJIS_L1, // 叶 + 0x691B, KANJI_SJIS_L1, // 怛 + 0x6A3A, KANJI_SJIS_L1, // 暺 + 0x9784, KANJI_SJIS_L1, // 鞄 + 0x682A, KANJI_SJIS_L1, // æ ª + 0x515C, KANJI_SJIS_L1, // 兜 + 0x7AC3, KANJI_SJIS_L1, // 竃 + 0x84B2, KANJI_SJIS_L1, // 蒲 + 0x91DC, KANJI_SJIS_L1, // 釜 + 0x938C, KANJI_SJIS_L1, // 鎌 + 0x565B, KANJI_SJIS_L1, // 噛 + 0x9D28, KANJI_SJIS_L1, // 鎚 + 0x6822, KANJI_SJIS_L1, // æ ¢ + 0x8305, KANJI_SJIS_L1, // 茅 + 0x8431, KANJI_SJIS_L1, // 萱 + 0x7CA5, KANJI_SJIS_L1, // ç²¥ + 0x5208, KANJI_SJIS_L1, // 刈 + 0x82C5, KANJI_SJIS_L1, // 苅 + 0x74E6, KANJI_SJIS_L1, // 瓩 + 0x4E7E, KANJI_SJIS_L1, // 也 + 0x4F83, KANJI_SJIS_L1, // 䟃 + 0x51A0, KANJI_SJIS_L1, // 冠 + 0x5BD2, KANJI_SJIS_L1, // 寒 + 0x520A, KANJI_SJIS_L1, // 刊 + 0x52D8, KANJI_SJIS_L1, // 勘 + 0x52E7, KANJI_SJIS_L1, // 勧 + 0x5DFB, KANJI_SJIS_L1, // å·» + 0x559A, KANJI_SJIS_L1, // 喚 + 0x582A, KANJI_SJIS_L1, // å ª + 0x59E6, KANJI_SJIS_L1, // å§Š + 0x5B8C, KANJI_SJIS_L1, // 完 + 0x5B98, KANJI_SJIS_L1, // 官 + 0x5BDB, KANJI_SJIS_L1, // 寛 + 0x5E72, KANJI_SJIS_L1, // å¹² + 0x5E79, KANJI_SJIS_L1, // å¹¹ + 0x60A3, KANJI_SJIS_L1, // 患 + 0x611F, KANJI_SJIS_L1, // 感 + 0x6163, KANJI_SJIS_L1, // 慣 + 0x61BE, KANJI_SJIS_L1, // 憟 + 0x63DB, KANJI_SJIS_L1, // 換 + 0x6562, KANJI_SJIS_L1, // 敢 + 0x67D1, KANJI_SJIS_L1, // 柑 + 0x6853, KANJI_SJIS_L1, // 桓 + 0x68FA, KANJI_SJIS_L1, // 棺 + 0x6B3E, KANJI_SJIS_L1, // 欟 + 0x6B53, KANJI_SJIS_L1, // 歓 + 0x6C57, KANJI_SJIS_L1, // 汗 + 0x6F22, KANJI_SJIS_L1, // 挢 + 0x6F97, KANJI_SJIS_L1, // 柗 + 0x6F45, KANJI_SJIS_L1, // 朅 + 0x74B0, KANJI_SJIS_L1, // 環 + 0x7518, KANJI_SJIS_L1, // 甘 + 0x76E3, KANJI_SJIS_L1, // 監 + 0x770B, KANJI_SJIS_L1, // 看 + 0x7AFF, KANJI_SJIS_L1, // ç«¿ + 0x7BA1, KANJI_SJIS_L1, // 管 + 0x7C21, KANJI_SJIS_L1, // ç°¡ + 0x7DE9, KANJI_SJIS_L1, // ç·© + 0x7F36, KANJI_SJIS_L1, // 猶 + 0x7FF0, KANJI_SJIS_L1, // ç¿° + 0x809D, KANJI_SJIS_L1, // 肝 + 0x8266, KANJI_SJIS_L1, // 艊 + 0x839E, KANJI_SJIS_L1, // 莞 + 0x89B3, KANJI_SJIS_L1, // 芳 + 0x8ACC, KANJI_SJIS_L1, // 諌 + 0x8CAB, KANJI_SJIS_L1, // 貫 + 0x9084, KANJI_SJIS_L1, // 還 + 0x9451, KANJI_SJIS_L1, // 鑑 + 0x9593, KANJI_SJIS_L1, // 間 + 0x9591, KANJI_SJIS_L1, // 閑 + 0x95A2, KANJI_SJIS_L1, // 関 + 0x9665, KANJI_SJIS_L1, // 陥 + 0x97D3, KANJI_SJIS_L1, // 韓 + 0x9928, KANJI_SJIS_L1, // 通 + 0x8218, KANJI_SJIS_L1, // 舘 + 0x4E38, KANJI_SJIS_L1, // äžž + 0x542B, KANJI_SJIS_L1, // 含 + 0x5CB8, KANJI_SJIS_L1, // 岞 + 0x5DCC, KANJI_SJIS_L1, // 巌 + 0x73A9, KANJI_SJIS_L1, // 玩 + 0x764C, KANJI_SJIS_L1, // 癌 + 0x773C, KANJI_SJIS_L1, // 県 + 0x5CA9, KANJI_SJIS_L1, // 岩 + 0x7FEB, KANJI_SJIS_L1, // ç¿« + 0x8D0B, KANJI_SJIS_L1, // 莋 + 0x96C1, KANJI_SJIS_L1, // 雁 + 0x9811, KANJI_SJIS_L1, // 頑 + 0x9854, KANJI_SJIS_L1, // 顔 + 0x9858, KANJI_SJIS_L1, // 願 + 0x4F01, KANJI_SJIS_L1, // 䌁 + 0x4F0E, KANJI_SJIS_L1, // 䌎 + 0x5371, KANJI_SJIS_L1, // 危 + 0x559C, KANJI_SJIS_L1, // 喜 + 0x5668, KANJI_SJIS_L1, // 噚 + 0x57FA, KANJI_SJIS_L1, // 基 + 0x5947, KANJI_SJIS_L1, // 奇 + 0x5B09, KANJI_SJIS_L1, // 嬉 + 0x5BC4, KANJI_SJIS_L1, // 寄 + 0x5C90, KANJI_SJIS_L1, // 岐 + 0x5E0C, KANJI_SJIS_L1, // 垌 + 0x5E7E, KANJI_SJIS_L1, // 幟 + 0x5FCC, KANJI_SJIS_L1, // 忌 + 0x63EE, KANJI_SJIS_L1, // 揮 + 0x673A, KANJI_SJIS_L1, // 机 + 0x65D7, KANJI_SJIS_L1, // 旗 + 0x65E2, KANJI_SJIS_L1, // 既 + 0x671F, KANJI_SJIS_L1, // 期 + 0x68CB, KANJI_SJIS_L1, // 棋 + 0x68C4, KANJI_SJIS_L1, // 棄 + 0x6A5F, KANJI_SJIS_L1, // 機 + 0x5E30, KANJI_SJIS_L1, // åž° + 0x6BC5, KANJI_SJIS_L1, // 毅 + 0x6C17, KANJI_SJIS_L1, // 気 + 0x6C7D, KANJI_SJIS_L1, // 汜 + 0x757F, KANJI_SJIS_L1, // 畿 + 0x7948, KANJI_SJIS_L1, // 祈 + 0x5B63, KANJI_SJIS_L1, // å­£ + 0x7A00, KANJI_SJIS_L1, // 繀 + 0x7D00, KANJI_SJIS_L1, // 简 + 0x5FBD, KANJI_SJIS_L1, // 埜 + 0x898F, KANJI_SJIS_L1, // 芏 + 0x8A18, KANJI_SJIS_L1, // 蚘 + 0x8CB4, KANJI_SJIS_L1, // 貎 + 0x8D77, KANJI_SJIS_L1, // èµ· + 0x8ECC, KANJI_SJIS_L1, // 軌 + 0x8F1D, KANJI_SJIS_L1, // 茝 + 0x98E2, KANJI_SJIS_L1, // 飢 + 0x9A0E, KANJI_SJIS_L1, // 階 + 0x9B3C, KANJI_SJIS_L1, // 鬌 + 0x4E80, KANJI_SJIS_L1, // 亀 + 0x507D, KANJI_SJIS_L1, // 停 + 0x5100, KANJI_SJIS_L1, // 儀 + 0x5993, KANJI_SJIS_L1, // 劓 + 0x5B9C, KANJI_SJIS_L1, // 宜 + 0x622F, KANJI_SJIS_L1, // 戯 + 0x6280, KANJI_SJIS_L1, // 技 + 0x64EC, KANJI_SJIS_L1, // 擬 + 0x6B3A, KANJI_SJIS_L1, // 欺 + 0x72A0, KANJI_SJIS_L1, // 犠 + 0x7591, KANJI_SJIS_L1, // 疑 + 0x7947, KANJI_SJIS_L1, // 祇 + 0x7FA9, KANJI_SJIS_L1, // 矩 + 0x87FB, KANJI_SJIS_L1, // 蟻 + 0x8ABC, KANJI_SJIS_L1, // 誌 + 0x8B70, KANJI_SJIS_L1, // è­° + 0x63AC, KANJI_SJIS_L1, // 掬 + 0x83CA, KANJI_SJIS_L1, // 菊 + 0x97A0, KANJI_SJIS_L1, // 鞠 + 0x5409, KANJI_SJIS_L1, // 吉 + 0x5403, KANJI_SJIS_L1, // 吃 + 0x55AB, KANJI_SJIS_L1, // 喫 + 0x6854, KANJI_SJIS_L1, // 桔 + 0x6A58, KANJI_SJIS_L1, // 橘 + 0x8A70, KANJI_SJIS_L1, // è©° + 0x7827, KANJI_SJIS_L1, // ç § + 0x6775, KANJI_SJIS_L1, // 杵 + 0x9ECD, KANJI_SJIS_L1, // 黍 + 0x5374, KANJI_SJIS_L1, // 华 + 0x5BA2, KANJI_SJIS_L1, // 客 + 0x811A, KANJI_SJIS_L1, // 脚 + 0x8650, KANJI_SJIS_L1, // 虐 + 0x9006, KANJI_SJIS_L1, // 逆 + 0x4E18, KANJI_SJIS_L1, // 䞘 + 0x4E45, KANJI_SJIS_L1, // 久 + 0x4EC7, KANJI_SJIS_L1, // 仇 + 0x4F11, KANJI_SJIS_L1, // 䌑 + 0x53CA, KANJI_SJIS_L1, // 及 + 0x5438, KANJI_SJIS_L1, // 吞 + 0x5BAE, KANJI_SJIS_L1, // å®® + 0x5F13, KANJI_SJIS_L1, // 匓 + 0x6025, KANJI_SJIS_L1, // 急 + 0x6551, KANJI_SJIS_L1, // 救 + 0x3000, KANJI_SJIS_L1, //   + 0x673D, KANJI_SJIS_L1, // 朜 + 0x6C42, KANJI_SJIS_L1, // 求 + 0x6C72, KANJI_SJIS_L1, // æ±² + 0x6CE3, KANJI_SJIS_L1, // æ³£ + 0x7078, KANJI_SJIS_L1, // 灞 + 0x7403, KANJI_SJIS_L1, // 球 + 0x7A76, KANJI_SJIS_L1, // ç©¶ + 0x7AAE, KANJI_SJIS_L1, // 窮 + 0x7B08, KANJI_SJIS_L1, // 笈 + 0x7D1A, KANJI_SJIS_L1, // 箚 + 0x7CFE, KANJI_SJIS_L1, // 糟 + 0x7D66, KANJI_SJIS_L1, // 絊 + 0x65E7, KANJI_SJIS_L1, // 旧 + 0x725B, KANJI_SJIS_L1, // 牛 + 0x53BB, KANJI_SJIS_L1, // 去 + 0x5C45, KANJI_SJIS_L1, // 居 + 0x5DE8, KANJI_SJIS_L1, // å·š + 0x62D2, KANJI_SJIS_L1, // 拒 + 0x62E0, KANJI_SJIS_L1, // 拠 + 0x6319, KANJI_SJIS_L1, // 挙 + 0x6E20, KANJI_SJIS_L1, // æž  + 0x865A, KANJI_SJIS_L1, // 虚 + 0x8A31, KANJI_SJIS_L1, // èš± + 0x8DDD, KANJI_SJIS_L1, // 距 + 0x92F8, KANJI_SJIS_L1, // 鋾 + 0x6F01, KANJI_SJIS_L1, // 持 + 0x79A6, KANJI_SJIS_L1, // 犊 + 0x9B5A, KANJI_SJIS_L1, // 魚 + 0x4EA8, KANJI_SJIS_L1, // 亚 + 0x4EAB, KANJI_SJIS_L1, // 享 + 0x4EAC, KANJI_SJIS_L1, // 京 + 0x4F9B, KANJI_SJIS_L1, // 䟛 + 0x4FA0, KANJI_SJIS_L1, // 䟠 + 0x50D1, KANJI_SJIS_L1, // 僑 + 0x5147, KANJI_SJIS_L1, // 兇 + 0x7AF6, KANJI_SJIS_L1, // ç«¶ + 0x5171, KANJI_SJIS_L1, // 共 + 0x51F6, KANJI_SJIS_L1, // 凶 + 0x5354, KANJI_SJIS_L1, // 協 + 0x5321, KANJI_SJIS_L1, // 匡 + 0x537F, KANJI_SJIS_L1, // 卿 + 0x53EB, KANJI_SJIS_L1, // 叫 + 0x55AC, KANJI_SJIS_L1, // 喬 + 0x5883, KANJI_SJIS_L1, // 境 + 0x5CE1, KANJI_SJIS_L1, // 峡 + 0x5F37, KANJI_SJIS_L1, // 匷 + 0x5F4A, KANJI_SJIS_L1, // 圊 + 0x602F, KANJI_SJIS_L1, // 怯 + 0x6050, KANJI_SJIS_L1, // 恐 + 0x606D, KANJI_SJIS_L1, // 恭 + 0x631F, KANJI_SJIS_L1, // 挟 + 0x6559, KANJI_SJIS_L1, // 教 + 0x6A4B, KANJI_SJIS_L1, // 橋 + 0x6CC1, KANJI_SJIS_L1, // 況 + 0x72C2, KANJI_SJIS_L1, // 狂 + 0x72ED, KANJI_SJIS_L1, // 狭 + 0x77EF, KANJI_SJIS_L1, // 矯 + 0x80F8, KANJI_SJIS_L1, // 胞 + 0x8105, KANJI_SJIS_L1, // 脅 + 0x8208, KANJI_SJIS_L1, // 興 + 0x854E, KANJI_SJIS_L1, // 蕎 + 0x90F7, KANJI_SJIS_L1, // 郷 + 0x93E1, KANJI_SJIS_L1, // 鏡 + 0x97FF, KANJI_SJIS_L1, // 響 + 0x9957, KANJI_SJIS_L1, // 饗 + 0x9A5A, KANJI_SJIS_L1, // 驚 + 0x4EF0, KANJI_SJIS_L1, // ä»° + 0x51DD, KANJI_SJIS_L1, // 凝 + 0x5C2D, KANJI_SJIS_L1, // å°­ + 0x6681, KANJI_SJIS_L1, // 暁 + 0x696D, KANJI_SJIS_L1, // 業 + 0x5C40, KANJI_SJIS_L1, // 局 + 0x66F2, KANJI_SJIS_L1, // 曲 + 0x6975, KANJI_SJIS_L1, // 極 + 0x7389, KANJI_SJIS_L1, // 玉 + 0x6850, KANJI_SJIS_L1, // 桐 + 0x7C81, KANJI_SJIS_L1, // 粁 + 0x50C5, KANJI_SJIS_L1, // 僅 + 0x52E4, KANJI_SJIS_L1, // å‹€ + 0x5747, KANJI_SJIS_L1, // 均 + 0x5DFE, KANJI_SJIS_L1, // å·Ÿ + 0x9326, KANJI_SJIS_L1, // 錩 + 0x65A4, KANJI_SJIS_L1, // æ–€ + 0x6B23, KANJI_SJIS_L1, // 欣 + 0x6B3D, KANJI_SJIS_L1, // 欜 + 0x7434, KANJI_SJIS_L1, // 琎 + 0x7981, KANJI_SJIS_L1, // 犁 + 0x79BD, KANJI_SJIS_L1, // 犜 + 0x7B4B, KANJI_SJIS_L1, // 筋 + 0x7DCA, KANJI_SJIS_L1, // 緊 + 0x82B9, KANJI_SJIS_L1, // 芹 + 0x83CC, KANJI_SJIS_L1, // 菌 + 0x887F, KANJI_SJIS_L1, // è¡¿ + 0x895F, KANJI_SJIS_L1, // 襟 + 0x8B39, KANJI_SJIS_L1, // 謹 + 0x8FD1, KANJI_SJIS_L1, // 近 + 0x91D1, KANJI_SJIS_L1, // 金 + 0x541F, KANJI_SJIS_L1, // 吟 + 0x9280, KANJI_SJIS_L1, // 銀 + 0x4E5D, KANJI_SJIS_L1, // 九 + 0x5036, KANJI_SJIS_L1, // 倶 + 0x53E5, KANJI_SJIS_L1, // 句 + 0x533A, KANJI_SJIS_L1, // 区 + 0x72D7, KANJI_SJIS_L1, // 狗 + 0x7396, KANJI_SJIS_L1, // 玖 + 0x77E9, KANJI_SJIS_L1, // 矩 + 0x82E6, KANJI_SJIS_L1, // 苊 + 0x8EAF, KANJI_SJIS_L1, // 躯 + 0x99C6, KANJI_SJIS_L1, // 駆 + 0x99C8, KANJI_SJIS_L1, // 駈 + 0x99D2, KANJI_SJIS_L1, // 駒 + 0x5177, KANJI_SJIS_L1, // 具 + 0x611A, KANJI_SJIS_L1, // 愚 + 0x865E, KANJI_SJIS_L1, // 虞 + 0x55B0, KANJI_SJIS_L1, // 喰 + 0x7A7A, KANJI_SJIS_L1, // 空 + 0x5076, KANJI_SJIS_L1, // 偶 + 0x5BD3, KANJI_SJIS_L1, // 寓 + 0x9047, KANJI_SJIS_L1, // 遇 + 0x9685, KANJI_SJIS_L1, // 隅 + 0x4E32, KANJI_SJIS_L1, // äž² + 0x6ADB, KANJI_SJIS_L1, // 櫛 + 0x91E7, KANJI_SJIS_L1, // 釧 + 0x5C51, KANJI_SJIS_L1, // 屑 + 0x5C48, KANJI_SJIS_L1, // 屈 + 0x6398, KANJI_SJIS_L1, // 掘 + 0x7A9F, KANJI_SJIS_L1, // 窟 + 0x6C93, KANJI_SJIS_L1, // 沓 + 0x9774, KANJI_SJIS_L1, // 靎 + 0x8F61, KANJI_SJIS_L1, // 蜡 + 0x7AAA, KANJI_SJIS_L1, // 窪 + 0x718A, KANJI_SJIS_L1, // 熊 + 0x9688, KANJI_SJIS_L1, // 隈 + 0x7C82, KANJI_SJIS_L1, // 粂 + 0x6817, KANJI_SJIS_L1, // 栗 + 0x7E70, KANJI_SJIS_L1, // ç¹° + 0x6851, KANJI_SJIS_L1, // 桑 + 0x936C, KANJI_SJIS_L1, // 鍬 + 0x52F2, KANJI_SJIS_L1, // 勲 + 0x541B, KANJI_SJIS_L1, // 君 + 0x85AB, KANJI_SJIS_L1, // 薫 + 0x8A13, KANJI_SJIS_L1, // èš“ + 0x7FA4, KANJI_SJIS_L1, // 矀 + 0x8ECD, KANJI_SJIS_L1, // 軍 + 0x90E1, KANJI_SJIS_L1, // 郡 + 0x5366, KANJI_SJIS_L1, // 半 + 0x8888, KANJI_SJIS_L1, // 袈 + 0x7941, KANJI_SJIS_L1, // 祁 + 0x4FC2, KANJI_SJIS_L1, // 係 + 0x50BE, KANJI_SJIS_L1, // 傟 + 0x5211, KANJI_SJIS_L1, // 刑 + 0x5144, KANJI_SJIS_L1, // 兄 + 0x5553, KANJI_SJIS_L1, // 啓 + 0x572D, KANJI_SJIS_L1, // 圭 + 0x73EA, KANJI_SJIS_L1, // 珪 + 0x578B, KANJI_SJIS_L1, // 型 + 0x5951, KANJI_SJIS_L1, // 契 + 0x5F62, KANJI_SJIS_L1, // 圢 + 0x5F84, KANJI_SJIS_L1, // 埄 + 0x6075, KANJI_SJIS_L1, // 恵 + 0x6176, KANJI_SJIS_L1, // 慶 + 0x6167, KANJI_SJIS_L1, // 慧 + 0x61A9, KANJI_SJIS_L1, // 憩 + 0x63B2, KANJI_SJIS_L1, // 掲 + 0x643A, KANJI_SJIS_L1, // 携 + 0x656C, KANJI_SJIS_L1, // 敬 + 0x666F, KANJI_SJIS_L1, // 景 + 0x6842, KANJI_SJIS_L1, // 桂 + 0x6E13, KANJI_SJIS_L1, // æž“ + 0x7566, KANJI_SJIS_L1, // 畩 + 0x7A3D, KANJI_SJIS_L1, // çšœ + 0x7CFB, KANJI_SJIS_L1, // ç³» + 0x7D4C, KANJI_SJIS_L1, // 経 + 0x7D99, KANJI_SJIS_L1, // 継 + 0x7E4B, KANJI_SJIS_L1, // 繋 + 0x7F6B, KANJI_SJIS_L1, // 眫 + 0x830E, KANJI_SJIS_L1, // 茎 + 0x834A, KANJI_SJIS_L1, // 荊 + 0x86CD, KANJI_SJIS_L1, // 蛍 + 0x8A08, KANJI_SJIS_L1, // 蚈 + 0x8A63, KANJI_SJIS_L1, // è©£ + 0x8B66, KANJI_SJIS_L1, // è­Š + 0x8EFD, KANJI_SJIS_L1, // 軜 + 0x981A, KANJI_SJIS_L1, // 頚 + 0x9D8F, KANJI_SJIS_L1, // 鶏 + 0x82B8, KANJI_SJIS_L1, // 芞 + 0x8FCE, KANJI_SJIS_L1, // 迎 + 0x9BE8, KANJI_SJIS_L1, // 鯚 + 0x3000, KANJI_SJIS_L1, //   + 0x5287, KANJI_SJIS_L1, // 劇 + 0x621F, KANJI_SJIS_L1, // 戟 + 0x6483, KANJI_SJIS_L1, // 撃 + 0x6FC0, KANJI_SJIS_L1, // 激 + 0x9699, KANJI_SJIS_L1, // 隙 + 0x6841, KANJI_SJIS_L1, // 桁 + 0x5091, KANJI_SJIS_L1, // 傑 + 0x6B20, KANJI_SJIS_L1, // 欠 + 0x6C7A, KANJI_SJIS_L1, // 決 + 0x6F54, KANJI_SJIS_L1, // 朔 + 0x7A74, KANJI_SJIS_L1, // 穎 + 0x7D50, KANJI_SJIS_L1, // 結 + 0x8840, KANJI_SJIS_L1, // 血 + 0x8A23, KANJI_SJIS_L1, // 蚣 + 0x6708, KANJI_SJIS_L1, // 月 + 0x4EF6, KANJI_SJIS_L1, // ä»¶ + 0x5039, KANJI_SJIS_L1, // 倹 + 0x5026, KANJI_SJIS_L1, // 倊 + 0x5065, KANJI_SJIS_L1, // 健 + 0x517C, KANJI_SJIS_L1, // å…Œ + 0x5238, KANJI_SJIS_L1, // 刞 + 0x5263, KANJI_SJIS_L1, // 剣 + 0x55A7, KANJI_SJIS_L1, // 喧 + 0x570F, KANJI_SJIS_L1, // 圏 + 0x5805, KANJI_SJIS_L1, // 堅 + 0x5ACC, KANJI_SJIS_L1, // 嫌 + 0x5EFA, KANJI_SJIS_L1, // 建 + 0x61B2, KANJI_SJIS_L1, // 憲 + 0x61F8, KANJI_SJIS_L1, // 懞 + 0x62F3, KANJI_SJIS_L1, // 拳 + 0x6372, KANJI_SJIS_L1, // 捲 + 0x691C, KANJI_SJIS_L1, // 怜 + 0x6A29, KANJI_SJIS_L1, // æš© + 0x727D, KANJI_SJIS_L1, // 牜 + 0x72AC, KANJI_SJIS_L1, // 犬 + 0x732E, KANJI_SJIS_L1, // 献 + 0x7814, KANJI_SJIS_L1, // 研 + 0x786F, KANJI_SJIS_L1, // 硯 + 0x7D79, KANJI_SJIS_L1, // çµ¹ + 0x770C, KANJI_SJIS_L1, // 県 + 0x80A9, KANJI_SJIS_L1, // 肩 + 0x898B, KANJI_SJIS_L1, // 芋 + 0x8B19, KANJI_SJIS_L1, // 謙 + 0x8CE2, KANJI_SJIS_L1, // è³¢ + 0x8ED2, KANJI_SJIS_L1, // 軒 + 0x9063, KANJI_SJIS_L1, // 遣 + 0x9375, KANJI_SJIS_L1, // 鍵 + 0x967A, KANJI_SJIS_L1, // 険 + 0x9855, KANJI_SJIS_L1, // 顕 + 0x9A13, KANJI_SJIS_L1, // 鹓 + 0x9E78, KANJI_SJIS_L1, // 鹞 + 0x5143, KANJI_SJIS_L1, // 元 + 0x539F, KANJI_SJIS_L1, // 原 + 0x53B3, KANJI_SJIS_L1, // 厳 + 0x5E7B, KANJI_SJIS_L1, // å¹» + 0x5F26, KANJI_SJIS_L1, // 匊 + 0x6E1B, KANJI_SJIS_L1, // æž› + 0x6E90, KANJI_SJIS_L1, // 源 + 0x7384, KANJI_SJIS_L1, // 玄 + 0x73FE, KANJI_SJIS_L1, // 珟 + 0x7D43, KANJI_SJIS_L1, // 絃 + 0x8237, KANJI_SJIS_L1, // 舷 + 0x8A00, KANJI_SJIS_L1, // 蚀 + 0x8AFA, KANJI_SJIS_L1, // 諺 + 0x9650, KANJI_SJIS_L1, // 限 + 0x4E4E, KANJI_SJIS_L1, // 乎 + 0x500B, KANJI_SJIS_L1, // 個 + 0x53E4, KANJI_SJIS_L1, // 叀 + 0x547C, KANJI_SJIS_L1, // 呌 + 0x56FA, KANJI_SJIS_L1, // 固 + 0x59D1, KANJI_SJIS_L1, // 姑 + 0x5B64, KANJI_SJIS_L1, // å­€ + 0x5DF1, KANJI_SJIS_L1, // å·± + 0x5EAB, KANJI_SJIS_L1, // 庫 + 0x5F27, KANJI_SJIS_L1, // 匧 + 0x6238, KANJI_SJIS_L1, // 戞 + 0x6545, KANJI_SJIS_L1, // 故 + 0x67AF, KANJI_SJIS_L1, // 枯 + 0x6E56, KANJI_SJIS_L1, // 湖 + 0x72D0, KANJI_SJIS_L1, // 狐 + 0x7CCA, KANJI_SJIS_L1, // 糊 + 0x88B4, KANJI_SJIS_L1, // 袎 + 0x80A1, KANJI_SJIS_L1, // 股 + 0x80E1, KANJI_SJIS_L1, // 胡 + 0x83F0, KANJI_SJIS_L1, // 菰 + 0x864E, KANJI_SJIS_L1, // 虎 + 0x8A87, KANJI_SJIS_L1, // 誇 + 0x8DE8, KANJI_SJIS_L1, // è·š + 0x9237, KANJI_SJIS_L1, // 鈷 + 0x96C7, KANJI_SJIS_L1, // 雇 + 0x9867, KANJI_SJIS_L1, // é¡§ + 0x9F13, KANJI_SJIS_L1, // 錓 + 0x4E94, KANJI_SJIS_L1, // 五 + 0x4E92, KANJI_SJIS_L1, // 互 + 0x4F0D, KANJI_SJIS_L1, // 䌍 + 0x5348, KANJI_SJIS_L1, // 午 + 0x5449, KANJI_SJIS_L1, // 呉 + 0x543E, KANJI_SJIS_L1, // 吟 + 0x5A2F, KANJI_SJIS_L1, // 嚯 + 0x5F8C, KANJI_SJIS_L1, // 埌 + 0x5FA1, KANJI_SJIS_L1, // 埡 + 0x609F, KANJI_SJIS_L1, // 悟 + 0x68A7, KANJI_SJIS_L1, // 梧 + 0x6A8E, KANJI_SJIS_L1, // 檎 + 0x745A, KANJI_SJIS_L1, // 瑚 + 0x7881, KANJI_SJIS_L1, // 碁 + 0x8A9E, KANJI_SJIS_L1, // 語 + 0x8AA4, KANJI_SJIS_L1, // 誀 + 0x8B77, KANJI_SJIS_L1, // è­· + 0x9190, KANJI_SJIS_L1, // 醐 + 0x4E5E, KANJI_SJIS_L1, // 乞 + 0x9BC9, KANJI_SJIS_L1, // 鯉 + 0x4EA4, KANJI_SJIS_L1, // 亀 + 0x4F7C, KANJI_SJIS_L1, // 䜌 + 0x4FAF, KANJI_SJIS_L1, // 䟯 + 0x5019, KANJI_SJIS_L1, // 候 + 0x5016, KANJI_SJIS_L1, // 倖 + 0x5149, KANJI_SJIS_L1, // 光 + 0x516C, KANJI_SJIS_L1, // 公 + 0x529F, KANJI_SJIS_L1, // 功 + 0x52B9, KANJI_SJIS_L1, // 効 + 0x52FE, KANJI_SJIS_L1, // 募 + 0x539A, KANJI_SJIS_L1, // 厚 + 0x53E3, KANJI_SJIS_L1, // 口 + 0x5411, KANJI_SJIS_L1, // 向 + 0x540E, KANJI_SJIS_L1, // 后 + 0x5589, KANJI_SJIS_L1, // 喉 + 0x5751, KANJI_SJIS_L1, // 坑 + 0x57A2, KANJI_SJIS_L1, // 垢 + 0x597D, KANJI_SJIS_L1, // 奜 + 0x5B54, KANJI_SJIS_L1, // 孔 + 0x5B5D, KANJI_SJIS_L1, // 孝 + 0x5B8F, KANJI_SJIS_L1, // 宏 + 0x5DE5, KANJI_SJIS_L1, // å·¥ + 0x5DE7, KANJI_SJIS_L1, // å·§ + 0x5DF7, KANJI_SJIS_L1, // å·· + 0x5E78, KANJI_SJIS_L1, // 幞 + 0x5E83, KANJI_SJIS_L1, // 広 + 0x5E9A, KANJI_SJIS_L1, // 庚 + 0x5EB7, KANJI_SJIS_L1, // 康 + 0x5F18, KANJI_SJIS_L1, // 匘 + 0x6052, KANJI_SJIS_L1, // 恒 + 0x614C, KANJI_SJIS_L1, // 慌 + 0x6297, KANJI_SJIS_L1, // 抗 + 0x62D8, KANJI_SJIS_L1, // 拘 + 0x63A7, KANJI_SJIS_L1, // 控 + 0x653B, KANJI_SJIS_L1, // 攻 + 0x6602, KANJI_SJIS_L1, // 昂 + 0x6643, KANJI_SJIS_L1, // 晃 + 0x66F4, KANJI_SJIS_L1, // 曎 + 0x676D, KANJI_SJIS_L1, // 杭 + 0x6821, KANJI_SJIS_L1, // æ ¡ + 0x6897, KANJI_SJIS_L1, // 梗 + 0x69CB, KANJI_SJIS_L1, // 構 + 0x6C5F, KANJI_SJIS_L1, // 江 + 0x6D2A, KANJI_SJIS_L1, // 措 + 0x6D69, KANJI_SJIS_L1, // 浩 + 0x6E2F, KANJI_SJIS_L1, // 枯 + 0x6E9D, KANJI_SJIS_L1, // 溝 + 0x7532, KANJI_SJIS_L1, // 甲 + 0x7687, KANJI_SJIS_L1, // 皇 + 0x786C, KANJI_SJIS_L1, // 硬 + 0x7A3F, KANJI_SJIS_L1, // çš¿ + 0x7CE0, KANJI_SJIS_L1, // ç³  + 0x7D05, KANJI_SJIS_L1, // 箅 + 0x7D18, KANJI_SJIS_L1, // 玘 + 0x7D5E, KANJI_SJIS_L1, // 絞 + 0x7DB1, KANJI_SJIS_L1, // ç¶± + 0x8015, KANJI_SJIS_L1, // 耕 + 0x8003, KANJI_SJIS_L1, // 考 + 0x80AF, KANJI_SJIS_L1, // 肯 + 0x80B1, KANJI_SJIS_L1, // 肱 + 0x8154, KANJI_SJIS_L1, // 腔 + 0x818F, KANJI_SJIS_L1, // 膏 + 0x822A, KANJI_SJIS_L1, // 航 + 0x8352, KANJI_SJIS_L1, // 荒 + 0x884C, KANJI_SJIS_L1, // 行 + 0x8861, KANJI_SJIS_L1, // è¡¡ + 0x8B1B, KANJI_SJIS_L1, // 講 + 0x8CA2, KANJI_SJIS_L1, // è²¢ + 0x8CFC, KANJI_SJIS_L1, // 賌 + 0x90CA, KANJI_SJIS_L1, // 郊 + 0x9175, KANJI_SJIS_L1, // 酵 + 0x9271, KANJI_SJIS_L1, // 鉱 + 0x783F, KANJI_SJIS_L1, // ç ¿ + 0x92FC, KANJI_SJIS_L1, // 鋌 + 0x95A4, KANJI_SJIS_L1, // é–€ + 0x964D, KANJI_SJIS_L1, // 降 + 0x3000, KANJI_SJIS_L1, //   + 0x9805, KANJI_SJIS_L1, // 項 + 0x9999, KANJI_SJIS_L1, // 驙 + 0x9AD8, KANJI_SJIS_L1, // 高 + 0x9D3B, KANJI_SJIS_L1, // 鎻 + 0x525B, KANJI_SJIS_L1, // 剛 + 0x52AB, KANJI_SJIS_L1, // 劫 + 0x53F7, KANJI_SJIS_L1, // 号 + 0x5408, KANJI_SJIS_L1, // 合 + 0x58D5, KANJI_SJIS_L1, // 壕 + 0x62F7, KANJI_SJIS_L1, // 拷 + 0x6FE0, KANJI_SJIS_L1, // æ¿  + 0x8C6A, KANJI_SJIS_L1, // 豪 + 0x8F5F, KANJI_SJIS_L1, // 蜟 + 0x9EB9, KANJI_SJIS_L1, // 麹 + 0x514B, KANJI_SJIS_L1, // 克 + 0x523B, KANJI_SJIS_L1, // 刻 + 0x544A, KANJI_SJIS_L1, // 告 + 0x56FD, KANJI_SJIS_L1, // 囜 + 0x7A40, KANJI_SJIS_L1, // 穀 + 0x9177, KANJI_SJIS_L1, // 酷 + 0x9D60, KANJI_SJIS_L1, // éµ  + 0x9ED2, KANJI_SJIS_L1, // 黒 + 0x7344, KANJI_SJIS_L1, // 獄 + 0x6F09, KANJI_SJIS_L1, // 按 + 0x8170, KANJI_SJIS_L1, // 腰 + 0x7511, KANJI_SJIS_L1, // 甑 + 0x5FFD, KANJI_SJIS_L1, // 応 + 0x60DA, KANJI_SJIS_L1, // 惚 + 0x9AA8, KANJI_SJIS_L1, // 骚 + 0x72DB, KANJI_SJIS_L1, // 狛 + 0x8FBC, KANJI_SJIS_L1, // 蟌 + 0x6B64, KANJI_SJIS_L1, // æ­€ + 0x9803, KANJI_SJIS_L1, // 頃 + 0x4ECA, KANJI_SJIS_L1, // 今 + 0x56F0, KANJI_SJIS_L1, // 困 + 0x5764, KANJI_SJIS_L1, // 址 + 0x58BE, KANJI_SJIS_L1, // 墟 + 0x5A5A, KANJI_SJIS_L1, // 婚 + 0x6068, KANJI_SJIS_L1, // 恚 + 0x61C7, KANJI_SJIS_L1, // 懇 + 0x660F, KANJI_SJIS_L1, // 昏 + 0x6606, KANJI_SJIS_L1, // 昆 + 0x6839, KANJI_SJIS_L1, // æ ¹ + 0x68B1, KANJI_SJIS_L1, // 梱 + 0x6DF7, KANJI_SJIS_L1, // æ·· + 0x75D5, KANJI_SJIS_L1, // 痕 + 0x7D3A, KANJI_SJIS_L1, // 玺 + 0x826E, KANJI_SJIS_L1, // 艮 + 0x9B42, KANJI_SJIS_L1, // 魂 + 0x4E9B, KANJI_SJIS_L1, // 些 + 0x4F50, KANJI_SJIS_L1, // 䜐 + 0x53C9, KANJI_SJIS_L1, // 叉 + 0x5506, KANJI_SJIS_L1, // 唆 + 0x5D6F, KANJI_SJIS_L1, // 嵯 + 0x5DE6, KANJI_SJIS_L1, // å·Š + 0x5DEE, KANJI_SJIS_L1, // å·® + 0x67FB, KANJI_SJIS_L1, // 査 + 0x6C99, KANJI_SJIS_L1, // 沙 + 0x7473, KANJI_SJIS_L1, // 瑳 + 0x7802, KANJI_SJIS_L1, // 砂 + 0x8A50, KANJI_SJIS_L1, // 詐 + 0x9396, KANJI_SJIS_L1, // 鎖 + 0x88DF, KANJI_SJIS_L1, // 裟 + 0x5750, KANJI_SJIS_L1, // 坐 + 0x5EA7, KANJI_SJIS_L1, // 座 + 0x632B, KANJI_SJIS_L1, // 挫 + 0x50B5, KANJI_SJIS_L1, // 債 + 0x50AC, KANJI_SJIS_L1, // 催 + 0x518D, KANJI_SJIS_L1, // 再 + 0x6700, KANJI_SJIS_L1, // 最 + 0x54C9, KANJI_SJIS_L1, // 哉 + 0x585E, KANJI_SJIS_L1, // 塞 + 0x59BB, KANJI_SJIS_L1, // 劻 + 0x5BB0, KANJI_SJIS_L1, // å®° + 0x5F69, KANJI_SJIS_L1, // 圩 + 0x624D, KANJI_SJIS_L1, // 才 + 0x63A1, KANJI_SJIS_L1, // 採 + 0x683D, KANJI_SJIS_L1, // æ œ + 0x6B73, KANJI_SJIS_L1, // æ­³ + 0x6E08, KANJI_SJIS_L1, // 枈 + 0x707D, KANJI_SJIS_L1, // 灜 + 0x91C7, KANJI_SJIS_L1, // 采 + 0x7280, KANJI_SJIS_L1, // 犀 + 0x7815, KANJI_SJIS_L1, // 砕 + 0x7826, KANJI_SJIS_L1, // ç Š + 0x796D, KANJI_SJIS_L1, // 祭 + 0x658E, KANJI_SJIS_L1, // 斎 + 0x7D30, KANJI_SJIS_L1, // 现 + 0x83DC, KANJI_SJIS_L1, // 菜 + 0x88C1, KANJI_SJIS_L1, // 裁 + 0x8F09, KANJI_SJIS_L1, // 茉 + 0x969B, KANJI_SJIS_L1, // 際 + 0x5264, KANJI_SJIS_L1, // 剀 + 0x5728, KANJI_SJIS_L1, // 圚 + 0x6750, KANJI_SJIS_L1, // 材 + 0x7F6A, KANJI_SJIS_L1, // 眪 + 0x8CA1, KANJI_SJIS_L1, // 財 + 0x51B4, KANJI_SJIS_L1, // 冎 + 0x5742, KANJI_SJIS_L1, // 坂 + 0x962A, KANJI_SJIS_L1, // 阪 + 0x583A, KANJI_SJIS_L1, // å º + 0x698A, KANJI_SJIS_L1, // 把 + 0x80B4, KANJI_SJIS_L1, // 肎 + 0x54B2, KANJI_SJIS_L1, // 咲 + 0x5D0E, KANJI_SJIS_L1, // 厎 + 0x57FC, KANJI_SJIS_L1, // 埌 + 0x7895, KANJI_SJIS_L1, // 碕 + 0x9DFA, KANJI_SJIS_L1, // é·º + 0x4F5C, KANJI_SJIS_L1, // 䜜 + 0x524A, KANJI_SJIS_L1, // 削 + 0x548B, KANJI_SJIS_L1, // 咋 + 0x643E, KANJI_SJIS_L1, // 搟 + 0x6628, KANJI_SJIS_L1, // 昚 + 0x6714, KANJI_SJIS_L1, // 朔 + 0x67F5, KANJI_SJIS_L1, // 柵 + 0x7A84, KANJI_SJIS_L1, // 窄 + 0x7B56, KANJI_SJIS_L1, // 策 + 0x7D22, KANJI_SJIS_L1, // 玢 + 0x932F, KANJI_SJIS_L1, // 錯 + 0x685C, KANJI_SJIS_L1, // 桜 + 0x9BAD, KANJI_SJIS_L1, // é®­ + 0x7B39, KANJI_SJIS_L1, // 笹 + 0x5319, KANJI_SJIS_L1, // 匙 + 0x518A, KANJI_SJIS_L1, // 冊 + 0x5237, KANJI_SJIS_L1, // 刷 + 0x5BDF, KANJI_SJIS_L1, // 察 + 0x62F6, KANJI_SJIS_L1, // 拶 + 0x64AE, KANJI_SJIS_L1, // 撮 + 0x64E6, KANJI_SJIS_L1, // 擊 + 0x672D, KANJI_SJIS_L1, // 札 + 0x6BBA, KANJI_SJIS_L1, // 殺 + 0x85A9, KANJI_SJIS_L1, // 薩 + 0x96D1, KANJI_SJIS_L1, // 雑 + 0x7690, KANJI_SJIS_L1, // 皐 + 0x9BD6, KANJI_SJIS_L1, // 鯖 + 0x634C, KANJI_SJIS_L1, // 捌 + 0x9306, KANJI_SJIS_L1, // 錆 + 0x9BAB, KANJI_SJIS_L1, // 鮫 + 0x76BF, KANJI_SJIS_L1, // 皿 + 0x6652, KANJI_SJIS_L1, // 晒 + 0x4E09, KANJI_SJIS_L1, // 侉 + 0x5098, KANJI_SJIS_L1, // 傘 + 0x53C2, KANJI_SJIS_L1, // 参 + 0x5C71, KANJI_SJIS_L1, // å±± + 0x60E8, KANJI_SJIS_L1, // 惚 + 0x6492, KANJI_SJIS_L1, // 撒 + 0x6563, KANJI_SJIS_L1, // 散 + 0x685F, KANJI_SJIS_L1, // 桟 + 0x71E6, KANJI_SJIS_L1, // 燩 + 0x73CA, KANJI_SJIS_L1, // 珊 + 0x7523, KANJI_SJIS_L1, // 産 + 0x7B97, KANJI_SJIS_L1, // 算 + 0x7E82, KANJI_SJIS_L1, // 纂 + 0x8695, KANJI_SJIS_L1, // 蚕 + 0x8B83, KANJI_SJIS_L1, // 讃 + 0x8CDB, KANJI_SJIS_L1, // 賛 + 0x9178, KANJI_SJIS_L1, // 酾 + 0x9910, KANJI_SJIS_L1, // 逐 + 0x65AC, KANJI_SJIS_L1, // 斬 + 0x66AB, KANJI_SJIS_L1, // 暫 + 0x6B8B, KANJI_SJIS_L1, // 残 + 0x4ED5, KANJI_SJIS_L1, // 仕 + 0x4ED4, KANJI_SJIS_L1, // 仔 + 0x4F3A, KANJI_SJIS_L1, // 䌺 + 0x4F7F, KANJI_SJIS_L1, // 䜿 + 0x523A, KANJI_SJIS_L1, // 刺 + 0x53F8, KANJI_SJIS_L1, // 叞 + 0x53F2, KANJI_SJIS_L1, // 史 + 0x55E3, KANJI_SJIS_L1, // 嗣 + 0x56DB, KANJI_SJIS_L1, // 四 + 0x58EB, KANJI_SJIS_L1, // 士 + 0x59CB, KANJI_SJIS_L1, // 始 + 0x59C9, KANJI_SJIS_L1, // 姉 + 0x59FF, KANJI_SJIS_L1, // å§¿ + 0x5B50, KANJI_SJIS_L1, // 子 + 0x5C4D, KANJI_SJIS_L1, // 屍 + 0x5E02, KANJI_SJIS_L1, // åž‚ + 0x5E2B, KANJI_SJIS_L1, // åž« + 0x5FD7, KANJI_SJIS_L1, // 志 + 0x601D, KANJI_SJIS_L1, // 思 + 0x6307, KANJI_SJIS_L1, // 指 + 0x652F, KANJI_SJIS_L1, // 支 + 0x5B5C, KANJI_SJIS_L1, // 孜 + 0x65AF, KANJI_SJIS_L1, // 斯 + 0x65BD, KANJI_SJIS_L1, // æ–œ + 0x65E8, KANJI_SJIS_L1, // æ—š + 0x679D, KANJI_SJIS_L1, // 枝 + 0x6B62, KANJI_SJIS_L1, // æ­¢ + 0x3000, KANJI_SJIS_L1, //   + 0x6B7B, KANJI_SJIS_L1, // æ­» + 0x6C0F, KANJI_SJIS_L1, // 氏 + 0x7345, KANJI_SJIS_L1, // 獅 + 0x7949, KANJI_SJIS_L1, // 祉 + 0x79C1, KANJI_SJIS_L1, // 私 + 0x7CF8, KANJI_SJIS_L1, // 糞 + 0x7D19, KANJI_SJIS_L1, // 箙 + 0x7D2B, KANJI_SJIS_L1, // 玫 + 0x80A2, KANJI_SJIS_L1, // 肢 + 0x8102, KANJI_SJIS_L1, // 脂 + 0x81F3, KANJI_SJIS_L1, // 至 + 0x8996, KANJI_SJIS_L1, // 芖 + 0x8A5E, KANJI_SJIS_L1, // 詞 + 0x8A69, KANJI_SJIS_L1, // è©© + 0x8A66, KANJI_SJIS_L1, // 詊 + 0x8A8C, KANJI_SJIS_L1, // 誌 + 0x8AEE, KANJI_SJIS_L1, // è«® + 0x8CC7, KANJI_SJIS_L1, // 資 + 0x8CDC, KANJI_SJIS_L1, // 賜 + 0x96CC, KANJI_SJIS_L1, // 雌 + 0x98FC, KANJI_SJIS_L1, // 飌 + 0x6B6F, KANJI_SJIS_L1, // æ­¯ + 0x4E8B, KANJI_SJIS_L1, // 事 + 0x4F3C, KANJI_SJIS_L1, // 䌌 + 0x4F8D, KANJI_SJIS_L1, // 䟍 + 0x5150, KANJI_SJIS_L1, // 児 + 0x5B57, KANJI_SJIS_L1, // 字 + 0x5BFA, KANJI_SJIS_L1, // 寺 + 0x6148, KANJI_SJIS_L1, // 慈 + 0x6301, KANJI_SJIS_L1, // 持 + 0x6642, KANJI_SJIS_L1, // 時 + 0x6B21, KANJI_SJIS_L1, // 次 + 0x6ECB, KANJI_SJIS_L1, // 滋 + 0x6CBB, KANJI_SJIS_L1, // æ²» + 0x723E, KANJI_SJIS_L1, // 爟 + 0x74BD, KANJI_SJIS_L1, // ç’œ + 0x75D4, KANJI_SJIS_L1, // 痔 + 0x78C1, KANJI_SJIS_L1, // 磁 + 0x793A, KANJI_SJIS_L1, // 瀺 + 0x800C, KANJI_SJIS_L1, // 而 + 0x8033, KANJI_SJIS_L1, // 耳 + 0x81EA, KANJI_SJIS_L1, // 自 + 0x8494, KANJI_SJIS_L1, // 蒔 + 0x8F9E, KANJI_SJIS_L1, // 蟞 + 0x6C50, KANJI_SJIS_L1, // 汐 + 0x9E7F, KANJI_SJIS_L1, // 鹿 + 0x5F0F, KANJI_SJIS_L1, // 匏 + 0x8B58, KANJI_SJIS_L1, // 識 + 0x9D2B, KANJI_SJIS_L1, // 鎫 + 0x7AFA, KANJI_SJIS_L1, // 竺 + 0x8EF8, KANJI_SJIS_L1, // 軞 + 0x5B8D, KANJI_SJIS_L1, // 宍 + 0x96EB, KANJI_SJIS_L1, // 雫 + 0x4E03, KANJI_SJIS_L1, // 䞃 + 0x53F1, KANJI_SJIS_L1, // 叱 + 0x57F7, KANJI_SJIS_L1, // 執 + 0x5931, KANJI_SJIS_L1, // 倱 + 0x5AC9, KANJI_SJIS_L1, // 嫉 + 0x5BA4, KANJI_SJIS_L1, // 宀 + 0x6089, KANJI_SJIS_L1, // 悉 + 0x6E7F, KANJI_SJIS_L1, // 湿 + 0x6F06, KANJI_SJIS_L1, // 挆 + 0x75BE, KANJI_SJIS_L1, // ç–Ÿ + 0x8CEA, KANJI_SJIS_L1, // 質 + 0x5B9F, KANJI_SJIS_L1, // 実 + 0x8500, KANJI_SJIS_L1, // 蔀 + 0x7BE0, KANJI_SJIS_L1, // 篠 + 0x5072, KANJI_SJIS_L1, // 偲 + 0x67F4, KANJI_SJIS_L1, // 柎 + 0x829D, KANJI_SJIS_L1, // 芝 + 0x5C61, KANJI_SJIS_L1, // 屡 + 0x854A, KANJI_SJIS_L1, // 蕊 + 0x7E1E, KANJI_SJIS_L1, // 羞 + 0x820E, KANJI_SJIS_L1, // 舎 + 0x5199, KANJI_SJIS_L1, // 写 + 0x5C04, KANJI_SJIS_L1, // 射 + 0x6368, KANJI_SJIS_L1, // 捚 + 0x8D66, KANJI_SJIS_L1, // 赊 + 0x659C, KANJI_SJIS_L1, // 斜 + 0x716E, KANJI_SJIS_L1, // 煮 + 0x793E, KANJI_SJIS_L1, // 瀟 + 0x7D17, KANJI_SJIS_L1, // 算 + 0x8005, KANJI_SJIS_L1, // 者 + 0x8B1D, KANJI_SJIS_L1, // 謝 + 0x8ECA, KANJI_SJIS_L1, // 車 + 0x906E, KANJI_SJIS_L1, // 遮 + 0x86C7, KANJI_SJIS_L1, // 蛇 + 0x90AA, KANJI_SJIS_L1, // 邪 + 0x501F, KANJI_SJIS_L1, // 借 + 0x52FA, KANJI_SJIS_L1, // 勺 + 0x5C3A, KANJI_SJIS_L1, // å°º + 0x6753, KANJI_SJIS_L1, // 杓 + 0x707C, KANJI_SJIS_L1, // 灌 + 0x7235, KANJI_SJIS_L1, // 爵 + 0x914C, KANJI_SJIS_L1, // 酌 + 0x91C8, KANJI_SJIS_L1, // 釈 + 0x932B, KANJI_SJIS_L1, // 錫 + 0x82E5, KANJI_SJIS_L1, // 若 + 0x5BC2, KANJI_SJIS_L1, // 寂 + 0x5F31, KANJI_SJIS_L1, // 匱 + 0x60F9, KANJI_SJIS_L1, // 惹 + 0x4E3B, KANJI_SJIS_L1, // äž» + 0x53D6, KANJI_SJIS_L1, // 取 + 0x5B88, KANJI_SJIS_L1, // 守 + 0x624B, KANJI_SJIS_L1, // 手 + 0x6731, KANJI_SJIS_L1, // 朱 + 0x6B8A, KANJI_SJIS_L1, // 殊 + 0x72E9, KANJI_SJIS_L1, // 狩 + 0x73E0, KANJI_SJIS_L1, // 珠 + 0x7A2E, KANJI_SJIS_L1, // çš® + 0x816B, KANJI_SJIS_L1, // 腫 + 0x8DA3, KANJI_SJIS_L1, // è¶£ + 0x9152, KANJI_SJIS_L1, // 酒 + 0x9996, KANJI_SJIS_L1, // 驖 + 0x5112, KANJI_SJIS_L1, // 儒 + 0x53D7, KANJI_SJIS_L1, // 受 + 0x546A, KANJI_SJIS_L1, // 呪 + 0x5BFF, KANJI_SJIS_L1, // 寿 + 0x6388, KANJI_SJIS_L1, // 授 + 0x6A39, KANJI_SJIS_L1, // æš¹ + 0x7DAC, KANJI_SJIS_L1, // 綬 + 0x9700, KANJI_SJIS_L1, // 需 + 0x56DA, KANJI_SJIS_L1, // 囚 + 0x53CE, KANJI_SJIS_L1, // 収 + 0x5468, KANJI_SJIS_L1, // 呚 + 0x5B97, KANJI_SJIS_L1, // 宗 + 0x5C31, KANJI_SJIS_L1, // å°± + 0x5DDE, KANJI_SJIS_L1, // 州 + 0x4FEE, KANJI_SJIS_L1, // ä¿® + 0x6101, KANJI_SJIS_L1, // 愁 + 0x62FE, KANJI_SJIS_L1, // 拟 + 0x6D32, KANJI_SJIS_L1, // 掲 + 0x79C0, KANJI_SJIS_L1, // 秀 + 0x79CB, KANJI_SJIS_L1, // 秋 + 0x7D42, KANJI_SJIS_L1, // 終 + 0x7E4D, KANJI_SJIS_L1, // 繍 + 0x7FD2, KANJI_SJIS_L1, // 習 + 0x81ED, KANJI_SJIS_L1, // 臭 + 0x821F, KANJI_SJIS_L1, // 舟 + 0x8490, KANJI_SJIS_L1, // 蒐 + 0x8846, KANJI_SJIS_L1, // 衆 + 0x8972, KANJI_SJIS_L1, // 襲 + 0x8B90, KANJI_SJIS_L1, // 讐 + 0x8E74, KANJI_SJIS_L1, // 蹎 + 0x8F2F, KANJI_SJIS_L1, // 茯 + 0x9031, KANJI_SJIS_L1, // 週 + 0x914B, KANJI_SJIS_L1, // 酋 + 0x916C, KANJI_SJIS_L1, // 酬 + 0x96C6, KANJI_SJIS_L1, // 集 + 0x919C, KANJI_SJIS_L1, // 醜 + 0x4EC0, KANJI_SJIS_L1, // 什 + 0x4F4F, KANJI_SJIS_L1, // 䜏 + 0x5145, KANJI_SJIS_L1, // 充 + 0x5341, KANJI_SJIS_L1, // 十 + 0x5F93, KANJI_SJIS_L1, // 埓 + 0x620E, KANJI_SJIS_L1, // 戎 + 0x67D4, KANJI_SJIS_L1, // 柔 + 0x6C41, KANJI_SJIS_L1, // 汁 + 0x6E0B, KANJI_SJIS_L1, // æž‹ + 0x7363, KANJI_SJIS_L1, // 獣 + 0x7E26, KANJI_SJIS_L1, // 瞊 + 0x91CD, KANJI_SJIS_L1, // 重 + 0x9283, KANJI_SJIS_L1, // 銃 + 0x53D4, KANJI_SJIS_L1, // 叔 + 0x5919, KANJI_SJIS_L1, // 候 + 0x5BBF, KANJI_SJIS_L1, // 宿 + 0x6DD1, KANJI_SJIS_L1, // 淑 + 0x795D, KANJI_SJIS_L1, // 祝 + 0x7E2E, KANJI_SJIS_L1, // çž® + 0x7C9B, KANJI_SJIS_L1, // 粛 + 0x587E, KANJI_SJIS_L1, // 塟 + 0x719F, KANJI_SJIS_L1, // 熟 + 0x51FA, KANJI_SJIS_L1, // 出 + 0x8853, KANJI_SJIS_L1, // 術 + 0x8FF0, KANJI_SJIS_L1, // è¿° + 0x4FCA, KANJI_SJIS_L1, // 俊 + 0x5CFB, KANJI_SJIS_L1, // å³» + 0x6625, KANJI_SJIS_L1, // 春 + 0x77AC, KANJI_SJIS_L1, // 瞬 + 0x7AE3, KANJI_SJIS_L1, // ç«£ + 0x821C, KANJI_SJIS_L1, // 舜 + 0x99FF, KANJI_SJIS_L1, // é§¿ + 0x51C6, KANJI_SJIS_L1, // 准 + 0x5FAA, KANJI_SJIS_L1, // 埪 + 0x65EC, KANJI_SJIS_L1, // 旬 + 0x696F, KANJI_SJIS_L1, // 楯 + 0x6B89, KANJI_SJIS_L1, // 殉 + 0x6DF3, KANJI_SJIS_L1, // æ·³ + 0x3000, KANJI_SJIS_L1, //   + 0x6E96, KANJI_SJIS_L1, // 準 + 0x6F64, KANJI_SJIS_L1, // 最 + 0x76FE, KANJI_SJIS_L1, // 盟 + 0x7D14, KANJI_SJIS_L1, // 箔 + 0x5DE1, KANJI_SJIS_L1, // å·¡ + 0x9075, KANJI_SJIS_L1, // 遵 + 0x9187, KANJI_SJIS_L1, // 醇 + 0x9806, KANJI_SJIS_L1, // 順 + 0x51E6, KANJI_SJIS_L1, // 凊 + 0x521D, KANJI_SJIS_L1, // 初 + 0x6240, KANJI_SJIS_L1, // 所 + 0x6691, KANJI_SJIS_L1, // 暑 + 0x66D9, KANJI_SJIS_L1, // 曙 + 0x6E1A, KANJI_SJIS_L1, // æžš + 0x5EB6, KANJI_SJIS_L1, // 庶 + 0x7DD2, KANJI_SJIS_L1, // 緒 + 0x7F72, KANJI_SJIS_L1, // 眲 + 0x66F8, KANJI_SJIS_L1, // 曞 + 0x85AF, KANJI_SJIS_L1, // 薯 + 0x85F7, KANJI_SJIS_L1, // 藷 + 0x8AF8, KANJI_SJIS_L1, // 諞 + 0x52A9, KANJI_SJIS_L1, // 助 + 0x53D9, KANJI_SJIS_L1, // 叙 + 0x5973, KANJI_SJIS_L1, // 女 + 0x5E8F, KANJI_SJIS_L1, // 序 + 0x5F90, KANJI_SJIS_L1, // 埐 + 0x6055, KANJI_SJIS_L1, // 恕 + 0x92E4, KANJI_SJIS_L1, // é‹€ + 0x9664, KANJI_SJIS_L1, // 陀 + 0x50B7, KANJI_SJIS_L1, // 傷 + 0x511F, KANJI_SJIS_L1, // 償 + 0x52DD, KANJI_SJIS_L1, // 勝 + 0x5320, KANJI_SJIS_L1, // 匠 + 0x5347, KANJI_SJIS_L1, // 升 + 0x53EC, KANJI_SJIS_L1, // 召 + 0x54E8, KANJI_SJIS_L1, // 哚 + 0x5546, KANJI_SJIS_L1, // 商 + 0x5531, KANJI_SJIS_L1, // 唱 + 0x5617, KANJI_SJIS_L1, // 嘗 + 0x5968, KANJI_SJIS_L1, // 奚 + 0x59BE, KANJI_SJIS_L1, // 功 + 0x5A3C, KANJI_SJIS_L1, // 嚌 + 0x5BB5, KANJI_SJIS_L1, // 宵 + 0x5C06, KANJI_SJIS_L1, // 将 + 0x5C0F, KANJI_SJIS_L1, // 小 + 0x5C11, KANJI_SJIS_L1, // 少 + 0x5C1A, KANJI_SJIS_L1, // 尚 + 0x5E84, KANJI_SJIS_L1, // 庄 + 0x5E8A, KANJI_SJIS_L1, // 床 + 0x5EE0, KANJI_SJIS_L1, // å»  + 0x5F70, KANJI_SJIS_L1, // 地 + 0x627F, KANJI_SJIS_L1, // 承 + 0x6284, KANJI_SJIS_L1, // 抄 + 0x62DB, KANJI_SJIS_L1, // 招 + 0x638C, KANJI_SJIS_L1, // 掌 + 0x6377, KANJI_SJIS_L1, // 捷 + 0x6607, KANJI_SJIS_L1, // 昇 + 0x660C, KANJI_SJIS_L1, // 昌 + 0x662D, KANJI_SJIS_L1, // 昭 + 0x6676, KANJI_SJIS_L1, // 晶 + 0x677E, KANJI_SJIS_L1, // 束 + 0x68A2, KANJI_SJIS_L1, // 梢 + 0x6A1F, KANJI_SJIS_L1, // 暟 + 0x6A35, KANJI_SJIS_L1, // æšµ + 0x6CBC, KANJI_SJIS_L1, // 沌 + 0x6D88, KANJI_SJIS_L1, // 消 + 0x6E09, KANJI_SJIS_L1, // 枉 + 0x6E58, KANJI_SJIS_L1, // 湘 + 0x713C, KANJI_SJIS_L1, // 焌 + 0x7126, KANJI_SJIS_L1, // 焩 + 0x7167, KANJI_SJIS_L1, // 照 + 0x75C7, KANJI_SJIS_L1, // 症 + 0x7701, KANJI_SJIS_L1, // 省 + 0x785D, KANJI_SJIS_L1, // 硝 + 0x7901, KANJI_SJIS_L1, // 瀁 + 0x7965, KANJI_SJIS_L1, // 祥 + 0x79F0, KANJI_SJIS_L1, // ç§° + 0x7AE0, KANJI_SJIS_L1, // ç«  + 0x7B11, KANJI_SJIS_L1, // 笑 + 0x7CA7, KANJI_SJIS_L1, // ç²§ + 0x7D39, KANJI_SJIS_L1, // 玹 + 0x8096, KANJI_SJIS_L1, // 肖 + 0x83D6, KANJI_SJIS_L1, // 菖 + 0x848B, KANJI_SJIS_L1, // 蒋 + 0x8549, KANJI_SJIS_L1, // 蕉 + 0x885D, KANJI_SJIS_L1, // 衝 + 0x88F3, KANJI_SJIS_L1, // 裳 + 0x8A1F, KANJI_SJIS_L1, // 蚟 + 0x8A3C, KANJI_SJIS_L1, // 蚌 + 0x8A54, KANJI_SJIS_L1, // 詔 + 0x8A73, KANJI_SJIS_L1, // 詳 + 0x8C61, KANJI_SJIS_L1, // 象 + 0x8CDE, KANJI_SJIS_L1, // 賞 + 0x91A4, KANJI_SJIS_L1, // 醀 + 0x9266, KANJI_SJIS_L1, // 鉩 + 0x937E, KANJI_SJIS_L1, // 鍟 + 0x9418, KANJI_SJIS_L1, // 鐘 + 0x969C, KANJI_SJIS_L1, // 障 + 0x9798, KANJI_SJIS_L1, // 鞘 + 0x4E0A, KANJI_SJIS_L1, // 侊 + 0x4E08, KANJI_SJIS_L1, // 䞈 + 0x4E1E, KANJI_SJIS_L1, // 侞 + 0x4E57, KANJI_SJIS_L1, // 乗 + 0x5197, KANJI_SJIS_L1, // 冗 + 0x5270, KANJI_SJIS_L1, // 剰 + 0x57CE, KANJI_SJIS_L1, // 城 + 0x5834, KANJI_SJIS_L1, // å Ž + 0x58CC, KANJI_SJIS_L1, // 壌 + 0x5B22, KANJI_SJIS_L1, // 嬢 + 0x5E38, KANJI_SJIS_L1, // åžž + 0x60C5, KANJI_SJIS_L1, // 情 + 0x64FE, KANJI_SJIS_L1, // 擟 + 0x6761, KANJI_SJIS_L1, // 条 + 0x6756, KANJI_SJIS_L1, // 杖 + 0x6D44, KANJI_SJIS_L1, // 浄 + 0x72B6, KANJI_SJIS_L1, // 状 + 0x7573, KANJI_SJIS_L1, // 畳 + 0x7A63, KANJI_SJIS_L1, // ç©£ + 0x84B8, KANJI_SJIS_L1, // è’ž + 0x8B72, KANJI_SJIS_L1, // è­² + 0x91B8, KANJI_SJIS_L1, // 醾 + 0x9320, KANJI_SJIS_L1, // 錠 + 0x5631, KANJI_SJIS_L1, // 嘱 + 0x57F4, KANJI_SJIS_L1, // 城 + 0x98FE, KANJI_SJIS_L1, // 食 + 0x62ED, KANJI_SJIS_L1, // 拭 + 0x690D, KANJI_SJIS_L1, // 怍 + 0x6B96, KANJI_SJIS_L1, // 殖 + 0x71ED, KANJI_SJIS_L1, // 燭 + 0x7E54, KANJI_SJIS_L1, // 織 + 0x8077, KANJI_SJIS_L1, // 職 + 0x8272, KANJI_SJIS_L1, // 色 + 0x89E6, KANJI_SJIS_L1, // è§Š + 0x98DF, KANJI_SJIS_L1, // 食 + 0x8755, KANJI_SJIS_L1, // 蝕 + 0x8FB1, KANJI_SJIS_L1, // 蟱 + 0x5C3B, KANJI_SJIS_L1, // å°» + 0x4F38, KANJI_SJIS_L1, // 䌞 + 0x4FE1, KANJI_SJIS_L1, // ä¿¡ + 0x4FB5, KANJI_SJIS_L1, // 䟵 + 0x5507, KANJI_SJIS_L1, // 唇 + 0x5A20, KANJI_SJIS_L1, // åš  + 0x5BDD, KANJI_SJIS_L1, // 寝 + 0x5BE9, KANJI_SJIS_L1, // 審 + 0x5FC3, KANJI_SJIS_L1, // 心 + 0x614E, KANJI_SJIS_L1, // 慎 + 0x632F, KANJI_SJIS_L1, // 振 + 0x65B0, KANJI_SJIS_L1, // 新 + 0x664B, KANJI_SJIS_L1, // 晋 + 0x68EE, KANJI_SJIS_L1, // 森 + 0x699B, KANJI_SJIS_L1, // 抛 + 0x6D78, KANJI_SJIS_L1, // 浞 + 0x6DF1, KANJI_SJIS_L1, // æ·± + 0x7533, KANJI_SJIS_L1, // 申 + 0x75B9, KANJI_SJIS_L1, // 疹 + 0x771F, KANJI_SJIS_L1, // 真 + 0x795E, KANJI_SJIS_L1, // 神 + 0x79E6, KANJI_SJIS_L1, // ç§Š + 0x7D33, KANJI_SJIS_L1, // 玳 + 0x81E3, KANJI_SJIS_L1, // 臣 + 0x82AF, KANJI_SJIS_L1, // 芯 + 0x85AA, KANJI_SJIS_L1, // 薪 + 0x89AA, KANJI_SJIS_L1, // 芪 + 0x8A3A, KANJI_SJIS_L1, // 蚺 + 0x8EAB, KANJI_SJIS_L1, // 身 + 0x8F9B, KANJI_SJIS_L1, // 蟛 + 0x9032, KANJI_SJIS_L1, // 進 + 0x91DD, KANJI_SJIS_L1, // 針 + 0x9707, KANJI_SJIS_L1, // 震 + 0x4EBA, KANJI_SJIS_L1, // 人 + 0x4EC1, KANJI_SJIS_L1, // 仁 + 0x5203, KANJI_SJIS_L1, // 刃 + 0x5875, KANJI_SJIS_L1, // 塵 + 0x58EC, KANJI_SJIS_L1, // 壬 + 0x5C0B, KANJI_SJIS_L1, // 尋 + 0x751A, KANJI_SJIS_L1, // 甚 + 0x5C3D, KANJI_SJIS_L1, // å°œ + 0x814E, KANJI_SJIS_L1, // 腎 + 0x8A0A, KANJI_SJIS_L1, // 蚊 + 0x8FC5, KANJI_SJIS_L1, // 迅 + 0x9663, KANJI_SJIS_L1, // 陣 + 0x976D, KANJI_SJIS_L1, // 靭 + 0x7B25, KANJI_SJIS_L1, // 笥 + 0x8ACF, KANJI_SJIS_L1, // 諏 + 0x9808, KANJI_SJIS_L1, // 須 + 0x9162, KANJI_SJIS_L1, // 酢 + 0x56F3, KANJI_SJIS_L1, // 図 + 0x53A8, KANJI_SJIS_L1, // 厚 + 0x3000, KANJI_SJIS_L1, //   + 0x9017, KANJI_SJIS_L1, // 逗 + 0x5439, KANJI_SJIS_L1, // 吹 + 0x5782, KANJI_SJIS_L1, // 垂 + 0x5E25, KANJI_SJIS_L1, // 垥 + 0x63A8, KANJI_SJIS_L1, // 掚 + 0x6C34, KANJI_SJIS_L1, // æ°Ž + 0x708A, KANJI_SJIS_L1, // 炊 + 0x7761, KANJI_SJIS_L1, // 睡 + 0x7C8B, KANJI_SJIS_L1, // 粋 + 0x7FE0, KANJI_SJIS_L1, // ç¿  + 0x8870, KANJI_SJIS_L1, // è¡° + 0x9042, KANJI_SJIS_L1, // 遂 + 0x9154, KANJI_SJIS_L1, // 酔 + 0x9310, KANJI_SJIS_L1, // 錐 + 0x9318, KANJI_SJIS_L1, // 錘 + 0x968F, KANJI_SJIS_L1, // 随 + 0x745E, KANJI_SJIS_L1, // 瑞 + 0x9AC4, KANJI_SJIS_L1, // 髄 + 0x5D07, KANJI_SJIS_L1, // 厇 + 0x5D69, KANJI_SJIS_L1, // 嵩 + 0x6570, KANJI_SJIS_L1, // 数 + 0x67A2, KANJI_SJIS_L1, // 枢 + 0x8DA8, KANJI_SJIS_L1, // è¶š + 0x96DB, KANJI_SJIS_L1, // 雛 + 0x636E, KANJI_SJIS_L1, // 据 + 0x6749, KANJI_SJIS_L1, // 杉 + 0x6919, KANJI_SJIS_L1, // 怙 + 0x83C5, KANJI_SJIS_L1, // 菅 + 0x9817, KANJI_SJIS_L1, // 頗 + 0x96C0, KANJI_SJIS_L1, // 雀 + 0x88FE, KANJI_SJIS_L1, // 裟 + 0x6F84, KANJI_SJIS_L1, // 柄 + 0x647A, KANJI_SJIS_L1, // 摺 + 0x5BF8, KANJI_SJIS_L1, // 寞 + 0x4E16, KANJI_SJIS_L1, // 侖 + 0x702C, KANJI_SJIS_L1, // 瀬 + 0x755D, KANJI_SJIS_L1, // 畝 + 0x662F, KANJI_SJIS_L1, // 是 + 0x51C4, KANJI_SJIS_L1, // 凄 + 0x5236, KANJI_SJIS_L1, // 制 + 0x52E2, KANJI_SJIS_L1, // 勢 + 0x59D3, KANJI_SJIS_L1, // 姓 + 0x5F81, KANJI_SJIS_L1, // 埁 + 0x6027, KANJI_SJIS_L1, // 性 + 0x6210, KANJI_SJIS_L1, // 成 + 0x653F, KANJI_SJIS_L1, // 政 + 0x6574, KANJI_SJIS_L1, // 敎 + 0x661F, KANJI_SJIS_L1, // 星 + 0x6674, KANJI_SJIS_L1, // 晎 + 0x68F2, KANJI_SJIS_L1, // 棲 + 0x6816, KANJI_SJIS_L1, // 栖 + 0x6B63, KANJI_SJIS_L1, // æ­£ + 0x6E05, KANJI_SJIS_L1, // æž… + 0x7272, KANJI_SJIS_L1, // 牲 + 0x751F, KANJI_SJIS_L1, // 生 + 0x76DB, KANJI_SJIS_L1, // 盛 + 0x7CBE, KANJI_SJIS_L1, // 粟 + 0x8056, KANJI_SJIS_L1, // 聖 + 0x58F0, KANJI_SJIS_L1, // 声 + 0x88FD, KANJI_SJIS_L1, // 補 + 0x897F, KANJI_SJIS_L1, // 西 + 0x8AA0, KANJI_SJIS_L1, // 誠 + 0x8A93, KANJI_SJIS_L1, // 誓 + 0x8ACB, KANJI_SJIS_L1, // 請 + 0x901D, KANJI_SJIS_L1, // 逝 + 0x9192, KANJI_SJIS_L1, // 醒 + 0x9752, KANJI_SJIS_L1, // 青 + 0x9759, KANJI_SJIS_L1, // 静 + 0x6589, KANJI_SJIS_L1, // 斉 + 0x7A0E, KANJI_SJIS_L1, // 皎 + 0x8106, KANJI_SJIS_L1, // 脆 + 0x96BB, KANJI_SJIS_L1, // 隻 + 0x5E2D, KANJI_SJIS_L1, // åž­ + 0x60DC, KANJI_SJIS_L1, // 惜 + 0x621A, KANJI_SJIS_L1, // 戚 + 0x65A5, KANJI_SJIS_L1, // 斥 + 0x6614, KANJI_SJIS_L1, // 昔 + 0x6790, KANJI_SJIS_L1, // 析 + 0x77F3, KANJI_SJIS_L1, // 石 + 0x7A4D, KANJI_SJIS_L1, // 積 + 0x7C4D, KANJI_SJIS_L1, // 籍 + 0x7E3E, KANJI_SJIS_L1, // 瞟 + 0x810A, KANJI_SJIS_L1, // 脊 + 0x8CAC, KANJI_SJIS_L1, // 責 + 0x8D64, KANJI_SJIS_L1, // èµ€ + 0x8DE1, KANJI_SJIS_L1, // è·¡ + 0x8E5F, KANJI_SJIS_L1, // 蹟 + 0x78A9, KANJI_SJIS_L1, // 碩 + 0x5207, KANJI_SJIS_L1, // 切 + 0x62D9, KANJI_SJIS_L1, // 拙 + 0x63A5, KANJI_SJIS_L1, // 接 + 0x6442, KANJI_SJIS_L1, // 摂 + 0x6298, KANJI_SJIS_L1, // 折 + 0x8A2D, KANJI_SJIS_L1, // èš­ + 0x7A83, KANJI_SJIS_L1, // 窃 + 0x7BC0, KANJI_SJIS_L1, // 節 + 0x8AAC, KANJI_SJIS_L1, // 説 + 0x96EA, KANJI_SJIS_L1, // 雪 + 0x7D76, KANJI_SJIS_L1, // çµ¶ + 0x820C, KANJI_SJIS_L1, // 舌 + 0x8749, KANJI_SJIS_L1, // 蝉 + 0x4ED9, KANJI_SJIS_L1, // 仙 + 0x5148, KANJI_SJIS_L1, // 先 + 0x5343, KANJI_SJIS_L1, // 千 + 0x5360, KANJI_SJIS_L1, // 占 + 0x5BA3, KANJI_SJIS_L1, // 宣 + 0x5C02, KANJI_SJIS_L1, // 専 + 0x5C16, KANJI_SJIS_L1, // 尖 + 0x5DDD, KANJI_SJIS_L1, // 川 + 0x6226, KANJI_SJIS_L1, // 戊 + 0x6247, KANJI_SJIS_L1, // 扇 + 0x64B0, KANJI_SJIS_L1, // 撰 + 0x6813, KANJI_SJIS_L1, // 栓 + 0x6834, KANJI_SJIS_L1, // æ Ž + 0x6CC9, KANJI_SJIS_L1, // 泉 + 0x6D45, KANJI_SJIS_L1, // 浅 + 0x6D17, KANJI_SJIS_L1, // 掗 + 0x67D3, KANJI_SJIS_L1, // 染 + 0x6F5C, KANJI_SJIS_L1, // 朜 + 0x714E, KANJI_SJIS_L1, // 煎 + 0x717D, KANJI_SJIS_L1, // ç…œ + 0x65CB, KANJI_SJIS_L1, // 旋 + 0x7A7F, KANJI_SJIS_L1, // ç©¿ + 0x7BAD, KANJI_SJIS_L1, // ç®­ + 0x7DDA, KANJI_SJIS_L1, // 線 + 0x7E4A, KANJI_SJIS_L1, // 繊 + 0x7FA8, KANJI_SJIS_L1, // 矚 + 0x817A, KANJI_SJIS_L1, // 腺 + 0x821B, KANJI_SJIS_L1, // 舛 + 0x8239, KANJI_SJIS_L1, // 船 + 0x85A6, KANJI_SJIS_L1, // è–Š + 0x8A6E, KANJI_SJIS_L1, // è©® + 0x8CCE, KANJI_SJIS_L1, // 賎 + 0x8DF5, KANJI_SJIS_L1, // è·µ + 0x9078, KANJI_SJIS_L1, // 遞 + 0x9077, KANJI_SJIS_L1, // 遷 + 0x92AD, KANJI_SJIS_L1, // 銭 + 0x9291, KANJI_SJIS_L1, // 銑 + 0x9583, KANJI_SJIS_L1, // 閃 + 0x9BAE, KANJI_SJIS_L1, // é®® + 0x524D, KANJI_SJIS_L1, // 前 + 0x5584, KANJI_SJIS_L1, // 善 + 0x6F38, KANJI_SJIS_L1, // 挞 + 0x7136, KANJI_SJIS_L1, // 然 + 0x5168, KANJI_SJIS_L1, // å…š + 0x7985, KANJI_SJIS_L1, // 穅 + 0x7E55, KANJI_SJIS_L1, // 繕 + 0x81B3, KANJI_SJIS_L1, // 膳 + 0x7CCE, KANJI_SJIS_L1, // 糎 + 0x564C, KANJI_SJIS_L1, // 噌 + 0x5851, KANJI_SJIS_L1, // 塑 + 0x5CA8, KANJI_SJIS_L1, // 岚 + 0x63AA, KANJI_SJIS_L1, // 措 + 0x66FE, KANJI_SJIS_L1, // 曟 + 0x66FD, KANJI_SJIS_L1, // 曜 + 0x695A, KANJI_SJIS_L1, // 楚 + 0x72D9, KANJI_SJIS_L1, // 狙 + 0x758F, KANJI_SJIS_L1, // 疏 + 0x758E, KANJI_SJIS_L1, // 疎 + 0x790E, KANJI_SJIS_L1, // 瀎 + 0x7956, KANJI_SJIS_L1, // 祖 + 0x79DF, KANJI_SJIS_L1, // 租 + 0x7C97, KANJI_SJIS_L1, // 粗 + 0x7D20, KANJI_SJIS_L1, // 玠 + 0x7D44, KANJI_SJIS_L1, // 組 + 0x8607, KANJI_SJIS_L1, // 蘇 + 0x8A34, KANJI_SJIS_L1, // 蚎 + 0x963B, KANJI_SJIS_L1, // 阻 + 0x9061, KANJI_SJIS_L1, // 遡 + 0x9F20, KANJI_SJIS_L1, // 錠 + 0x50E7, KANJI_SJIS_L1, // 僧 + 0x5275, KANJI_SJIS_L1, // 創 + 0x53CC, KANJI_SJIS_L1, // 双 + 0x53E2, KANJI_SJIS_L1, // 叢 + 0x5009, KANJI_SJIS_L1, // 倉 + 0x55AA, KANJI_SJIS_L1, // 喪 + 0x58EE, KANJI_SJIS_L1, // 壮 + 0x594F, KANJI_SJIS_L1, // 奏 + 0x723D, KANJI_SJIS_L1, // 爜 + 0x5B8B, KANJI_SJIS_L1, // 宋 + 0x5C64, KANJI_SJIS_L1, // å±€ + 0x531D, KANJI_SJIS_L1, // 匝 + 0x60E3, KANJI_SJIS_L1, // 惣 + 0x60F3, KANJI_SJIS_L1, // 想 + 0x635C, KANJI_SJIS_L1, // 捜 + 0x6383, KANJI_SJIS_L1, // 掃 + 0x633F, KANJI_SJIS_L1, // 挿 + 0x63BB, KANJI_SJIS_L1, // 掻 + 0x3000, KANJI_SJIS_L1, //   + 0x64CD, KANJI_SJIS_L1, // 操 + 0x65E9, KANJI_SJIS_L1, // 早 + 0x66F9, KANJI_SJIS_L1, // 曹 + 0x5DE3, KANJI_SJIS_L1, // å·£ + 0x69CD, KANJI_SJIS_L1, // 槍 + 0x69FD, KANJI_SJIS_L1, // æ§œ + 0x6F15, KANJI_SJIS_L1, // 挕 + 0x71E5, KANJI_SJIS_L1, // 燥 + 0x4E89, KANJI_SJIS_L1, // 争 + 0x75E9, KANJI_SJIS_L1, // 痩 + 0x76F8, KANJI_SJIS_L1, // 盾 + 0x7A93, KANJI_SJIS_L1, // 窓 + 0x7CDF, KANJI_SJIS_L1, // 糟 + 0x7DCF, KANJI_SJIS_L1, // 総 + 0x7D9C, KANJI_SJIS_L1, // 綜 + 0x8061, KANJI_SJIS_L1, // 聡 + 0x8349, KANJI_SJIS_L1, // 草 + 0x8358, KANJI_SJIS_L1, // 荘 + 0x846C, KANJI_SJIS_L1, // 葬 + 0x84BC, KANJI_SJIS_L1, // è’Œ + 0x85FB, KANJI_SJIS_L1, // 藻 + 0x88C5, KANJI_SJIS_L1, // 装 + 0x8D70, KANJI_SJIS_L1, // èµ° + 0x9001, KANJI_SJIS_L1, // 送 + 0x906D, KANJI_SJIS_L1, // 遭 + 0x9397, KANJI_SJIS_L1, // 鎗 + 0x971C, KANJI_SJIS_L1, // 霜 + 0x9A12, KANJI_SJIS_L1, // 鹒 + 0x50CF, KANJI_SJIS_L1, // 像 + 0x5897, KANJI_SJIS_L1, // 増 + 0x618E, KANJI_SJIS_L1, // 憎 + 0x81D3, KANJI_SJIS_L1, // 臓 + 0x8535, KANJI_SJIS_L1, // 蔵 + 0x8D08, KANJI_SJIS_L1, // 莈 + 0x9020, KANJI_SJIS_L1, // 造 + 0x4FC3, KANJI_SJIS_L1, // 促 + 0x5074, KANJI_SJIS_L1, // 偎 + 0x5247, KANJI_SJIS_L1, // 則 + 0x5373, KANJI_SJIS_L1, // 即 + 0x606F, KANJI_SJIS_L1, // 息 + 0x6349, KANJI_SJIS_L1, // 捉 + 0x675F, KANJI_SJIS_L1, // 束 + 0x6E2C, KANJI_SJIS_L1, // 枬 + 0x8DB3, KANJI_SJIS_L1, // è¶³ + 0x901F, KANJI_SJIS_L1, // 速 + 0x4FD7, KANJI_SJIS_L1, // 俗 + 0x5C5E, KANJI_SJIS_L1, // 属 + 0x8CCA, KANJI_SJIS_L1, // 賊 + 0x65CF, KANJI_SJIS_L1, // 族 + 0x7D9A, KANJI_SJIS_L1, // 続 + 0x5352, KANJI_SJIS_L1, // 卒 + 0x8896, KANJI_SJIS_L1, // 袖 + 0x5176, KANJI_SJIS_L1, // 其 + 0x63C3, KANJI_SJIS_L1, // 揃 + 0x5B58, KANJI_SJIS_L1, // 存 + 0x5B6B, KANJI_SJIS_L1, // å­« + 0x5C0A, KANJI_SJIS_L1, // 尊 + 0x640D, KANJI_SJIS_L1, // 損 + 0x6751, KANJI_SJIS_L1, // 村 + 0x905C, KANJI_SJIS_L1, // 遜 + 0x4ED6, KANJI_SJIS_L1, // 他 + 0x591A, KANJI_SJIS_L1, // 倚 + 0x592A, KANJI_SJIS_L1, // 倪 + 0x6C70, KANJI_SJIS_L1, // æ±° + 0x8A51, KANJI_SJIS_L1, // 詑 + 0x553E, KANJI_SJIS_L1, // 唟 + 0x5815, KANJI_SJIS_L1, // 堕 + 0x59A5, KANJI_SJIS_L1, // 劥 + 0x60F0, KANJI_SJIS_L1, // 惰 + 0x6253, KANJI_SJIS_L1, // 打 + 0x67C1, KANJI_SJIS_L1, // 柁 + 0x8235, KANJI_SJIS_L1, // 舵 + 0x6955, KANJI_SJIS_L1, // 楕 + 0x9640, KANJI_SJIS_L1, // 陀 + 0x99C4, KANJI_SJIS_L1, // 駄 + 0x9A28, KANJI_SJIS_L1, // éšš + 0x4F53, KANJI_SJIS_L1, // 䜓 + 0x5806, KANJI_SJIS_L1, // 堆 + 0x5BFE, KANJI_SJIS_L1, // 察 + 0x8010, KANJI_SJIS_L1, // 耐 + 0x5CB1, KANJI_SJIS_L1, // å²± + 0x5E2F, KANJI_SJIS_L1, // 垯 + 0x5F85, KANJI_SJIS_L1, // 埅 + 0x6020, KANJI_SJIS_L1, // 怠 + 0x614B, KANJI_SJIS_L1, // 態 + 0x6234, KANJI_SJIS_L1, // 戎 + 0x66FF, KANJI_SJIS_L1, // 替 + 0x6CF0, KANJI_SJIS_L1, // æ³° + 0x6EDE, KANJI_SJIS_L1, // 滞 + 0x80CE, KANJI_SJIS_L1, // 胎 + 0x817F, KANJI_SJIS_L1, // 腿 + 0x82D4, KANJI_SJIS_L1, // 苔 + 0x888B, KANJI_SJIS_L1, // 袋 + 0x8CB8, KANJI_SJIS_L1, // 貞 + 0x9000, KANJI_SJIS_L1, // 退 + 0x902E, KANJI_SJIS_L1, // 逮 + 0x968A, KANJI_SJIS_L1, // 隊 + 0x9EDB, KANJI_SJIS_L1, // 黛 + 0x9BDB, KANJI_SJIS_L1, // 鯛 + 0x4EE3, KANJI_SJIS_L1, // 代 + 0x53F0, KANJI_SJIS_L1, // 台 + 0x5927, KANJI_SJIS_L1, // 倧 + 0x7B2C, KANJI_SJIS_L1, // 第 + 0x918D, KANJI_SJIS_L1, // 醍 + 0x984C, KANJI_SJIS_L1, // 題 + 0x9DF9, KANJI_SJIS_L1, // é·¹ + 0x6EDD, KANJI_SJIS_L1, // 滝 + 0x7027, KANJI_SJIS_L1, // 瀧 + 0x5353, KANJI_SJIS_L1, // 卓 + 0x5544, KANJI_SJIS_L1, // 啄 + 0x5B85, KANJI_SJIS_L1, // 宅 + 0x6258, KANJI_SJIS_L1, // 托 + 0x629E, KANJI_SJIS_L1, // 択 + 0x62D3, KANJI_SJIS_L1, // 拓 + 0x6CA2, KANJI_SJIS_L1, // æ²¢ + 0x6FEF, KANJI_SJIS_L1, // 濯 + 0x7422, KANJI_SJIS_L1, // 琢 + 0x8A17, KANJI_SJIS_L1, // èš— + 0x9438, KANJI_SJIS_L1, // 鐞 + 0x6FC1, KANJI_SJIS_L1, // 濁 + 0x8AFE, KANJI_SJIS_L1, // 諟 + 0x8338, KANJI_SJIS_L1, // 茞 + 0x51E7, KANJI_SJIS_L1, // 凧 + 0x86F8, KANJI_SJIS_L1, // 蛞 + 0x53EA, KANJI_SJIS_L1, // 只 + 0x53E9, KANJI_SJIS_L1, // 叩 + 0x4F46, KANJI_SJIS_L1, // 䜆 + 0x9054, KANJI_SJIS_L1, // 達 + 0x8FB0, KANJI_SJIS_L1, // 蟰 + 0x596A, KANJI_SJIS_L1, // 奪 + 0x8131, KANJI_SJIS_L1, // 脱 + 0x5DFD, KANJI_SJIS_L1, // å·œ + 0x7AEA, KANJI_SJIS_L1, // 竪 + 0x8FBF, KANJI_SJIS_L1, // 蟿 + 0x68DA, KANJI_SJIS_L1, // 棚 + 0x8C37, KANJI_SJIS_L1, // è°· + 0x72F8, KANJI_SJIS_L1, // 狾 + 0x9C48, KANJI_SJIS_L1, // 鱈 + 0x6A3D, KANJI_SJIS_L1, // æšœ + 0x8AB0, KANJI_SJIS_L1, // 誰 + 0x4E39, KANJI_SJIS_L1, // äž¹ + 0x5358, KANJI_SJIS_L1, // 単 + 0x5606, KANJI_SJIS_L1, // 嘆 + 0x5766, KANJI_SJIS_L1, // 坊 + 0x62C5, KANJI_SJIS_L1, // 担 + 0x63A2, KANJI_SJIS_L1, // 探 + 0x65E6, KANJI_SJIS_L1, // æ—Š + 0x6B4E, KANJI_SJIS_L1, // 歎 + 0x6DE1, KANJI_SJIS_L1, // æ·¡ + 0x6E5B, KANJI_SJIS_L1, // 湛 + 0x70AD, KANJI_SJIS_L1, // 炭 + 0x77ED, KANJI_SJIS_L1, // 短 + 0x7AEF, KANJI_SJIS_L1, // 端 + 0x7BAA, KANJI_SJIS_L1, // 箪 + 0x7DBB, KANJI_SJIS_L1, // ç¶» + 0x803D, KANJI_SJIS_L1, // 耜 + 0x80C6, KANJI_SJIS_L1, // 胆 + 0x86CB, KANJI_SJIS_L1, // 蛋 + 0x8A95, KANJI_SJIS_L1, // 誕 + 0x935B, KANJI_SJIS_L1, // 鍛 + 0x56E3, KANJI_SJIS_L1, // 団 + 0x58C7, KANJI_SJIS_L1, // 壇 + 0x5F3E, KANJI_SJIS_L1, // 匟 + 0x65AD, KANJI_SJIS_L1, // 断 + 0x6696, KANJI_SJIS_L1, // 暖 + 0x6A80, KANJI_SJIS_L1, // 檀 + 0x6BB5, KANJI_SJIS_L1, // 段 + 0x7537, KANJI_SJIS_L1, // 男 + 0x8AC7, KANJI_SJIS_L1, // 談 + 0x5024, KANJI_SJIS_L1, // 倀 + 0x77E5, KANJI_SJIS_L1, // 知 + 0x5730, KANJI_SJIS_L1, // 地 + 0x5F1B, KANJI_SJIS_L1, // 匛 + 0x6065, KANJI_SJIS_L1, // 恥 + 0x667A, KANJI_SJIS_L1, // 智 + 0x6C60, KANJI_SJIS_L1, // æ±  + 0x75F4, KANJI_SJIS_L1, // 痮 + 0x7A1A, KANJI_SJIS_L1, // 繚 + 0x7F6E, KANJI_SJIS_L1, // 眮 + 0x81F4, KANJI_SJIS_L1, // 臎 + 0x8718, KANJI_SJIS_L1, // 蜘 + 0x9045, KANJI_SJIS_L1, // 遅 + 0x99B3, KANJI_SJIS_L1, // 銳 + 0x7BC9, KANJI_SJIS_L1, // 築 + 0x755C, KANJI_SJIS_L1, // 畜 + 0x7AF9, KANJI_SJIS_L1, // 竹 + 0x7B51, KANJI_SJIS_L1, // 筑 + 0x84C4, KANJI_SJIS_L1, // 蓄 + 0x3000, KANJI_SJIS_L1, //   + 0x9010, KANJI_SJIS_L1, // 逐 + 0x79E9, KANJI_SJIS_L1, // ç§© + 0x7A92, KANJI_SJIS_L1, // 窒 + 0x8336, KANJI_SJIS_L1, // 茶 + 0x5AE1, KANJI_SJIS_L1, // å«¡ + 0x7740, KANJI_SJIS_L1, // 着 + 0x4E2D, KANJI_SJIS_L1, // äž­ + 0x4EF2, KANJI_SJIS_L1, // 仲 + 0x5B99, KANJI_SJIS_L1, // 宙 + 0x5FE0, KANJI_SJIS_L1, // å¿  + 0x62BD, KANJI_SJIS_L1, // 抜 + 0x663C, KANJI_SJIS_L1, // 昌 + 0x67F1, KANJI_SJIS_L1, // 柱 + 0x6CE8, KANJI_SJIS_L1, // 泚 + 0x866B, KANJI_SJIS_L1, // 虫 + 0x8877, KANJI_SJIS_L1, // è¡· + 0x8A3B, KANJI_SJIS_L1, // èš» + 0x914E, KANJI_SJIS_L1, // 酎 + 0x92F3, KANJI_SJIS_L1, // 鋳 + 0x99D0, KANJI_SJIS_L1, // 駐 + 0x6A17, KANJI_SJIS_L1, // æš— + 0x7026, KANJI_SJIS_L1, // 瀩 + 0x732A, KANJI_SJIS_L1, // 猪 + 0x82E7, KANJI_SJIS_L1, // 苧 + 0x8457, KANJI_SJIS_L1, // 著 + 0x8CAF, KANJI_SJIS_L1, // 貯 + 0x4E01, KANJI_SJIS_L1, // 䞁 + 0x5146, KANJI_SJIS_L1, // 兆 + 0x51CB, KANJI_SJIS_L1, // 凋 + 0x558B, KANJI_SJIS_L1, // 喋 + 0x5BF5, KANJI_SJIS_L1, // 寵 + 0x5E16, KANJI_SJIS_L1, // åž– + 0x5E33, KANJI_SJIS_L1, // åž³ + 0x5E81, KANJI_SJIS_L1, // 庁 + 0x5F14, KANJI_SJIS_L1, // 匔 + 0x5F35, KANJI_SJIS_L1, // 匵 + 0x5F6B, KANJI_SJIS_L1, // 圫 + 0x5FB4, KANJI_SJIS_L1, // 城 + 0x61F2, KANJI_SJIS_L1, // 懲 + 0x6311, KANJI_SJIS_L1, // 挑 + 0x66A2, KANJI_SJIS_L1, // 暢 + 0x671D, KANJI_SJIS_L1, // 朝 + 0x6F6E, KANJI_SJIS_L1, // 朮 + 0x7252, KANJI_SJIS_L1, // 牒 + 0x753A, KANJI_SJIS_L1, // 町 + 0x773A, KANJI_SJIS_L1, // 眺 + 0x8074, KANJI_SJIS_L1, // 聎 + 0x8139, KANJI_SJIS_L1, // 脹 + 0x8178, KANJI_SJIS_L1, // è…ž + 0x8776, KANJI_SJIS_L1, // 蝶 + 0x8ABF, KANJI_SJIS_L1, // 調 + 0x8ADC, KANJI_SJIS_L1, // 諜 + 0x8D85, KANJI_SJIS_L1, // 超 + 0x8DF3, KANJI_SJIS_L1, // è·³ + 0x929A, KANJI_SJIS_L1, // 銚 + 0x9577, KANJI_SJIS_L1, // 長 + 0x9802, KANJI_SJIS_L1, // 頂 + 0x9CE5, KANJI_SJIS_L1, // é³¥ + 0x52C5, KANJI_SJIS_L1, // 勅 + 0x6357, KANJI_SJIS_L1, // 捗 + 0x76F4, KANJI_SJIS_L1, // 目 + 0x6715, KANJI_SJIS_L1, // 朕 + 0x6C88, KANJI_SJIS_L1, // 沈 + 0x73CD, KANJI_SJIS_L1, // 珍 + 0x8CC3, KANJI_SJIS_L1, // 賃 + 0x93AE, KANJI_SJIS_L1, // 鎮 + 0x9673, KANJI_SJIS_L1, // 陳 + 0x6D25, KANJI_SJIS_L1, // 接 + 0x589C, KANJI_SJIS_L1, // 墜 + 0x690E, KANJI_SJIS_L1, // 怎 + 0x69CC, KANJI_SJIS_L1, // 槌 + 0x8FFD, KANJI_SJIS_L1, // 远 + 0x939A, KANJI_SJIS_L1, // 鎚 + 0x75DB, KANJI_SJIS_L1, // 痛 + 0x901A, KANJI_SJIS_L1, // 通 + 0x585A, KANJI_SJIS_L1, // 塚 + 0x6802, KANJI_SJIS_L1, // 栂 + 0x63B4, KANJI_SJIS_L1, // 掎 + 0x69FB, KANJI_SJIS_L1, // æ§» + 0x4F43, KANJI_SJIS_L1, // 䜃 + 0x6F2C, KANJI_SJIS_L1, // 挬 + 0x67D8, KANJI_SJIS_L1, // 柘 + 0x8FBB, KANJI_SJIS_L1, // 蟻 + 0x8526, KANJI_SJIS_L1, // 蔊 + 0x7DB4, KANJI_SJIS_L1, // ç¶Ž + 0x9354, KANJI_SJIS_L1, // 鍔 + 0x693F, KANJI_SJIS_L1, // 怿 + 0x6F70, KANJI_SJIS_L1, // 朰 + 0x576A, KANJI_SJIS_L1, // 坪 + 0x58F7, KANJI_SJIS_L1, // 壷 + 0x5B2C, KANJI_SJIS_L1, // 嬬 + 0x7D2C, KANJI_SJIS_L1, // 玬 + 0x722A, KANJI_SJIS_L1, // 爪 + 0x540A, KANJI_SJIS_L1, // 吊 + 0x91E3, KANJI_SJIS_L1, // 釣 + 0x9DB4, KANJI_SJIS_L1, // é¶Ž + 0x4EAD, KANJI_SJIS_L1, // 亭 + 0x4F4E, KANJI_SJIS_L1, // 䜎 + 0x505C, KANJI_SJIS_L1, // 停 + 0x5075, KANJI_SJIS_L1, // 偵 + 0x5243, KANJI_SJIS_L1, // 剃 + 0x8C9E, KANJI_SJIS_L1, // 貞 + 0x5448, KANJI_SJIS_L1, // 呈 + 0x5824, KANJI_SJIS_L1, // å € + 0x5B9A, KANJI_SJIS_L1, // 定 + 0x5E1D, KANJI_SJIS_L1, // 垝 + 0x5E95, KANJI_SJIS_L1, // 底 + 0x5EAD, KANJI_SJIS_L1, // 庭 + 0x5EF7, KANJI_SJIS_L1, // å»· + 0x5F1F, KANJI_SJIS_L1, // 匟 + 0x608C, KANJI_SJIS_L1, // 悌 + 0x62B5, KANJI_SJIS_L1, // 抵 + 0x633A, KANJI_SJIS_L1, // 挺 + 0x63D0, KANJI_SJIS_L1, // 提 + 0x68AF, KANJI_SJIS_L1, // 梯 + 0x6C40, KANJI_SJIS_L1, // 汀 + 0x7887, KANJI_SJIS_L1, // 碇 + 0x798E, KANJI_SJIS_L1, // 犎 + 0x7A0B, KANJI_SJIS_L1, // 繋 + 0x7DE0, KANJI_SJIS_L1, // ç·  + 0x8247, KANJI_SJIS_L1, // 艇 + 0x8A02, KANJI_SJIS_L1, // èš‚ + 0x8AE6, KANJI_SJIS_L1, // 諊 + 0x8E44, KANJI_SJIS_L1, // 蹄 + 0x9013, KANJI_SJIS_L1, // 逓 + 0x90B8, KANJI_SJIS_L1, // 邾 + 0x912D, KANJI_SJIS_L1, // 鄭 + 0x91D8, KANJI_SJIS_L1, // 釘 + 0x9F0E, KANJI_SJIS_L1, // 錎 + 0x6CE5, KANJI_SJIS_L1, // æ³¥ + 0x6458, KANJI_SJIS_L1, // 摘 + 0x64E2, KANJI_SJIS_L1, // 擢 + 0x6575, KANJI_SJIS_L1, // 敵 + 0x6EF4, KANJI_SJIS_L1, // 滎 + 0x7684, KANJI_SJIS_L1, // 的 + 0x7B1B, KANJI_SJIS_L1, // 笛 + 0x9069, KANJI_SJIS_L1, // 適 + 0x93D1, KANJI_SJIS_L1, // 鏑 + 0x6EBA, KANJI_SJIS_L1, // 溺 + 0x54F2, KANJI_SJIS_L1, // 哲 + 0x5FB9, KANJI_SJIS_L1, // 培 + 0x64A4, KANJI_SJIS_L1, // æ’€ + 0x8F4D, KANJI_SJIS_L1, // 蜍 + 0x8FED, KANJI_SJIS_L1, // è¿­ + 0x9244, KANJI_SJIS_L1, // 鉄 + 0x5178, KANJI_SJIS_L1, // å…ž + 0x586B, KANJI_SJIS_L1, // å¡« + 0x5929, KANJI_SJIS_L1, // 倩 + 0x5C55, KANJI_SJIS_L1, // 展 + 0x5E97, KANJI_SJIS_L1, // 店 + 0x6DFB, KANJI_SJIS_L1, // æ·» + 0x7E8F, KANJI_SJIS_L1, // 纏 + 0x751C, KANJI_SJIS_L1, // 甜 + 0x8CBC, KANJI_SJIS_L1, // 貌 + 0x8EE2, KANJI_SJIS_L1, // 転 + 0x985B, KANJI_SJIS_L1, // 顛 + 0x70B9, KANJI_SJIS_L1, // 点 + 0x4F1D, KANJI_SJIS_L1, // 䌝 + 0x6BBF, KANJI_SJIS_L1, // 殿 + 0x6FB1, KANJI_SJIS_L1, // 柱 + 0x7530, KANJI_SJIS_L1, // 田 + 0x96FB, KANJI_SJIS_L1, // 電 + 0x514E, KANJI_SJIS_L1, // 兎 + 0x5410, KANJI_SJIS_L1, // 吐 + 0x5835, KANJI_SJIS_L1, // å µ + 0x5857, KANJI_SJIS_L1, // 塗 + 0x59AC, KANJI_SJIS_L1, // 劬 + 0x5C60, KANJI_SJIS_L1, // å±  + 0x5F92, KANJI_SJIS_L1, // 埒 + 0x6597, KANJI_SJIS_L1, // 斗 + 0x675C, KANJI_SJIS_L1, // 杜 + 0x6E21, KANJI_SJIS_L1, // æž¡ + 0x767B, KANJI_SJIS_L1, // 登 + 0x83DF, KANJI_SJIS_L1, // 菟 + 0x8CED, KANJI_SJIS_L1, // è³­ + 0x9014, KANJI_SJIS_L1, // 途 + 0x90FD, KANJI_SJIS_L1, // 郜 + 0x934D, KANJI_SJIS_L1, // 鍍 + 0x7825, KANJI_SJIS_L1, // ç ¥ + 0x783A, KANJI_SJIS_L1, // ç º + 0x52AA, KANJI_SJIS_L1, // 努 + 0x5EA6, KANJI_SJIS_L1, // 床 + 0x571F, KANJI_SJIS_L1, // 土 + 0x5974, KANJI_SJIS_L1, // 奎 + 0x6012, KANJI_SJIS_L1, // 怒 + 0x5012, KANJI_SJIS_L1, // 倒 + 0x515A, KANJI_SJIS_L1, // 党 + 0x51AC, KANJI_SJIS_L1, // 冬 + 0x3000, KANJI_SJIS_L1, //   + 0x51CD, KANJI_SJIS_L1, // 凍 + 0x5200, KANJI_SJIS_L1, // 刀 + 0x5510, KANJI_SJIS_L1, // 唐 + 0x5854, KANJI_SJIS_L1, // 塔 + 0x5858, KANJI_SJIS_L1, // 塘 + 0x5957, KANJI_SJIS_L1, // 套 + 0x5B95, KANJI_SJIS_L1, // 宕 + 0x5CF6, KANJI_SJIS_L1, // å³¶ + 0x5D8B, KANJI_SJIS_L1, // 嶋 + 0x60BC, KANJI_SJIS_L1, // 悌 + 0x6295, KANJI_SJIS_L1, // 投 + 0x642D, KANJI_SJIS_L1, // 搭 + 0x6771, KANJI_SJIS_L1, // 東 + 0x6843, KANJI_SJIS_L1, // 桃 + 0x68BC, KANJI_SJIS_L1, // 梌 + 0x68DF, KANJI_SJIS_L1, // 棟 + 0x76D7, KANJI_SJIS_L1, // 盗 + 0x6DD8, KANJI_SJIS_L1, // 淘 + 0x6E6F, KANJI_SJIS_L1, // 湯 + 0x6D9B, KANJI_SJIS_L1, // 涛 + 0x706F, KANJI_SJIS_L1, // 灯 + 0x71C8, KANJI_SJIS_L1, // 燈 + 0x5F53, KANJI_SJIS_L1, // 圓 + 0x75D8, KANJI_SJIS_L1, // 痘 + 0x7977, KANJI_SJIS_L1, // 祷 + 0x7B49, KANJI_SJIS_L1, // 等 + 0x7B54, KANJI_SJIS_L1, // 答 + 0x7B52, KANJI_SJIS_L1, // 筒 + 0x7CD6, KANJI_SJIS_L1, // 糖 + 0x7D71, KANJI_SJIS_L1, // çµ± + 0x5230, KANJI_SJIS_L1, // 到 + 0x8463, KANJI_SJIS_L1, // 董 + 0x8569, KANJI_SJIS_L1, // 蕩 + 0x85E4, KANJI_SJIS_L1, // è—€ + 0x8A0E, KANJI_SJIS_L1, // 蚎 + 0x8B04, KANJI_SJIS_L1, // 謄 + 0x8C46, KANJI_SJIS_L1, // 豆 + 0x8E0F, KANJI_SJIS_L1, // 螏 + 0x9003, KANJI_SJIS_L1, // 逃 + 0x900F, KANJI_SJIS_L1, // 透 + 0x9419, KANJI_SJIS_L1, // 鐙 + 0x9676, KANJI_SJIS_L1, // 陶 + 0x982D, KANJI_SJIS_L1, // é ­ + 0x9A30, KANJI_SJIS_L1, // éš° + 0x95D8, KANJI_SJIS_L1, // 闘 + 0x50CD, KANJI_SJIS_L1, // 働 + 0x52D5, KANJI_SJIS_L1, // 動 + 0x540C, KANJI_SJIS_L1, // 同 + 0x5802, KANJI_SJIS_L1, // 堂 + 0x5C0E, KANJI_SJIS_L1, // 導 + 0x61A7, KANJI_SJIS_L1, // 憧 + 0x649E, KANJI_SJIS_L1, // 撞 + 0x6D1E, KANJI_SJIS_L1, // 掞 + 0x77B3, KANJI_SJIS_L1, // 瞳 + 0x7AE5, KANJI_SJIS_L1, // ç«¥ + 0x80F4, KANJI_SJIS_L1, // 胎 + 0x8404, KANJI_SJIS_L1, // 萄 + 0x9053, KANJI_SJIS_L1, // 道 + 0x9285, KANJI_SJIS_L1, // 銅 + 0x5CE0, KANJI_SJIS_L1, // å³  + 0x9D07, KANJI_SJIS_L1, // 鮇 + 0x533F, KANJI_SJIS_L1, // 匿 + 0x5F97, KANJI_SJIS_L1, // 埗 + 0x5FB3, KANJI_SJIS_L1, // 埳 + 0x6D9C, KANJI_SJIS_L1, // 涜 + 0x7279, KANJI_SJIS_L1, // 特 + 0x7763, KANJI_SJIS_L1, // 督 + 0x79BF, KANJI_SJIS_L1, // 犿 + 0x7BE4, KANJI_SJIS_L1, // 節 + 0x6BD2, KANJI_SJIS_L1, // 毒 + 0x72EC, KANJI_SJIS_L1, // 独 + 0x8AAD, KANJI_SJIS_L1, // 読 + 0x6803, KANJI_SJIS_L1, // 栃 + 0x6A61, KANJI_SJIS_L1, // æ©¡ + 0x51F8, KANJI_SJIS_L1, // 凞 + 0x7A81, KANJI_SJIS_L1, // 突 + 0x6934, KANJI_SJIS_L1, // 怎 + 0x5C4A, KANJI_SJIS_L1, // 届 + 0x9CF6, KANJI_SJIS_L1, // é³¶ + 0x82EB, KANJI_SJIS_L1, // 苫 + 0x5BC5, KANJI_SJIS_L1, // 寅 + 0x9149, KANJI_SJIS_L1, // 酉 + 0x701E, KANJI_SJIS_L1, // 瀞 + 0x5678, KANJI_SJIS_L1, // 噞 + 0x5C6F, KANJI_SJIS_L1, // 屯 + 0x60C7, KANJI_SJIS_L1, // 惇 + 0x6566, KANJI_SJIS_L1, // 敊 + 0x6C8C, KANJI_SJIS_L1, // 沌 + 0x8C5A, KANJI_SJIS_L1, // 豚 + 0x9041, KANJI_SJIS_L1, // 遁 + 0x9813, KANJI_SJIS_L1, // 頓 + 0x5451, KANJI_SJIS_L1, // 呑 + 0x66C7, KANJI_SJIS_L1, // 曇 + 0x920D, KANJI_SJIS_L1, // 鈍 + 0x5948, KANJI_SJIS_L1, // 奈 + 0x90A3, KANJI_SJIS_L1, // 那 + 0x5185, KANJI_SJIS_L1, // 内 + 0x4E4D, KANJI_SJIS_L1, // 乍 + 0x51EA, KANJI_SJIS_L1, // 凪 + 0x8599, KANJI_SJIS_L1, // 薙 + 0x8B0E, KANJI_SJIS_L1, // 謎 + 0x7058, KANJI_SJIS_L1, // 灘 + 0x637A, KANJI_SJIS_L1, // 捺 + 0x934B, KANJI_SJIS_L1, // 鍋 + 0x6962, KANJI_SJIS_L1, // 楢 + 0x99B4, KANJI_SJIS_L1, // 銎 + 0x7E04, KANJI_SJIS_L1, // 羄 + 0x7577, KANJI_SJIS_L1, // 畷 + 0x5357, KANJI_SJIS_L1, // 南 + 0x6960, KANJI_SJIS_L1, // 楠 + 0x8EDF, KANJI_SJIS_L1, // 軟 + 0x96E3, KANJI_SJIS_L1, // 難 + 0x6C5D, KANJI_SJIS_L1, // 汝 + 0x4E8C, KANJI_SJIS_L1, // 二 + 0x5C3C, KANJI_SJIS_L1, // å°Œ + 0x5F10, KANJI_SJIS_L1, // 匐 + 0x8FE9, KANJI_SJIS_L1, // è¿© + 0x5302, KANJI_SJIS_L1, // 匂 + 0x8CD1, KANJI_SJIS_L1, // 賑 + 0x8089, KANJI_SJIS_L1, // 肉 + 0x8679, KANJI_SJIS_L1, // 虹 + 0x5EFF, KANJI_SJIS_L1, // 廿 + 0x65E5, KANJI_SJIS_L1, // 日 + 0x4E73, KANJI_SJIS_L1, // ä¹³ + 0x5165, KANJI_SJIS_L1, // 入 + 0x5982, KANJI_SJIS_L1, // 劂 + 0x5C3F, KANJI_SJIS_L1, // å°¿ + 0x97EE, KANJI_SJIS_L1, // 韮 + 0x4EFB, KANJI_SJIS_L1, // ä»» + 0x598A, KANJI_SJIS_L1, // 劊 + 0x5FCD, KANJI_SJIS_L1, // 忍 + 0x8A8D, KANJI_SJIS_L1, // 認 + 0x6FE1, KANJI_SJIS_L1, // æ¿¡ + 0x79B0, KANJI_SJIS_L1, // 犰 + 0x7962, KANJI_SJIS_L1, // 祢 + 0x5BE7, KANJI_SJIS_L1, // 寧 + 0x8471, KANJI_SJIS_L1, // 葱 + 0x732B, KANJI_SJIS_L1, // 猫 + 0x71B1, KANJI_SJIS_L1, // 熱 + 0x5E74, KANJI_SJIS_L1, // 幎 + 0x5FF5, KANJI_SJIS_L1, // 念 + 0x637B, KANJI_SJIS_L1, // 捻 + 0x649A, KANJI_SJIS_L1, // 撚 + 0x71C3, KANJI_SJIS_L1, // 燃 + 0x7C98, KANJI_SJIS_L1, // 粘 + 0x4E43, KANJI_SJIS_L1, // 乃 + 0x5EFC, KANJI_SJIS_L1, // 廌 + 0x4E4B, KANJI_SJIS_L1, // 之 + 0x57DC, KANJI_SJIS_L1, // 埜 + 0x56A2, KANJI_SJIS_L1, // 嚢 + 0x60A9, KANJI_SJIS_L1, // 悩 + 0x6FC3, KANJI_SJIS_L1, // 濃 + 0x7D0D, KANJI_SJIS_L1, // 玍 + 0x80FD, KANJI_SJIS_L1, // 胜 + 0x8133, KANJI_SJIS_L1, // 脳 + 0x81BF, KANJI_SJIS_L1, // 膿 + 0x8FB2, KANJI_SJIS_L1, // 蟲 + 0x8997, KANJI_SJIS_L1, // 芗 + 0x86A4, KANJI_SJIS_L1, // 蚀 + 0x5DF4, KANJI_SJIS_L1, // å·Ž + 0x628A, KANJI_SJIS_L1, // 把 + 0x64AD, KANJI_SJIS_L1, // 播 + 0x8987, KANJI_SJIS_L1, // 芇 + 0x6777, KANJI_SJIS_L1, // 杷 + 0x6CE2, KANJI_SJIS_L1, // æ³¢ + 0x6D3E, KANJI_SJIS_L1, // 掟 + 0x7436, KANJI_SJIS_L1, // 琶 + 0x7834, KANJI_SJIS_L1, // ç Ž + 0x5A46, KANJI_SJIS_L1, // 婆 + 0x7F75, KANJI_SJIS_L1, // 眵 + 0x82AD, KANJI_SJIS_L1, // 芭 + 0x99AC, KANJI_SJIS_L1, // 銬 + 0x4FF3, KANJI_SJIS_L1, // 俳 + 0x5EC3, KANJI_SJIS_L1, // 廃 + 0x62DD, KANJI_SJIS_L1, // 拝 + 0x6392, KANJI_SJIS_L1, // 排 + 0x6557, KANJI_SJIS_L1, // 敗 + 0x676F, KANJI_SJIS_L1, // 杯 + 0x76C3, KANJI_SJIS_L1, // 盃 + 0x724C, KANJI_SJIS_L1, // 牌 + 0x80CC, KANJI_SJIS_L1, // 背 + 0x80BA, KANJI_SJIS_L1, // 肺 + 0x8F29, KANJI_SJIS_L1, // 茩 + 0x914D, KANJI_SJIS_L1, // 配 + 0x500D, KANJI_SJIS_L1, // 倍 + 0x57F9, KANJI_SJIS_L1, // 培 + 0x5A92, KANJI_SJIS_L1, // 媒 + 0x6885, KANJI_SJIS_L1, // 梅 + 0x3000, KANJI_SJIS_L1, //   + 0x6973, KANJI_SJIS_L1, // 楳 + 0x7164, KANJI_SJIS_L1, // ç…€ + 0x72FD, KANJI_SJIS_L1, // 狜 + 0x8CB7, KANJI_SJIS_L1, // è²· + 0x58F2, KANJI_SJIS_L1, // 売 + 0x8CE0, KANJI_SJIS_L1, // è³  + 0x966A, KANJI_SJIS_L1, // 陪 + 0x9019, KANJI_SJIS_L1, // 這 + 0x877F, KANJI_SJIS_L1, // 蝿 + 0x79E4, KANJI_SJIS_L1, // ç§€ + 0x77E7, KANJI_SJIS_L1, // 矧 + 0x8429, KANJI_SJIS_L1, // 萩 + 0x4F2F, KANJI_SJIS_L1, // 䌯 + 0x5265, KANJI_SJIS_L1, // 剥 + 0x535A, KANJI_SJIS_L1, // 博 + 0x62CD, KANJI_SJIS_L1, // 拍 + 0x67CF, KANJI_SJIS_L1, // 柏 + 0x6CCA, KANJI_SJIS_L1, // 泊 + 0x767D, KANJI_SJIS_L1, // 癜 + 0x7B94, KANJI_SJIS_L1, // 箔 + 0x7C95, KANJI_SJIS_L1, // 粕 + 0x8236, KANJI_SJIS_L1, // 舶 + 0x8584, KANJI_SJIS_L1, // 薄 + 0x8FEB, KANJI_SJIS_L1, // è¿« + 0x66DD, KANJI_SJIS_L1, // 曝 + 0x6F20, KANJI_SJIS_L1, // 挠 + 0x7206, KANJI_SJIS_L1, // 爆 + 0x7E1B, KANJI_SJIS_L1, // 羛 + 0x83AB, KANJI_SJIS_L1, // 莫 + 0x99C1, KANJI_SJIS_L1, // 駁 + 0x9EA6, KANJI_SJIS_L1, // 麊 + 0x51FD, KANJI_SJIS_L1, // 凜 + 0x7BB1, KANJI_SJIS_L1, // ç®± + 0x7872, KANJI_SJIS_L1, // 硲 + 0x7BB8, KANJI_SJIS_L1, // 箞 + 0x8087, KANJI_SJIS_L1, // 肇 + 0x7B48, KANJI_SJIS_L1, // 筈 + 0x6AE8, KANJI_SJIS_L1, // 櫚 + 0x5E61, KANJI_SJIS_L1, // 幡 + 0x808C, KANJI_SJIS_L1, // 肌 + 0x7551, KANJI_SJIS_L1, // 畑 + 0x7560, KANJI_SJIS_L1, // 畠 + 0x516B, KANJI_SJIS_L1, // 八 + 0x9262, KANJI_SJIS_L1, // 鉢 + 0x6E8C, KANJI_SJIS_L1, // 溌 + 0x767A, KANJI_SJIS_L1, // 発 + 0x9197, KANJI_SJIS_L1, // 醗 + 0x9AEA, KANJI_SJIS_L1, // 髪 + 0x4F10, KANJI_SJIS_L1, // 䌐 + 0x7F70, KANJI_SJIS_L1, // 眰 + 0x629C, KANJI_SJIS_L1, // 抜 + 0x7B4F, KANJI_SJIS_L1, // 筏 + 0x95A5, KANJI_SJIS_L1, // 閥 + 0x9CE9, KANJI_SJIS_L1, // 鳩 + 0x567A, KANJI_SJIS_L1, // 噺 + 0x5859, KANJI_SJIS_L1, // 塙 + 0x86E4, KANJI_SJIS_L1, // 蛀 + 0x96BC, KANJI_SJIS_L1, // 隌 + 0x4F34, KANJI_SJIS_L1, // 䌎 + 0x5224, KANJI_SJIS_L1, // 刀 + 0x534A, KANJI_SJIS_L1, // 半 + 0x53CD, KANJI_SJIS_L1, // 反 + 0x53DB, KANJI_SJIS_L1, // 叛 + 0x5E06, KANJI_SJIS_L1, // 垆 + 0x642C, KANJI_SJIS_L1, // 搬 + 0x6591, KANJI_SJIS_L1, // 斑 + 0x677F, KANJI_SJIS_L1, // 板 + 0x6C3E, KANJI_SJIS_L1, // æ°Ÿ + 0x6C4E, KANJI_SJIS_L1, // 汎 + 0x7248, KANJI_SJIS_L1, // 版 + 0x72AF, KANJI_SJIS_L1, // 犯 + 0x73ED, KANJI_SJIS_L1, // 班 + 0x7554, KANJI_SJIS_L1, // 畔 + 0x7E41, KANJI_SJIS_L1, // 繁 + 0x822C, KANJI_SJIS_L1, // 般 + 0x85E9, KANJI_SJIS_L1, // 藩 + 0x8CA9, KANJI_SJIS_L1, // 販 + 0x7BC4, KANJI_SJIS_L1, // 範 + 0x91C6, KANJI_SJIS_L1, // 釆 + 0x7169, KANJI_SJIS_L1, // 煩 + 0x9812, KANJI_SJIS_L1, // 頒 + 0x98EF, KANJI_SJIS_L1, // 飯 + 0x633D, KANJI_SJIS_L1, // 挜 + 0x6669, KANJI_SJIS_L1, // 晩 + 0x756A, KANJI_SJIS_L1, // 番 + 0x76E4, KANJI_SJIS_L1, // 盀 + 0x78D0, KANJI_SJIS_L1, // 磐 + 0x8543, KANJI_SJIS_L1, // 蕃 + 0x86EE, KANJI_SJIS_L1, // 蛮 + 0x532A, KANJI_SJIS_L1, // 匪 + 0x5351, KANJI_SJIS_L1, // 卑 + 0x5426, KANJI_SJIS_L1, // 吊 + 0x5983, KANJI_SJIS_L1, // 劃 + 0x5E87, KANJI_SJIS_L1, // 庇 + 0x5F7C, KANJI_SJIS_L1, // 圌 + 0x60B2, KANJI_SJIS_L1, // 悲 + 0x6249, KANJI_SJIS_L1, // 扉 + 0x6279, KANJI_SJIS_L1, // 批 + 0x62AB, KANJI_SJIS_L1, // 披 + 0x6590, KANJI_SJIS_L1, // 斐 + 0x6BD4, KANJI_SJIS_L1, // 比 + 0x6CCC, KANJI_SJIS_L1, // 泌 + 0x75B2, KANJI_SJIS_L1, // 疲 + 0x76AE, KANJI_SJIS_L1, // 皮 + 0x7891, KANJI_SJIS_L1, // 碑 + 0x79D8, KANJI_SJIS_L1, // 秘 + 0x7DCB, KANJI_SJIS_L1, // 緋 + 0x7F77, KANJI_SJIS_L1, // 眷 + 0x80A5, KANJI_SJIS_L1, // 肥 + 0x88AB, KANJI_SJIS_L1, // 被 + 0x8AB9, KANJI_SJIS_L1, // 誹 + 0x8CBB, KANJI_SJIS_L1, // è²» + 0x907F, KANJI_SJIS_L1, // 避 + 0x975E, KANJI_SJIS_L1, // 非 + 0x98DB, KANJI_SJIS_L1, // 飛 + 0x6A0B, KANJI_SJIS_L1, // æš‹ + 0x7C38, KANJI_SJIS_L1, // ç°ž + 0x5099, KANJI_SJIS_L1, // 備 + 0x5C3E, KANJI_SJIS_L1, // å°Ÿ + 0x5FAE, KANJI_SJIS_L1, // 埮 + 0x6787, KANJI_SJIS_L1, // 枇 + 0x6BD8, KANJI_SJIS_L1, // 毘 + 0x7435, KANJI_SJIS_L1, // 琵 + 0x7709, KANJI_SJIS_L1, // 眉 + 0x7F8E, KANJI_SJIS_L1, // 矎 + 0x9F3B, KANJI_SJIS_L1, // 錻 + 0x67CA, KANJI_SJIS_L1, // 柊 + 0x7A17, KANJI_SJIS_L1, // 繗 + 0x5339, KANJI_SJIS_L1, // 匹 + 0x758B, KANJI_SJIS_L1, // 疋 + 0x9AED, KANJI_SJIS_L1, // é«­ + 0x5F66, KANJI_SJIS_L1, // 圊 + 0x819D, KANJI_SJIS_L1, // 膝 + 0x83F1, KANJI_SJIS_L1, // 菱 + 0x8098, KANJI_SJIS_L1, // 肘 + 0x5F3C, KANJI_SJIS_L1, // 匌 + 0x5FC5, KANJI_SJIS_L1, // 必 + 0x7562, KANJI_SJIS_L1, // 畢 + 0x7B46, KANJI_SJIS_L1, // 筆 + 0x903C, KANJI_SJIS_L1, // 逌 + 0x6867, KANJI_SJIS_L1, // æ¡§ + 0x59EB, KANJI_SJIS_L1, // å§« + 0x5A9B, KANJI_SJIS_L1, // 媛 + 0x7D10, KANJI_SJIS_L1, // 玐 + 0x767E, KANJI_SJIS_L1, // 癟 + 0x8B2C, KANJI_SJIS_L1, // 謬 + 0x4FF5, KANJI_SJIS_L1, // 俵 + 0x5F6A, KANJI_SJIS_L1, // 圪 + 0x6A19, KANJI_SJIS_L1, // æš™ + 0x6C37, KANJI_SJIS_L1, // æ°· + 0x6F02, KANJI_SJIS_L1, // 挂 + 0x74E2, KANJI_SJIS_L1, // 瓢 + 0x7968, KANJI_SJIS_L1, // 祚 + 0x8868, KANJI_SJIS_L1, // 衚 + 0x8A55, KANJI_SJIS_L1, // 評 + 0x8C79, KANJI_SJIS_L1, // è±¹ + 0x5EDF, KANJI_SJIS_L1, // 廟 + 0x63CF, KANJI_SJIS_L1, // 描 + 0x75C5, KANJI_SJIS_L1, // 病 + 0x79D2, KANJI_SJIS_L1, // 秒 + 0x82D7, KANJI_SJIS_L1, // 苗 + 0x9328, KANJI_SJIS_L1, // 錹 + 0x92F2, KANJI_SJIS_L1, // 鋲 + 0x849C, KANJI_SJIS_L1, // 蒜 + 0x86ED, KANJI_SJIS_L1, // 蛭 + 0x9C2D, KANJI_SJIS_L1, // é°­ + 0x54C1, KANJI_SJIS_L1, // 品 + 0x5F6C, KANJI_SJIS_L1, // 圬 + 0x658C, KANJI_SJIS_L1, // 斌 + 0x6D5C, KANJI_SJIS_L1, // 浜 + 0x7015, KANJI_SJIS_L1, // 瀕 + 0x8CA7, KANJI_SJIS_L1, // è²§ + 0x8CD3, KANJI_SJIS_L1, // 賓 + 0x983B, KANJI_SJIS_L1, // é » + 0x654F, KANJI_SJIS_L1, // 敏 + 0x74F6, KANJI_SJIS_L1, // 瓶 + 0x4E0D, KANJI_SJIS_L1, // 䞍 + 0x4ED8, KANJI_SJIS_L1, // 付 + 0x57E0, KANJI_SJIS_L1, // 埠 + 0x592B, KANJI_SJIS_L1, // 倫 + 0x5A66, KANJI_SJIS_L1, // 婊 + 0x5BCC, KANJI_SJIS_L1, // 富 + 0x51A8, KANJI_SJIS_L1, // 冚 + 0x5E03, KANJI_SJIS_L1, // 垃 + 0x5E9C, KANJI_SJIS_L1, // 府 + 0x6016, KANJI_SJIS_L1, // 怖 + 0x6276, KANJI_SJIS_L1, // 扶 + 0x6577, KANJI_SJIS_L1, // 敷 + 0x3000, KANJI_SJIS_L1, //   + 0x65A7, KANJI_SJIS_L1, // 斧 + 0x666E, KANJI_SJIS_L1, // 普 + 0x6D6E, KANJI_SJIS_L1, // æµ® + 0x7236, KANJI_SJIS_L1, // 父 + 0x7B26, KANJI_SJIS_L1, // 笊 + 0x8150, KANJI_SJIS_L1, // 腐 + 0x819A, KANJI_SJIS_L1, // 膚 + 0x8299, KANJI_SJIS_L1, // 芙 + 0x8B5C, KANJI_SJIS_L1, // 譜 + 0x8CA0, KANJI_SJIS_L1, // è²  + 0x8CE6, KANJI_SJIS_L1, // 賊 + 0x8D74, KANJI_SJIS_L1, // 赎 + 0x961C, KANJI_SJIS_L1, // 阜 + 0x9644, KANJI_SJIS_L1, // 附 + 0x4FAE, KANJI_SJIS_L1, // 䟮 + 0x64AB, KANJI_SJIS_L1, // 撫 + 0x6B66, KANJI_SJIS_L1, // æ­Š + 0x821E, KANJI_SJIS_L1, // 舞 + 0x8461, KANJI_SJIS_L1, // 葡 + 0x856A, KANJI_SJIS_L1, // 蕪 + 0x90E8, KANJI_SJIS_L1, // 郚 + 0x5C01, KANJI_SJIS_L1, // 封 + 0x6953, KANJI_SJIS_L1, // 楓 + 0x98A8, KANJI_SJIS_L1, // 颚 + 0x847A, KANJI_SJIS_L1, // 葺 + 0x8557, KANJI_SJIS_L1, // 蕗 + 0x4F0F, KANJI_SJIS_L1, // 䌏 + 0x526F, KANJI_SJIS_L1, // 副 + 0x5FA9, KANJI_SJIS_L1, // 埩 + 0x5E45, KANJI_SJIS_L1, // 幅 + 0x670D, KANJI_SJIS_L1, // 服 + 0x798F, KANJI_SJIS_L1, // 犏 + 0x8179, KANJI_SJIS_L1, // 腹 + 0x8907, KANJI_SJIS_L1, // 耇 + 0x8986, KANJI_SJIS_L1, // 芆 + 0x6DF5, KANJI_SJIS_L1, // æ·µ + 0x5F17, KANJI_SJIS_L1, // 北 + 0x6255, KANJI_SJIS_L1, // 払 + 0x6CB8, KANJI_SJIS_L1, // 沞 + 0x4ECF, KANJI_SJIS_L1, // 仏 + 0x7269, KANJI_SJIS_L1, // 物 + 0x9B92, KANJI_SJIS_L1, // 鮒 + 0x5206, KANJI_SJIS_L1, // 分 + 0x543B, KANJI_SJIS_L1, // 吻 + 0x5674, KANJI_SJIS_L1, // 噎 + 0x58B3, KANJI_SJIS_L1, // 墳 + 0x61A4, KANJI_SJIS_L1, // 憀 + 0x626E, KANJI_SJIS_L1, // 扮 + 0x711A, KANJI_SJIS_L1, // 焚 + 0x596E, KANJI_SJIS_L1, // 奮 + 0x7C89, KANJI_SJIS_L1, // 粉 + 0x7CDE, KANJI_SJIS_L1, // 糞 + 0x7D1B, KANJI_SJIS_L1, // 箛 + 0x96F0, KANJI_SJIS_L1, // 雰 + 0x6587, KANJI_SJIS_L1, // 文 + 0x805E, KANJI_SJIS_L1, // 聞 + 0x4E19, KANJI_SJIS_L1, // 侙 + 0x4F75, KANJI_SJIS_L1, // 䜵 + 0x5175, KANJI_SJIS_L1, // 兵 + 0x5840, KANJI_SJIS_L1, // 塀 + 0x5E63, KANJI_SJIS_L1, // å¹£ + 0x5E73, KANJI_SJIS_L1, // å¹³ + 0x5F0A, KANJI_SJIS_L1, // 匊 + 0x67C4, KANJI_SJIS_L1, // 柄 + 0x4E26, KANJI_SJIS_L1, // 䞊 + 0x853D, KANJI_SJIS_L1, // 蔜 + 0x9589, KANJI_SJIS_L1, // 閉 + 0x965B, KANJI_SJIS_L1, // 陛 + 0x7C73, KANJI_SJIS_L1, // ç±³ + 0x9801, KANJI_SJIS_L1, // 頁 + 0x50FB, KANJI_SJIS_L1, // 僻 + 0x58C1, KANJI_SJIS_L1, // 壁 + 0x7656, KANJI_SJIS_L1, // 癖 + 0x78A7, KANJI_SJIS_L1, // 碧 + 0x5225, KANJI_SJIS_L1, // 別 + 0x77A5, KANJI_SJIS_L1, // 瞥 + 0x8511, KANJI_SJIS_L1, // 蔑 + 0x7B86, KANJI_SJIS_L1, // 箆 + 0x504F, KANJI_SJIS_L1, // 偏 + 0x5909, KANJI_SJIS_L1, // 倉 + 0x7247, KANJI_SJIS_L1, // 片 + 0x7BC7, KANJI_SJIS_L1, // 篇 + 0x7DE8, KANJI_SJIS_L1, // ç·š + 0x8FBA, KANJI_SJIS_L1, // 蟺 + 0x8FD4, KANJI_SJIS_L1, // 返 + 0x904D, KANJI_SJIS_L1, // 遍 + 0x4FBF, KANJI_SJIS_L1, // 䟿 + 0x52C9, KANJI_SJIS_L1, // 勉 + 0x5A29, KANJI_SJIS_L1, // åš© + 0x5F01, KANJI_SJIS_L1, // 匁 + 0x97AD, KANJI_SJIS_L1, // 鞭 + 0x4FDD, KANJI_SJIS_L1, // 保 + 0x8217, KANJI_SJIS_L1, // 舗 + 0x92EA, KANJI_SJIS_L1, // 鋪 + 0x5703, KANJI_SJIS_L1, // 圃 + 0x6355, KANJI_SJIS_L1, // 捕 + 0x6B69, KANJI_SJIS_L1, // æ­© + 0x752B, KANJI_SJIS_L1, // 甫 + 0x88DC, KANJI_SJIS_L1, // 補 + 0x8F14, KANJI_SJIS_L1, // 茔 + 0x7A42, KANJI_SJIS_L1, // 穂 + 0x52DF, KANJI_SJIS_L1, // 募 + 0x5893, KANJI_SJIS_L1, // 墓 + 0x6155, KANJI_SJIS_L1, // 慕 + 0x620A, KANJI_SJIS_L1, // 戊 + 0x66AE, KANJI_SJIS_L1, // 暮 + 0x6BCD, KANJI_SJIS_L1, // 母 + 0x7C3F, KANJI_SJIS_L1, // ç°¿ + 0x83E9, KANJI_SJIS_L1, // 菩 + 0x5023, KANJI_SJIS_L1, // 倣 + 0x4FF8, KANJI_SJIS_L1, // 俞 + 0x5305, KANJI_SJIS_L1, // 包 + 0x5446, KANJI_SJIS_L1, // 呆 + 0x5831, KANJI_SJIS_L1, // å ± + 0x5949, KANJI_SJIS_L1, // 奉 + 0x5B9D, KANJI_SJIS_L1, // 宝 + 0x5CF0, KANJI_SJIS_L1, // å³° + 0x5CEF, KANJI_SJIS_L1, // 峯 + 0x5D29, KANJI_SJIS_L1, // 厩 + 0x5E96, KANJI_SJIS_L1, // 庖 + 0x62B1, KANJI_SJIS_L1, // 抱 + 0x6367, KANJI_SJIS_L1, // 捧 + 0x653E, KANJI_SJIS_L1, // 攟 + 0x65B9, KANJI_SJIS_L1, // 方 + 0x670B, KANJI_SJIS_L1, // 朋 + 0x6CD5, KANJI_SJIS_L1, // 法 + 0x6CE1, KANJI_SJIS_L1, // 泡 + 0x70F9, KANJI_SJIS_L1, // 烹 + 0x7832, KANJI_SJIS_L1, // ç ² + 0x7E2B, KANJI_SJIS_L1, // çž« + 0x80DE, KANJI_SJIS_L1, // 胞 + 0x82B3, KANJI_SJIS_L1, // 芳 + 0x840C, KANJI_SJIS_L1, // 萌 + 0x84EC, KANJI_SJIS_L1, // 蓬 + 0x8702, KANJI_SJIS_L1, // 蜂 + 0x8912, KANJI_SJIS_L1, // 耒 + 0x8A2A, KANJI_SJIS_L1, // 蚪 + 0x8C4A, KANJI_SJIS_L1, // 豊 + 0x90A6, KANJI_SJIS_L1, // 邩 + 0x92D2, KANJI_SJIS_L1, // 鋒 + 0x98FD, KANJI_SJIS_L1, // 飜 + 0x9CF3, KANJI_SJIS_L1, // é³³ + 0x9D6C, KANJI_SJIS_L1, // 鵬 + 0x4E4F, KANJI_SJIS_L1, // 乏 + 0x4EA1, KANJI_SJIS_L1, // 亡 + 0x508D, KANJI_SJIS_L1, // 傍 + 0x5256, KANJI_SJIS_L1, // 剖 + 0x574A, KANJI_SJIS_L1, // 坊 + 0x59A8, KANJI_SJIS_L1, // 劚 + 0x5E3D, KANJI_SJIS_L1, // åžœ + 0x5FD8, KANJI_SJIS_L1, // 忘 + 0x5FD9, KANJI_SJIS_L1, // 忙 + 0x623F, KANJI_SJIS_L1, // 房 + 0x66B4, KANJI_SJIS_L1, // 暎 + 0x671B, KANJI_SJIS_L1, // 望 + 0x67D0, KANJI_SJIS_L1, // 某 + 0x68D2, KANJI_SJIS_L1, // 棒 + 0x5192, KANJI_SJIS_L1, // 冒 + 0x7D21, KANJI_SJIS_L1, // 玡 + 0x80AA, KANJI_SJIS_L1, // 肪 + 0x81A8, KANJI_SJIS_L1, // 膚 + 0x8B00, KANJI_SJIS_L1, // 謀 + 0x8C8C, KANJI_SJIS_L1, // 貌 + 0x8CBF, KANJI_SJIS_L1, // 貿 + 0x927E, KANJI_SJIS_L1, // 鉟 + 0x9632, KANJI_SJIS_L1, // 防 + 0x5420, KANJI_SJIS_L1, // 吠 + 0x982C, KANJI_SJIS_L1, // é ¬ + 0x5317, KANJI_SJIS_L1, // 北 + 0x50D5, KANJI_SJIS_L1, // 僕 + 0x535C, KANJI_SJIS_L1, // 卜 + 0x58A8, KANJI_SJIS_L1, // 墚 + 0x64B2, KANJI_SJIS_L1, // 撲 + 0x6734, KANJI_SJIS_L1, // 朎 + 0x7267, KANJI_SJIS_L1, // 牧 + 0x7766, KANJI_SJIS_L1, // 睊 + 0x7A46, KANJI_SJIS_L1, // 穆 + 0x91E6, KANJI_SJIS_L1, // 釩 + 0x52C3, KANJI_SJIS_L1, // 勃 + 0x6CA1, KANJI_SJIS_L1, // 没 + 0x6B86, KANJI_SJIS_L1, // 殆 + 0x5800, KANJI_SJIS_L1, // 堀 + 0x5E4C, KANJI_SJIS_L1, // 幌 + 0x5954, KANJI_SJIS_L1, // 奔 + 0x672C, KANJI_SJIS_L1, // 本 + 0x7FFB, KANJI_SJIS_L1, // ç¿» + 0x51E1, KANJI_SJIS_L1, // 凡 + 0x76C6, KANJI_SJIS_L1, // 盆 + 0x3000, KANJI_SJIS_L1, //   + 0x6469, KANJI_SJIS_L1, // 摩 + 0x78E8, KANJI_SJIS_L1, // 磚 + 0x9B54, KANJI_SJIS_L1, // 魔 + 0x9EBB, KANJI_SJIS_L1, // 麻 + 0x57CB, KANJI_SJIS_L1, // 埋 + 0x59B9, KANJI_SJIS_L1, // 効 + 0x6627, KANJI_SJIS_L1, // 昧 + 0x679A, KANJI_SJIS_L1, // 枚 + 0x6BCE, KANJI_SJIS_L1, // 毎 + 0x54E9, KANJI_SJIS_L1, // 哩 + 0x69D9, KANJI_SJIS_L1, // 槙 + 0x5E55, KANJI_SJIS_L1, // 幕 + 0x819C, KANJI_SJIS_L1, // 膜 + 0x6795, KANJI_SJIS_L1, // 枕 + 0x9BAA, KANJI_SJIS_L1, // 鮪 + 0x67FE, KANJI_SJIS_L1, // 柟 + 0x9C52, KANJI_SJIS_L1, // 鱒 + 0x685D, KANJI_SJIS_L1, // 桝 + 0x4EA6, KANJI_SJIS_L1, // 亊 + 0x4FE3, KANJI_SJIS_L1, // ä¿£ + 0x53C8, KANJI_SJIS_L1, // 又 + 0x62B9, KANJI_SJIS_L1, // 抹 + 0x672B, KANJI_SJIS_L1, // 末 + 0x6CAB, KANJI_SJIS_L1, // 沫 + 0x8FC4, KANJI_SJIS_L1, // 迄 + 0x4FAD, KANJI_SJIS_L1, // 䟭 + 0x7E6D, KANJI_SJIS_L1, // ç¹­ + 0x9EBF, KANJI_SJIS_L1, // 麿 + 0x4E07, KANJI_SJIS_L1, // 侇 + 0x6162, KANJI_SJIS_L1, // 慢 + 0x6E80, KANJI_SJIS_L1, // 満 + 0x6F2B, KANJI_SJIS_L1, // 挫 + 0x8513, KANJI_SJIS_L1, // 蔓 + 0x5473, KANJI_SJIS_L1, // 味 + 0x672A, KANJI_SJIS_L1, // 未 + 0x9B45, KANJI_SJIS_L1, // 魅 + 0x5DF3, KANJI_SJIS_L1, // å·³ + 0x7B95, KANJI_SJIS_L1, // 箕 + 0x5CAC, KANJI_SJIS_L1, // 岬 + 0x5BC6, KANJI_SJIS_L1, // 密 + 0x871C, KANJI_SJIS_L1, // 蜜 + 0x6E4A, KANJI_SJIS_L1, // 湊 + 0x84D1, KANJI_SJIS_L1, // 蓑 + 0x7A14, KANJI_SJIS_L1, // 織 + 0x8108, KANJI_SJIS_L1, // 脈 + 0x5999, KANJI_SJIS_L1, // 劙 + 0x7C8D, KANJI_SJIS_L1, // 粍 + 0x6C11, KANJI_SJIS_L1, // 民 + 0x7720, KANJI_SJIS_L1, // 眠 + 0x52D9, KANJI_SJIS_L1, // 務 + 0x5922, KANJI_SJIS_L1, // 倢 + 0x7121, KANJI_SJIS_L1, // 無 + 0x725F, KANJI_SJIS_L1, // 牟 + 0x77DB, KANJI_SJIS_L1, // 矛 + 0x9727, KANJI_SJIS_L1, // 霧 + 0x9D61, KANJI_SJIS_L1, // 鵡 + 0x690B, KANJI_SJIS_L1, // 怋 + 0x5A7F, KANJI_SJIS_L1, // å©¿ + 0x5A18, KANJI_SJIS_L1, // 嚘 + 0x51A5, KANJI_SJIS_L1, // 冥 + 0x540D, KANJI_SJIS_L1, // 名 + 0x547D, KANJI_SJIS_L1, // 呜 + 0x660E, KANJI_SJIS_L1, // 明 + 0x76DF, KANJI_SJIS_L1, // 盟 + 0x8FF7, KANJI_SJIS_L1, // è¿· + 0x9298, KANJI_SJIS_L1, // 銘 + 0x9CF4, KANJI_SJIS_L1, // 鳎 + 0x59EA, KANJI_SJIS_L1, // 姪 + 0x725D, KANJI_SJIS_L1, // 牝 + 0x6EC5, KANJI_SJIS_L1, // 滅 + 0x514D, KANJI_SJIS_L1, // 免 + 0x68C9, KANJI_SJIS_L1, // 棉 + 0x7DBF, KANJI_SJIS_L1, // ç¶¿ + 0x7DEC, KANJI_SJIS_L1, // ç·¬ + 0x9762, KANJI_SJIS_L1, // 面 + 0x9EBA, KANJI_SJIS_L1, // 麺 + 0x6478, KANJI_SJIS_L1, // 摞 + 0x6A21, KANJI_SJIS_L1, // æš¡ + 0x8302, KANJI_SJIS_L1, // 茂 + 0x5984, KANJI_SJIS_L1, // 劄 + 0x5B5F, KANJI_SJIS_L1, // 孟 + 0x6BDB, KANJI_SJIS_L1, // 毛 + 0x731B, KANJI_SJIS_L1, // 猛 + 0x76F2, KANJI_SJIS_L1, // 盲 + 0x7DB2, KANJI_SJIS_L1, // ç¶² + 0x8017, KANJI_SJIS_L1, // 耗 + 0x8499, KANJI_SJIS_L1, // 蒙 + 0x5132, KANJI_SJIS_L1, // 儲 + 0x6728, KANJI_SJIS_L1, // 朚 + 0x9ED9, KANJI_SJIS_L1, // 黙 + 0x76EE, KANJI_SJIS_L1, // 目 + 0x6762, KANJI_SJIS_L1, // 杢 + 0x52FF, KANJI_SJIS_L1, // 勿 + 0x9905, KANJI_SJIS_L1, // 逅 + 0x5C24, KANJI_SJIS_L1, // å°€ + 0x623B, KANJI_SJIS_L1, // 戻 + 0x7C7E, KANJI_SJIS_L1, // 籟 + 0x8CB0, KANJI_SJIS_L1, // è²° + 0x554F, KANJI_SJIS_L1, // 問 + 0x60B6, KANJI_SJIS_L1, // 悶 + 0x7D0B, KANJI_SJIS_L1, // 箋 + 0x9580, KANJI_SJIS_L1, // 門 + 0x5301, KANJI_SJIS_L1, // 匁 + 0x4E5F, KANJI_SJIS_L1, // 也 + 0x51B6, KANJI_SJIS_L1, // 冶 + 0x591C, KANJI_SJIS_L1, // 倜 + 0x723A, KANJI_SJIS_L1, // 爺 + 0x8036, KANJI_SJIS_L1, // 耶 + 0x91CE, KANJI_SJIS_L1, // 野 + 0x5F25, KANJI_SJIS_L1, // 匥 + 0x77E2, KANJI_SJIS_L1, // 矢 + 0x5384, KANJI_SJIS_L1, // 厄 + 0x5F79, KANJI_SJIS_L1, // 圹 + 0x7D04, KANJI_SJIS_L1, // 箄 + 0x85AC, KANJI_SJIS_L1, // 薬 + 0x8A33, KANJI_SJIS_L1, // èš³ + 0x8E8D, KANJI_SJIS_L1, // 躍 + 0x9756, KANJI_SJIS_L1, // 靖 + 0x67F3, KANJI_SJIS_L1, // 柳 + 0x85AE, KANJI_SJIS_L1, // 薮 + 0x9453, KANJI_SJIS_L1, // 鑓 + 0x6109, KANJI_SJIS_L1, // 愉 + 0x6108, KANJI_SJIS_L1, // 愈 + 0x6CB9, KANJI_SJIS_L1, // æ²¹ + 0x7652, KANJI_SJIS_L1, // 癒 + 0x8AED, KANJI_SJIS_L1, // è«­ + 0x8F38, KANJI_SJIS_L1, // 茞 + 0x552F, KANJI_SJIS_L1, // 唯 + 0x4F51, KANJI_SJIS_L1, // 䜑 + 0x512A, KANJI_SJIS_L1, // 優 + 0x52C7, KANJI_SJIS_L1, // 勇 + 0x53CB, KANJI_SJIS_L1, // 友 + 0x5BA5, KANJI_SJIS_L1, // 宥 + 0x5E7D, KANJI_SJIS_L1, // 幜 + 0x60A0, KANJI_SJIS_L1, // 悠 + 0x6182, KANJI_SJIS_L1, // 憂 + 0x63D6, KANJI_SJIS_L1, // 揖 + 0x6709, KANJI_SJIS_L1, // 有 + 0x67DA, KANJI_SJIS_L1, // 柚 + 0x6E67, KANJI_SJIS_L1, // æ¹§ + 0x6D8C, KANJI_SJIS_L1, // 涌 + 0x7336, KANJI_SJIS_L1, // 猶 + 0x7337, KANJI_SJIS_L1, // 猷 + 0x7531, KANJI_SJIS_L1, // 由 + 0x7950, KANJI_SJIS_L1, // 祐 + 0x88D5, KANJI_SJIS_L1, // 裕 + 0x8A98, KANJI_SJIS_L1, // 誘 + 0x904A, KANJI_SJIS_L1, // 遊 + 0x9091, KANJI_SJIS_L1, // 邑 + 0x90F5, KANJI_SJIS_L1, // 郵 + 0x96C4, KANJI_SJIS_L1, // 雄 + 0x878D, KANJI_SJIS_L1, // 融 + 0x5915, KANJI_SJIS_L1, // 倕 + 0x4E88, KANJI_SJIS_L1, // 予 + 0x4F59, KANJI_SJIS_L1, // 䜙 + 0x4E0E, KANJI_SJIS_L1, // 侎 + 0x8A89, KANJI_SJIS_L1, // 誉 + 0x8F3F, KANJI_SJIS_L1, // 茿 + 0x9810, KANJI_SJIS_L1, // 預 + 0x50AD, KANJI_SJIS_L1, // 傭 + 0x5E7C, KANJI_SJIS_L1, // 幌 + 0x5996, KANJI_SJIS_L1, // 劖 + 0x5BB9, KANJI_SJIS_L1, // 容 + 0x5EB8, KANJI_SJIS_L1, // 庞 + 0x63DA, KANJI_SJIS_L1, // 揚 + 0x63FA, KANJI_SJIS_L1, // 揺 + 0x64C1, KANJI_SJIS_L1, // 擁 + 0x66DC, KANJI_SJIS_L1, // 曜 + 0x694A, KANJI_SJIS_L1, // 楊 + 0x69D8, KANJI_SJIS_L1, // 様 + 0x6D0B, KANJI_SJIS_L1, // 掋 + 0x6EB6, KANJI_SJIS_L1, // 溶 + 0x7194, KANJI_SJIS_L1, // 熔 + 0x7528, KANJI_SJIS_L1, // 甹 + 0x7AAF, KANJI_SJIS_L1, // 窯 + 0x7F8A, KANJI_SJIS_L1, // 矊 + 0x8000, KANJI_SJIS_L1, // 耀 + 0x8449, KANJI_SJIS_L1, // 葉 + 0x84C9, KANJI_SJIS_L1, // 蓉 + 0x8981, KANJI_SJIS_L1, // 芁 + 0x8B21, KANJI_SJIS_L1, // 謡 + 0x8E0A, KANJI_SJIS_L1, // 螊 + 0x9065, KANJI_SJIS_L1, // 遥 + 0x967D, KANJI_SJIS_L1, // 陜 + 0x990A, KANJI_SJIS_L1, // 逊 + 0x617E, KANJI_SJIS_L1, // æ…Ÿ + 0x6291, KANJI_SJIS_L1, // 抑 + 0x6B32, KANJI_SJIS_L1, // 欲 + 0x3000, KANJI_SJIS_L1, //   + 0x6C83, KANJI_SJIS_L1, // 沃 + 0x6D74, KANJI_SJIS_L1, // 济 + 0x7FCC, KANJI_SJIS_L1, // 翌 + 0x7FFC, KANJI_SJIS_L1, // 翌 + 0x6DC0, KANJI_SJIS_L1, // 淀 + 0x7F85, KANJI_SJIS_L1, // 矅 + 0x87BA, KANJI_SJIS_L1, // 螺 + 0x88F8, KANJI_SJIS_L1, // 裞 + 0x6765, KANJI_SJIS_L1, // 来 + 0x83B1, KANJI_SJIS_L1, // 莱 + 0x983C, KANJI_SJIS_L1, // é Œ + 0x96F7, KANJI_SJIS_L1, // 雷 + 0x6D1B, KANJI_SJIS_L1, // 掛 + 0x7D61, KANJI_SJIS_L1, // 絡 + 0x843D, KANJI_SJIS_L1, // 萜 + 0x916A, KANJI_SJIS_L1, // 酪 + 0x4E71, KANJI_SJIS_L1, // ä¹± + 0x5375, KANJI_SJIS_L1, // 卵 + 0x5D50, KANJI_SJIS_L1, // 嵐 + 0x6B04, KANJI_SJIS_L1, // 欄 + 0x6FEB, KANJI_SJIS_L1, // æ¿« + 0x85CD, KANJI_SJIS_L1, // 藍 + 0x862D, KANJI_SJIS_L1, // 蘭 + 0x89A7, KANJI_SJIS_L1, // 芧 + 0x5229, KANJI_SJIS_L1, // 利 + 0x540F, KANJI_SJIS_L1, // 吏 + 0x5C65, KANJI_SJIS_L1, // å±¥ + 0x674E, KANJI_SJIS_L1, // 李 + 0x68A8, KANJI_SJIS_L1, // 梚 + 0x7406, KANJI_SJIS_L1, // 理 + 0x7483, KANJI_SJIS_L1, // 璃 + 0x75E2, KANJI_SJIS_L1, // 痢 + 0x88CF, KANJI_SJIS_L1, // 裏 + 0x88E1, KANJI_SJIS_L1, // 裡 + 0x91CC, KANJI_SJIS_L1, // 里 + 0x96E2, KANJI_SJIS_L1, // 離 + 0x9678, KANJI_SJIS_L1, // 陾 + 0x5F8B, KANJI_SJIS_L1, // 埋 + 0x7387, KANJI_SJIS_L1, // 率 + 0x7ACB, KANJI_SJIS_L1, // 立 + 0x844E, KANJI_SJIS_L1, // 葎 + 0x63A0, KANJI_SJIS_L1, // 掠 + 0x7565, KANJI_SJIS_L1, // 略 + 0x5289, KANJI_SJIS_L1, // 劉 + 0x6D41, KANJI_SJIS_L1, // 流 + 0x6E9C, KANJI_SJIS_L1, // 溜 + 0x7409, KANJI_SJIS_L1, // 琉 + 0x7559, KANJI_SJIS_L1, // 留 + 0x786B, KANJI_SJIS_L1, // ç¡« + 0x7C92, KANJI_SJIS_L1, // 粒 + 0x9686, KANJI_SJIS_L1, // 隆 + 0x7ADC, KANJI_SJIS_L1, // 竜 + 0x9F8D, KANJI_SJIS_L1, // 韍 + 0x4FB6, KANJI_SJIS_L1, // 䟶 + 0x616E, KANJI_SJIS_L1, // 慮 + 0x65C5, KANJI_SJIS_L1, // 旅 + 0x865C, KANJI_SJIS_L1, // 虜 + 0x4E86, KANJI_SJIS_L1, // 了 + 0x4EAE, KANJI_SJIS_L1, // 亮 + 0x50DA, KANJI_SJIS_L1, // 僚 + 0x4E21, KANJI_SJIS_L1, // äž¡ + 0x51CC, KANJI_SJIS_L1, // 凌 + 0x5BEE, KANJI_SJIS_L1, // 寮 + 0x6599, KANJI_SJIS_L1, // 料 + 0x6881, KANJI_SJIS_L1, // 梁 + 0x6DBC, KANJI_SJIS_L1, // æ¶Œ + 0x731F, KANJI_SJIS_L1, // 猟 + 0x7642, KANJI_SJIS_L1, // 療 + 0x77AD, KANJI_SJIS_L1, // 瞭 + 0x7A1C, KANJI_SJIS_L1, // 繜 + 0x7CE7, KANJI_SJIS_L1, // ç³§ + 0x826F, KANJI_SJIS_L1, // 良 + 0x8AD2, KANJI_SJIS_L1, // 諒 + 0x907C, KANJI_SJIS_L1, // 遌 + 0x91CF, KANJI_SJIS_L1, // 量 + 0x9675, KANJI_SJIS_L1, // 陵 + 0x9818, KANJI_SJIS_L1, // 領 + 0x529B, KANJI_SJIS_L1, // 力 + 0x7DD1, KANJI_SJIS_L1, // 緑 + 0x502B, KANJI_SJIS_L1, // 倫 + 0x5398, KANJI_SJIS_L1, // 厘 + 0x6797, KANJI_SJIS_L1, // 林 + 0x6DCB, KANJI_SJIS_L1, // 淋 + 0x71D0, KANJI_SJIS_L1, // 燐 + 0x7433, KANJI_SJIS_L1, // 琳 + 0x81E8, KANJI_SJIS_L1, // 臚 + 0x8F2A, KANJI_SJIS_L1, // 茪 + 0x96A3, KANJI_SJIS_L1, // 隣 + 0x9C57, KANJI_SJIS_L1, // 鱗 + 0x9E9F, KANJI_SJIS_L1, // 麟 + 0x7460, KANJI_SJIS_L1, // 瑠 + 0x5841, KANJI_SJIS_L1, // 塁 + 0x6D99, KANJI_SJIS_L1, // 涙 + 0x7D2F, KANJI_SJIS_L1, // 环 + 0x985E, KANJI_SJIS_L1, // 類 + 0x4EE4, KANJI_SJIS_L1, // 什 + 0x4F36, KANJI_SJIS_L1, // 䌶 + 0x4F8B, KANJI_SJIS_L1, // 䟋 + 0x51B7, KANJI_SJIS_L1, // 冷 + 0x52B1, KANJI_SJIS_L1, // 励 + 0x5DBA, KANJI_SJIS_L1, // 嶺 + 0x601C, KANJI_SJIS_L1, // 怜 + 0x73B2, KANJI_SJIS_L1, // 玲 + 0x793C, KANJI_SJIS_L1, // 瀌 + 0x82D3, KANJI_SJIS_L1, // 苓 + 0x9234, KANJI_SJIS_L1, // 鈎 + 0x96B7, KANJI_SJIS_L1, // 隷 + 0x96F6, KANJI_SJIS_L1, // 零 + 0x970A, KANJI_SJIS_L1, // 霊 + 0x9E97, KANJI_SJIS_L1, // 麗 + 0x9F62, KANJI_SJIS_L1, // 霢 + 0x66A6, KANJI_SJIS_L1, // 暊 + 0x6B74, KANJI_SJIS_L1, // æ­Ž + 0x5217, KANJI_SJIS_L1, // 列 + 0x52A3, KANJI_SJIS_L1, // 劣 + 0x70C8, KANJI_SJIS_L1, // 烈 + 0x88C2, KANJI_SJIS_L1, // 裂 + 0x5EC9, KANJI_SJIS_L1, // 廉 + 0x604B, KANJI_SJIS_L1, // 恋 + 0x6190, KANJI_SJIS_L1, // 憐 + 0x6F23, KANJI_SJIS_L1, // 挣 + 0x7149, KANJI_SJIS_L1, // 煉 + 0x7C3E, KANJI_SJIS_L1, // ç°Ÿ + 0x7DF4, KANJI_SJIS_L1, // ç·Ž + 0x806F, KANJI_SJIS_L1, // 聯 + 0x84EE, KANJI_SJIS_L1, // 蓮 + 0x9023, KANJI_SJIS_L1, // 連 + 0x932C, KANJI_SJIS_L1, // 錬 + 0x5442, KANJI_SJIS_L1, // 呂 + 0x9B6F, KANJI_SJIS_L1, // é­¯ + 0x6AD3, KANJI_SJIS_L1, // 櫓 + 0x7089, KANJI_SJIS_L1, // 炉 + 0x8CC2, KANJI_SJIS_L1, // 賂 + 0x8DEF, KANJI_SJIS_L1, // è·¯ + 0x9732, KANJI_SJIS_L1, // 露 + 0x52B4, KANJI_SJIS_L1, // 劎 + 0x5A41, KANJI_SJIS_L1, // 婁 + 0x5ECA, KANJI_SJIS_L1, // 廊 + 0x5F04, KANJI_SJIS_L1, // 匄 + 0x6717, KANJI_SJIS_L1, // 朗 + 0x697C, KANJI_SJIS_L1, // 楌 + 0x6994, KANJI_SJIS_L1, // 抔 + 0x6D6A, KANJI_SJIS_L1, // 浪 + 0x6F0F, KANJI_SJIS_L1, // 挏 + 0x7262, KANJI_SJIS_L1, // 牢 + 0x72FC, KANJI_SJIS_L1, // 狌 + 0x7BED, KANJI_SJIS_L1, // 篭 + 0x8001, KANJI_SJIS_L1, // 老 + 0x807E, KANJI_SJIS_L1, // 聟 + 0x874B, KANJI_SJIS_L1, // 蝋 + 0x90CE, KANJI_SJIS_L1, // 郎 + 0x516D, KANJI_SJIS_L1, // 六 + 0x9E93, KANJI_SJIS_L1, // 麓 + 0x7984, KANJI_SJIS_L1, // 穄 + 0x808B, KANJI_SJIS_L1, // 肋 + 0x9332, KANJI_SJIS_L1, // 録 + 0x8AD6, KANJI_SJIS_L1, // 論 + 0x502D, KANJI_SJIS_L1, // 倭 + 0x548C, KANJI_SJIS_L1, // 和 + 0x8A71, KANJI_SJIS_L1, // 話 + 0x6B6A, KANJI_SJIS_L1, // æ­ª + 0x8CC4, KANJI_SJIS_L1, // 賄 + 0x8107, KANJI_SJIS_L1, // 脇 + 0x60D1, KANJI_SJIS_L1, // 惑 + 0x67A0, KANJI_SJIS_L1, // 枠 + 0x9DF2, KANJI_SJIS_L1, // é·² + 0x4E99, KANJI_SJIS_L1, // 亙 + 0x4E98, KANJI_SJIS_L1, // 亘 + 0x9C10, KANJI_SJIS_L1, // 鰐 + 0x8A6B, KANJI_SJIS_L1, // è©« + 0x85C1, KANJI_SJIS_L1, // 藁 + 0x8568, KANJI_SJIS_L1, // 蕚 + 0x6900, KANJI_SJIS_L1, // 怀 + 0x6E7E, KANJI_SJIS_L1, // 湟 + 0x7897, KANJI_SJIS_L1, // 碗 + 0x8155, KANJI_SJIS_L1, // 腕 + 0x5F0C, KANJI_SJIS_L2, // 匌 + 0x4E10, KANJI_SJIS_L2, // 䞐 + 0x4E15, KANJI_SJIS_L2, // 侕 + 0x4E2A, KANJI_SJIS_L2, // 䞪 + 0x4E31, KANJI_SJIS_L2, // äž± + 0x4E36, KANJI_SJIS_L2, // äž¶ + 0x4E3C, KANJI_SJIS_L2, // 䞌 + 0x4E3F, KANJI_SJIS_L2, // äž¿ + 0x4E42, KANJI_SJIS_L2, // 乂 + 0x4E56, KANJI_SJIS_L2, // 乖 + 0x4E58, KANJI_SJIS_L2, // 乘 + 0x4E82, KANJI_SJIS_L2, // 亂 + 0x4E85, KANJI_SJIS_L2, // 亅 + 0x8C6B, KANJI_SJIS_L2, // 豫 + 0x4E8A, KANJI_SJIS_L2, // 亊 + 0x8212, KANJI_SJIS_L2, // 舒 + 0x5F0D, KANJI_SJIS_L2, // 匍 + 0x4E8E, KANJI_SJIS_L2, // 于 + 0x4E9E, KANJI_SJIS_L2, // 亞 + 0x4E9F, KANJI_SJIS_L2, // 亟 + 0x4EA0, KANJI_SJIS_L2, // 亠 + 0x4EA2, KANJI_SJIS_L2, // 亢 + 0x4EB0, KANJI_SJIS_L2, // 亰 + 0x4EB3, KANJI_SJIS_L2, // 亳 + 0x4EB6, KANJI_SJIS_L2, // 亶 + 0x4ECE, KANJI_SJIS_L2, // 从 + 0x4ECD, KANJI_SJIS_L2, // 仍 + 0x4EC4, KANJI_SJIS_L2, // 仄 + 0x4EC6, KANJI_SJIS_L2, // 仆 + 0x4EC2, KANJI_SJIS_L2, // 仂 + 0x4ED7, KANJI_SJIS_L2, // 仗 + 0x4EDE, KANJI_SJIS_L2, // 仞 + 0x4EED, KANJI_SJIS_L2, // ä»­ + 0x4EDF, KANJI_SJIS_L2, // 仟 + 0x4EF7, KANJI_SJIS_L2, // ä»· + 0x4F09, KANJI_SJIS_L2, // 䌉 + 0x4F5A, KANJI_SJIS_L2, // 䜚 + 0x4F30, KANJI_SJIS_L2, // 䌰 + 0x4F5B, KANJI_SJIS_L2, // 䜛 + 0x4F5D, KANJI_SJIS_L2, // 䜝 + 0x4F57, KANJI_SJIS_L2, // 䜗 + 0x4F47, KANJI_SJIS_L2, // 䜇 + 0x4F76, KANJI_SJIS_L2, // 䜶 + 0x4F88, KANJI_SJIS_L2, // 䟈 + 0x4F8F, KANJI_SJIS_L2, // 䟏 + 0x4F98, KANJI_SJIS_L2, // 䟘 + 0x4F7B, KANJI_SJIS_L2, // 䜻 + 0x4F69, KANJI_SJIS_L2, // 䜩 + 0x4F70, KANJI_SJIS_L2, // 䜰 + 0x4F91, KANJI_SJIS_L2, // 䟑 + 0x4F6F, KANJI_SJIS_L2, // 䜯 + 0x4F86, KANJI_SJIS_L2, // 䟆 + 0x4F96, KANJI_SJIS_L2, // 䟖 + 0x5118, KANJI_SJIS_L2, // 儘 + 0x4FD4, KANJI_SJIS_L2, // 俔 + 0x4FDF, KANJI_SJIS_L2, // 俟 + 0x4FCE, KANJI_SJIS_L2, // 俎 + 0x4FD8, KANJI_SJIS_L2, // 俘 + 0x4FDB, KANJI_SJIS_L2, // 俛 + 0x4FD1, KANJI_SJIS_L2, // 俑 + 0x4FDA, KANJI_SJIS_L2, // 俚 + 0x4FD0, KANJI_SJIS_L2, // 俐 + 0x4FE4, KANJI_SJIS_L2, // ä¿€ + 0x4FE5, KANJI_SJIS_L2, // ä¿¥ + 0x501A, KANJI_SJIS_L2, // 倚 + 0x5028, KANJI_SJIS_L2, // 倚 + 0x5014, KANJI_SJIS_L2, // 倔 + 0x502A, KANJI_SJIS_L2, // 倪 + 0x5025, KANJI_SJIS_L2, // 倥 + 0x5005, KANJI_SJIS_L2, // 倅 + 0x4F1C, KANJI_SJIS_L2, // 䌜 + 0x4FF6, KANJI_SJIS_L2, // ä¿¶ + 0x5021, KANJI_SJIS_L2, // 倡 + 0x5029, KANJI_SJIS_L2, // 倩 + 0x502C, KANJI_SJIS_L2, // 倬 + 0x4FFE, KANJI_SJIS_L2, // 俟 + 0x4FEF, KANJI_SJIS_L2, // 俯 + 0x5011, KANJI_SJIS_L2, // 們 + 0x5006, KANJI_SJIS_L2, // 倆 + 0x5043, KANJI_SJIS_L2, // 偃 + 0x5047, KANJI_SJIS_L2, // 假 + 0x6703, KANJI_SJIS_L2, // 會 + 0x5055, KANJI_SJIS_L2, // 偕 + 0x5050, KANJI_SJIS_L2, // 偐 + 0x5048, KANJI_SJIS_L2, // 偈 + 0x505A, KANJI_SJIS_L2, // 做 + 0x5056, KANJI_SJIS_L2, // 偖 + 0x506C, KANJI_SJIS_L2, // 偬 + 0x5078, KANJI_SJIS_L2, // 偞 + 0x5080, KANJI_SJIS_L2, // 傀 + 0x509A, KANJI_SJIS_L2, // 傚 + 0x5085, KANJI_SJIS_L2, // 傅 + 0x50B4, KANJI_SJIS_L2, // 傎 + 0x50B2, KANJI_SJIS_L2, // 傲 + 0x50C9, KANJI_SJIS_L2, // 僉 + 0x50CA, KANJI_SJIS_L2, // 僊 + 0x50B3, KANJI_SJIS_L2, // 傳 + 0x50C2, KANJI_SJIS_L2, // 僂 + 0x50D6, KANJI_SJIS_L2, // 僖 + 0x50DE, KANJI_SJIS_L2, // 僞 + 0x50E5, KANJI_SJIS_L2, // 僥 + 0x50ED, KANJI_SJIS_L2, // 僭 + 0x50E3, KANJI_SJIS_L2, // 僣 + 0x50EE, KANJI_SJIS_L2, // 僮 + 0x50F9, KANJI_SJIS_L2, // 價 + 0x50F5, KANJI_SJIS_L2, // 僵 + 0x5109, KANJI_SJIS_L2, // 儉 + 0x5101, KANJI_SJIS_L2, // 儁 + 0x5102, KANJI_SJIS_L2, // 儂 + 0x5116, KANJI_SJIS_L2, // 儖 + 0x5115, KANJI_SJIS_L2, // 儕 + 0x5114, KANJI_SJIS_L2, // 儔 + 0x511A, KANJI_SJIS_L2, // 儚 + 0x5121, KANJI_SJIS_L2, // 儡 + 0x513A, KANJI_SJIS_L2, // 儺 + 0x5137, KANJI_SJIS_L2, // 儷 + 0x513C, KANJI_SJIS_L2, // 儌 + 0x513B, KANJI_SJIS_L2, // 儻 + 0x513F, KANJI_SJIS_L2, // 儿 + 0x5140, KANJI_SJIS_L2, // 兀 + 0x5152, KANJI_SJIS_L2, // 兒 + 0x514C, KANJI_SJIS_L2, // 兌 + 0x5154, KANJI_SJIS_L2, // 兔 + 0x5162, KANJI_SJIS_L2, // 兢 + 0x7AF8, KANJI_SJIS_L2, // 竞 + 0x5169, KANJI_SJIS_L2, // 兩 + 0x516A, KANJI_SJIS_L2, // 兪 + 0x516E, KANJI_SJIS_L2, // 兮 + 0x5180, KANJI_SJIS_L2, // 冀 + 0x5182, KANJI_SJIS_L2, // 冂 + 0x56D8, KANJI_SJIS_L2, // 囘 + 0x518C, KANJI_SJIS_L2, // 册 + 0x5189, KANJI_SJIS_L2, // 冉 + 0x518F, KANJI_SJIS_L2, // 冏 + 0x5191, KANJI_SJIS_L2, // 冑 + 0x5193, KANJI_SJIS_L2, // 冓 + 0x5195, KANJI_SJIS_L2, // 冕 + 0x5196, KANJI_SJIS_L2, // 冖 + 0x51A4, KANJI_SJIS_L2, // 冀 + 0x51A6, KANJI_SJIS_L2, // 冊 + 0x51A2, KANJI_SJIS_L2, // 冢 + 0x51A9, KANJI_SJIS_L2, // 冩 + 0x51AA, KANJI_SJIS_L2, // 冪 + 0x51AB, KANJI_SJIS_L2, // 冫 + 0x51B3, KANJI_SJIS_L2, // 决 + 0x51B1, KANJI_SJIS_L2, // 冱 + 0x51B2, KANJI_SJIS_L2, // 冲 + 0x51B0, KANJI_SJIS_L2, // 冰 + 0x51B5, KANJI_SJIS_L2, // 况 + 0x51BD, KANJI_SJIS_L2, // 农 + 0x51C5, KANJI_SJIS_L2, // 凅 + 0x51C9, KANJI_SJIS_L2, // 凉 + 0x51DB, KANJI_SJIS_L2, // 凛 + 0x51E0, KANJI_SJIS_L2, // 几 + 0x8655, KANJI_SJIS_L2, // 處 + 0x51E9, KANJI_SJIS_L2, // 凩 + 0x51ED, KANJI_SJIS_L2, // 凭 + 0x3000, KANJI_SJIS_L2, //   + 0x51F0, KANJI_SJIS_L2, // 凰 + 0x51F5, KANJI_SJIS_L2, // 凵 + 0x51FE, KANJI_SJIS_L2, // 凟 + 0x5204, KANJI_SJIS_L2, // 刄 + 0x520B, KANJI_SJIS_L2, // 刋 + 0x5214, KANJI_SJIS_L2, // 刔 + 0x520E, KANJI_SJIS_L2, // 刎 + 0x5227, KANJI_SJIS_L2, // 刧 + 0x522A, KANJI_SJIS_L2, // 刪 + 0x522E, KANJI_SJIS_L2, // 刮 + 0x5233, KANJI_SJIS_L2, // 刳 + 0x5239, KANJI_SJIS_L2, // 刹 + 0x524F, KANJI_SJIS_L2, // 剏 + 0x5244, KANJI_SJIS_L2, // 剄 + 0x524B, KANJI_SJIS_L2, // 剋 + 0x524C, KANJI_SJIS_L2, // 剌 + 0x525E, KANJI_SJIS_L2, // 剞 + 0x5254, KANJI_SJIS_L2, // 剔 + 0x526A, KANJI_SJIS_L2, // 剪 + 0x5274, KANJI_SJIS_L2, // 剎 + 0x5269, KANJI_SJIS_L2, // 剩 + 0x5273, KANJI_SJIS_L2, // 剳 + 0x527F, KANJI_SJIS_L2, // 剿 + 0x527D, KANJI_SJIS_L2, // 剜 + 0x528D, KANJI_SJIS_L2, // 劍 + 0x5294, KANJI_SJIS_L2, // 劔 + 0x5292, KANJI_SJIS_L2, // 劒 + 0x5271, KANJI_SJIS_L2, // 剱 + 0x5288, KANJI_SJIS_L2, // 劈 + 0x5291, KANJI_SJIS_L2, // 劑 + 0x8FA8, KANJI_SJIS_L2, // 蟚 + 0x8FA7, KANJI_SJIS_L2, // 蟧 + 0x52AC, KANJI_SJIS_L2, // 劬 + 0x52AD, KANJI_SJIS_L2, // 劭 + 0x52BC, KANJI_SJIS_L2, // 劌 + 0x52B5, KANJI_SJIS_L2, // 劵 + 0x52C1, KANJI_SJIS_L2, // 勁 + 0x52CD, KANJI_SJIS_L2, // 勍 + 0x52D7, KANJI_SJIS_L2, // 勗 + 0x52DE, KANJI_SJIS_L2, // 勞 + 0x52E3, KANJI_SJIS_L2, // 勣 + 0x52E6, KANJI_SJIS_L2, // 勊 + 0x98ED, KANJI_SJIS_L2, // 飭 + 0x52E0, KANJI_SJIS_L2, // 勠 + 0x52F3, KANJI_SJIS_L2, // 勳 + 0x52F5, KANJI_SJIS_L2, // 勵 + 0x52F8, KANJI_SJIS_L2, // 勞 + 0x52F9, KANJI_SJIS_L2, // 勹 + 0x5306, KANJI_SJIS_L2, // 匆 + 0x5308, KANJI_SJIS_L2, // 匈 + 0x7538, KANJI_SJIS_L2, // 甾 + 0x530D, KANJI_SJIS_L2, // 匍 + 0x5310, KANJI_SJIS_L2, // 匐 + 0x530F, KANJI_SJIS_L2, // 匏 + 0x5315, KANJI_SJIS_L2, // 匕 + 0x531A, KANJI_SJIS_L2, // 匚 + 0x5323, KANJI_SJIS_L2, // 匣 + 0x532F, KANJI_SJIS_L2, // 匯 + 0x5331, KANJI_SJIS_L2, // 匱 + 0x5333, KANJI_SJIS_L2, // 匳 + 0x5338, KANJI_SJIS_L2, // 匞 + 0x5340, KANJI_SJIS_L2, // 區 + 0x5346, KANJI_SJIS_L2, // 卆 + 0x5345, KANJI_SJIS_L2, // 卅 + 0x4E17, KANJI_SJIS_L2, // 侗 + 0x5349, KANJI_SJIS_L2, // 卉 + 0x534D, KANJI_SJIS_L2, // 卍 + 0x51D6, KANJI_SJIS_L2, // 凖 + 0x535E, KANJI_SJIS_L2, // 卞 + 0x5369, KANJI_SJIS_L2, // 卩 + 0x536E, KANJI_SJIS_L2, // 卮 + 0x5918, KANJI_SJIS_L2, // 倘 + 0x537B, KANJI_SJIS_L2, // 卻 + 0x5377, KANJI_SJIS_L2, // 卷 + 0x5382, KANJI_SJIS_L2, // 厂 + 0x5396, KANJI_SJIS_L2, // 厖 + 0x53A0, KANJI_SJIS_L2, // 厠 + 0x53A6, KANJI_SJIS_L2, // 厊 + 0x53A5, KANJI_SJIS_L2, // 厥 + 0x53AE, KANJI_SJIS_L2, // 厮 + 0x53B0, KANJI_SJIS_L2, // 厰 + 0x53B6, KANJI_SJIS_L2, // 厶 + 0x53C3, KANJI_SJIS_L2, // 參 + 0x7C12, KANJI_SJIS_L2, // 簒 + 0x96D9, KANJI_SJIS_L2, // 雙 + 0x53DF, KANJI_SJIS_L2, // 叟 + 0x66FC, KANJI_SJIS_L2, // 曌 + 0x71EE, KANJI_SJIS_L2, // 燮 + 0x53EE, KANJI_SJIS_L2, // 叮 + 0x53E8, KANJI_SJIS_L2, // 叚 + 0x53ED, KANJI_SJIS_L2, // 叭 + 0x53FA, KANJI_SJIS_L2, // 叺 + 0x5401, KANJI_SJIS_L2, // 吁 + 0x543D, KANJI_SJIS_L2, // 吜 + 0x5440, KANJI_SJIS_L2, // 呀 + 0x542C, KANJI_SJIS_L2, // 听 + 0x542D, KANJI_SJIS_L2, // 吭 + 0x543C, KANJI_SJIS_L2, // 同 + 0x542E, KANJI_SJIS_L2, // 吮 + 0x5436, KANJI_SJIS_L2, // 吶 + 0x5429, KANJI_SJIS_L2, // 吩 + 0x541D, KANJI_SJIS_L2, // 吝 + 0x544E, KANJI_SJIS_L2, // 呎 + 0x548F, KANJI_SJIS_L2, // 咏 + 0x5475, KANJI_SJIS_L2, // 呵 + 0x548E, KANJI_SJIS_L2, // 咎 + 0x545F, KANJI_SJIS_L2, // 呟 + 0x5471, KANJI_SJIS_L2, // 呱 + 0x5477, KANJI_SJIS_L2, // 呷 + 0x5470, KANJI_SJIS_L2, // 呰 + 0x5492, KANJI_SJIS_L2, // 咒 + 0x547B, KANJI_SJIS_L2, // 呻 + 0x5480, KANJI_SJIS_L2, // 咀 + 0x5476, KANJI_SJIS_L2, // 呶 + 0x5484, KANJI_SJIS_L2, // 咄 + 0x5490, KANJI_SJIS_L2, // 咐 + 0x5486, KANJI_SJIS_L2, // 咆 + 0x54C7, KANJI_SJIS_L2, // 哇 + 0x54A2, KANJI_SJIS_L2, // 咢 + 0x54B8, KANJI_SJIS_L2, // å’ž + 0x54A5, KANJI_SJIS_L2, // 咥 + 0x54AC, KANJI_SJIS_L2, // 咬 + 0x54C4, KANJI_SJIS_L2, // 哄 + 0x54C8, KANJI_SJIS_L2, // 哈 + 0x54A8, KANJI_SJIS_L2, // å’š + 0x54AB, KANJI_SJIS_L2, // 咫 + 0x54C2, KANJI_SJIS_L2, // 哂 + 0x54A4, KANJI_SJIS_L2, // å’€ + 0x54BE, KANJI_SJIS_L2, // å’Ÿ + 0x54BC, KANJI_SJIS_L2, // å’Œ + 0x54D8, KANJI_SJIS_L2, // 哘 + 0x54E5, KANJI_SJIS_L2, // 哥 + 0x54E6, KANJI_SJIS_L2, // 哊 + 0x550F, KANJI_SJIS_L2, // 唏 + 0x5514, KANJI_SJIS_L2, // 唔 + 0x54FD, KANJI_SJIS_L2, // 哜 + 0x54EE, KANJI_SJIS_L2, // 哮 + 0x54ED, KANJI_SJIS_L2, // 哭 + 0x54FA, KANJI_SJIS_L2, // 哺 + 0x54E2, KANJI_SJIS_L2, // 哢 + 0x5539, KANJI_SJIS_L2, // 唹 + 0x5540, KANJI_SJIS_L2, // 啀 + 0x5563, KANJI_SJIS_L2, // 啣 + 0x554C, KANJI_SJIS_L2, // 啌 + 0x552E, KANJI_SJIS_L2, // 售 + 0x555C, KANJI_SJIS_L2, // 啜 + 0x5545, KANJI_SJIS_L2, // 啅 + 0x5556, KANJI_SJIS_L2, // 啖 + 0x5557, KANJI_SJIS_L2, // 啗 + 0x5538, KANJI_SJIS_L2, // 唞 + 0x5533, KANJI_SJIS_L2, // 唳 + 0x555D, KANJI_SJIS_L2, // 啝 + 0x5599, KANJI_SJIS_L2, // 喙 + 0x5580, KANJI_SJIS_L2, // 喀 + 0x54AF, KANJI_SJIS_L2, // 咯 + 0x558A, KANJI_SJIS_L2, // 喊 + 0x559F, KANJI_SJIS_L2, // 喟 + 0x557B, KANJI_SJIS_L2, // 啻 + 0x557E, KANJI_SJIS_L2, // 啟 + 0x5598, KANJI_SJIS_L2, // 喘 + 0x559E, KANJI_SJIS_L2, // 喞 + 0x55AE, KANJI_SJIS_L2, // 單 + 0x557C, KANJI_SJIS_L2, // 啌 + 0x5583, KANJI_SJIS_L2, // 喃 + 0x55A9, KANJI_SJIS_L2, // 喩 + 0x5587, KANJI_SJIS_L2, // 喇 + 0x55A8, KANJI_SJIS_L2, // å–š + 0x55DA, KANJI_SJIS_L2, // 嗚 + 0x55C5, KANJI_SJIS_L2, // 嗅 + 0x55DF, KANJI_SJIS_L2, // 嗟 + 0x55C4, KANJI_SJIS_L2, // 嗄 + 0x55DC, KANJI_SJIS_L2, // 嗜 + 0x55E4, KANJI_SJIS_L2, // å—€ + 0x55D4, KANJI_SJIS_L2, // 嗔 + 0x5614, KANJI_SJIS_L2, // 嘔 + 0x55F7, KANJI_SJIS_L2, // 嗷 + 0x5616, KANJI_SJIS_L2, // 嘖 + 0x55FE, KANJI_SJIS_L2, // å—Ÿ + 0x55FD, KANJI_SJIS_L2, // å—œ + 0x561B, KANJI_SJIS_L2, // 嘛 + 0x55F9, KANJI_SJIS_L2, // 嗹 + 0x564E, KANJI_SJIS_L2, // 噎 + 0x5650, KANJI_SJIS_L2, // 噐 + 0x71DF, KANJI_SJIS_L2, // 營 + 0x5634, KANJI_SJIS_L2, // 嘎 + 0x5636, KANJI_SJIS_L2, // 嘶 + 0x5632, KANJI_SJIS_L2, // 嘲 + 0x5638, KANJI_SJIS_L2, // 嘞 + 0x3000, KANJI_SJIS_L2, //   + 0x566B, KANJI_SJIS_L2, // 噫 + 0x5664, KANJI_SJIS_L2, // 噀 + 0x562F, KANJI_SJIS_L2, // 嘯 + 0x566C, KANJI_SJIS_L2, // 噬 + 0x566A, KANJI_SJIS_L2, // 噪 + 0x5686, KANJI_SJIS_L2, // 嚆 + 0x5680, KANJI_SJIS_L2, // 嚀 + 0x568A, KANJI_SJIS_L2, // 嚊 + 0x56A0, KANJI_SJIS_L2, // 嚠 + 0x5694, KANJI_SJIS_L2, // 嚔 + 0x568F, KANJI_SJIS_L2, // 嚏 + 0x56A5, KANJI_SJIS_L2, // 嚥 + 0x56AE, KANJI_SJIS_L2, // 嚮 + 0x56B6, KANJI_SJIS_L2, // 嚶 + 0x56B4, KANJI_SJIS_L2, // 嚎 + 0x56C2, KANJI_SJIS_L2, // 囂 + 0x56BC, KANJI_SJIS_L2, // 嚌 + 0x56C1, KANJI_SJIS_L2, // 囁 + 0x56C3, KANJI_SJIS_L2, // 囃 + 0x56C0, KANJI_SJIS_L2, // 囀 + 0x56C8, KANJI_SJIS_L2, // 囈 + 0x56CE, KANJI_SJIS_L2, // 囎 + 0x56D1, KANJI_SJIS_L2, // 囑 + 0x56D3, KANJI_SJIS_L2, // 囓 + 0x56D7, KANJI_SJIS_L2, // 囗 + 0x56EE, KANJI_SJIS_L2, // 囮 + 0x56F9, KANJI_SJIS_L2, // 囹 + 0x5700, KANJI_SJIS_L2, // 圀 + 0x56FF, KANJI_SJIS_L2, // 囿 + 0x5704, KANJI_SJIS_L2, // 圄 + 0x5709, KANJI_SJIS_L2, // 圉 + 0x5708, KANJI_SJIS_L2, // 圈 + 0x570B, KANJI_SJIS_L2, // 國 + 0x570D, KANJI_SJIS_L2, // 圍 + 0x5713, KANJI_SJIS_L2, // 圓 + 0x5718, KANJI_SJIS_L2, // 團 + 0x5716, KANJI_SJIS_L2, // 圖 + 0x55C7, KANJI_SJIS_L2, // 嗇 + 0x571C, KANJI_SJIS_L2, // 圜 + 0x5726, KANJI_SJIS_L2, // 圊 + 0x5737, KANJI_SJIS_L2, // 圷 + 0x5738, KANJI_SJIS_L2, // 圞 + 0x574E, KANJI_SJIS_L2, // 坎 + 0x573B, KANJI_SJIS_L2, // 圻 + 0x5740, KANJI_SJIS_L2, // 址 + 0x574F, KANJI_SJIS_L2, // 坏 + 0x5769, KANJI_SJIS_L2, // 坩 + 0x57C0, KANJI_SJIS_L2, // 埀 + 0x5788, KANJI_SJIS_L2, // 垈 + 0x5761, KANJI_SJIS_L2, // 坡 + 0x577F, KANJI_SJIS_L2, // 坿 + 0x5789, KANJI_SJIS_L2, // 垉 + 0x5793, KANJI_SJIS_L2, // 垓 + 0x57A0, KANJI_SJIS_L2, // 垠 + 0x57B3, KANJI_SJIS_L2, // 垳 + 0x57A4, KANJI_SJIS_L2, // 垀 + 0x57AA, KANJI_SJIS_L2, // 垪 + 0x57B0, KANJI_SJIS_L2, // 垰 + 0x57C3, KANJI_SJIS_L2, // 埃 + 0x57C6, KANJI_SJIS_L2, // 埆 + 0x57D4, KANJI_SJIS_L2, // 埔 + 0x57D2, KANJI_SJIS_L2, // 埒 + 0x57D3, KANJI_SJIS_L2, // 埓 + 0x580A, KANJI_SJIS_L2, // 堊 + 0x57D6, KANJI_SJIS_L2, // 埖 + 0x57E3, KANJI_SJIS_L2, // 埣 + 0x580B, KANJI_SJIS_L2, // 堋 + 0x5819, KANJI_SJIS_L2, // 堙 + 0x581D, KANJI_SJIS_L2, // 堝 + 0x5872, KANJI_SJIS_L2, // 塲 + 0x5821, KANJI_SJIS_L2, // å ¡ + 0x5862, KANJI_SJIS_L2, // å¡¢ + 0x584B, KANJI_SJIS_L2, // 塋 + 0x5870, KANJI_SJIS_L2, // å¡° + 0x6BC0, KANJI_SJIS_L2, // 毀 + 0x5852, KANJI_SJIS_L2, // 塒 + 0x583D, KANJI_SJIS_L2, // å œ + 0x5879, KANJI_SJIS_L2, // 塹 + 0x5885, KANJI_SJIS_L2, // 墅 + 0x58B9, KANJI_SJIS_L2, // 墹 + 0x589F, KANJI_SJIS_L2, // 墟 + 0x58AB, KANJI_SJIS_L2, // 墫 + 0x58BA, KANJI_SJIS_L2, // 墺 + 0x58DE, KANJI_SJIS_L2, // 壞 + 0x58BB, KANJI_SJIS_L2, // 墻 + 0x58B8, KANJI_SJIS_L2, // 增 + 0x58AE, KANJI_SJIS_L2, // 墮 + 0x58C5, KANJI_SJIS_L2, // 壅 + 0x58D3, KANJI_SJIS_L2, // 壓 + 0x58D1, KANJI_SJIS_L2, // 壑 + 0x58D7, KANJI_SJIS_L2, // 壗 + 0x58D9, KANJI_SJIS_L2, // 壙 + 0x58D8, KANJI_SJIS_L2, // 壘 + 0x58E5, KANJI_SJIS_L2, // 壥 + 0x58DC, KANJI_SJIS_L2, // 壜 + 0x58E4, KANJI_SJIS_L2, // 壀 + 0x58DF, KANJI_SJIS_L2, // 壟 + 0x58EF, KANJI_SJIS_L2, // 壯 + 0x58FA, KANJI_SJIS_L2, // 壺 + 0x58F9, KANJI_SJIS_L2, // 壹 + 0x58FB, KANJI_SJIS_L2, // 壻 + 0x58FC, KANJI_SJIS_L2, // 壌 + 0x58FD, KANJI_SJIS_L2, // 壜 + 0x5902, KANJI_SJIS_L2, // 倂 + 0x590A, KANJI_SJIS_L2, // 倊 + 0x5910, KANJI_SJIS_L2, // 倐 + 0x591B, KANJI_SJIS_L2, // 倛 + 0x68A6, KANJI_SJIS_L2, // 梊 + 0x5925, KANJI_SJIS_L2, // 倥 + 0x592C, KANJI_SJIS_L2, // 倬 + 0x592D, KANJI_SJIS_L2, // 倭 + 0x5932, KANJI_SJIS_L2, // 倲 + 0x5938, KANJI_SJIS_L2, // 倞 + 0x593E, KANJI_SJIS_L2, // 借 + 0x7AD2, KANJI_SJIS_L2, // 竒 + 0x5955, KANJI_SJIS_L2, // 奕 + 0x5950, KANJI_SJIS_L2, // 奐 + 0x594E, KANJI_SJIS_L2, // 奎 + 0x595A, KANJI_SJIS_L2, // 奚 + 0x5958, KANJI_SJIS_L2, // 奘 + 0x5962, KANJI_SJIS_L2, // 奢 + 0x5960, KANJI_SJIS_L2, // 奠 + 0x5967, KANJI_SJIS_L2, // 奧 + 0x596C, KANJI_SJIS_L2, // 奬 + 0x5969, KANJI_SJIS_L2, // 奩 + 0x5978, KANJI_SJIS_L2, // 奞 + 0x5981, KANJI_SJIS_L2, // 劁 + 0x599D, KANJI_SJIS_L2, // 劝 + 0x4F5E, KANJI_SJIS_L2, // 䜞 + 0x4FAB, KANJI_SJIS_L2, // 䟫 + 0x59A3, KANJI_SJIS_L2, // 劣 + 0x59B2, KANJI_SJIS_L2, // 劲 + 0x59C6, KANJI_SJIS_L2, // 姆 + 0x59E8, KANJI_SJIS_L2, // å§š + 0x59DC, KANJI_SJIS_L2, // 姜 + 0x598D, KANJI_SJIS_L2, // 劍 + 0x59D9, KANJI_SJIS_L2, // 姙 + 0x59DA, KANJI_SJIS_L2, // 姚 + 0x5A25, KANJI_SJIS_L2, // 嚥 + 0x5A1F, KANJI_SJIS_L2, // 嚟 + 0x5A11, KANJI_SJIS_L2, // åš‘ + 0x5A1C, KANJI_SJIS_L2, // åšœ + 0x5A09, KANJI_SJIS_L2, // 嚉 + 0x5A1A, KANJI_SJIS_L2, // åšš + 0x5A40, KANJI_SJIS_L2, // 婀 + 0x5A6C, KANJI_SJIS_L2, // 婬 + 0x5A49, KANJI_SJIS_L2, // 婉 + 0x5A35, KANJI_SJIS_L2, // åšµ + 0x5A36, KANJI_SJIS_L2, // åš¶ + 0x5A62, KANJI_SJIS_L2, // å©¢ + 0x5A6A, KANJI_SJIS_L2, // 婪 + 0x5A9A, KANJI_SJIS_L2, // 媚 + 0x5ABC, KANJI_SJIS_L2, // 媌 + 0x5ABE, KANJI_SJIS_L2, // 媟 + 0x5ACB, KANJI_SJIS_L2, // 嫋 + 0x5AC2, KANJI_SJIS_L2, // 嫂 + 0x5ABD, KANJI_SJIS_L2, // 媜 + 0x5AE3, KANJI_SJIS_L2, // å«£ + 0x5AD7, KANJI_SJIS_L2, // 嫗 + 0x5AE6, KANJI_SJIS_L2, // 嫊 + 0x5AE9, KANJI_SJIS_L2, // å«© + 0x5AD6, KANJI_SJIS_L2, // 嫖 + 0x5AFA, KANJI_SJIS_L2, // 嫺 + 0x5AFB, KANJI_SJIS_L2, // å«» + 0x5B0C, KANJI_SJIS_L2, // 嬌 + 0x5B0B, KANJI_SJIS_L2, // 嬋 + 0x5B16, KANJI_SJIS_L2, // 嬖 + 0x5B32, KANJI_SJIS_L2, // 嬲 + 0x5AD0, KANJI_SJIS_L2, // 嫐 + 0x5B2A, KANJI_SJIS_L2, // 嬪 + 0x5B36, KANJI_SJIS_L2, // 嬶 + 0x5B3E, KANJI_SJIS_L2, // 嬟 + 0x5B43, KANJI_SJIS_L2, // 孃 + 0x5B45, KANJI_SJIS_L2, // 孅 + 0x5B40, KANJI_SJIS_L2, // 孀 + 0x5B51, KANJI_SJIS_L2, // 孑 + 0x5B55, KANJI_SJIS_L2, // 孕 + 0x5B5A, KANJI_SJIS_L2, // 孚 + 0x5B5B, KANJI_SJIS_L2, // 孛 + 0x5B65, KANJI_SJIS_L2, // å­¥ + 0x5B69, KANJI_SJIS_L2, // å­© + 0x5B70, KANJI_SJIS_L2, // å­° + 0x5B73, KANJI_SJIS_L2, // å­³ + 0x5B75, KANJI_SJIS_L2, // å­µ + 0x5B78, KANJI_SJIS_L2, // å­ž + 0x6588, KANJI_SJIS_L2, // 斈 + 0x5B7A, KANJI_SJIS_L2, // å­º + 0x5B80, KANJI_SJIS_L2, // 宀 + 0x3000, KANJI_SJIS_L2, //   + 0x5B83, KANJI_SJIS_L2, // 它 + 0x5BA6, KANJI_SJIS_L2, // 宊 + 0x5BB8, KANJI_SJIS_L2, // 实 + 0x5BC3, KANJI_SJIS_L2, // 寃 + 0x5BC7, KANJI_SJIS_L2, // 寇 + 0x5BC9, KANJI_SJIS_L2, // 寉 + 0x5BD4, KANJI_SJIS_L2, // 寔 + 0x5BD0, KANJI_SJIS_L2, // 寐 + 0x5BE4, KANJI_SJIS_L2, // 寀 + 0x5BE6, KANJI_SJIS_L2, // 寊 + 0x5BE2, KANJI_SJIS_L2, // 寢 + 0x5BDE, KANJI_SJIS_L2, // 寞 + 0x5BE5, KANJI_SJIS_L2, // 寥 + 0x5BEB, KANJI_SJIS_L2, // 寫 + 0x5BF0, KANJI_SJIS_L2, // 寰 + 0x5BF6, KANJI_SJIS_L2, // 寶 + 0x5BF3, KANJI_SJIS_L2, // 寳 + 0x5C05, KANJI_SJIS_L2, // 尅 + 0x5C07, KANJI_SJIS_L2, // 將 + 0x5C08, KANJI_SJIS_L2, // 專 + 0x5C0D, KANJI_SJIS_L2, // 對 + 0x5C13, KANJI_SJIS_L2, // 尓 + 0x5C20, KANJI_SJIS_L2, // å°  + 0x5C22, KANJI_SJIS_L2, // å°¢ + 0x5C28, KANJI_SJIS_L2, // å°š + 0x5C38, KANJI_SJIS_L2, // å°ž + 0x5C39, KANJI_SJIS_L2, // å°¹ + 0x5C41, KANJI_SJIS_L2, // 屁 + 0x5C46, KANJI_SJIS_L2, // 屆 + 0x5C4E, KANJI_SJIS_L2, // 屎 + 0x5C53, KANJI_SJIS_L2, // 屓 + 0x5C50, KANJI_SJIS_L2, // 屐 + 0x5C4F, KANJI_SJIS_L2, // 屏 + 0x5B71, KANJI_SJIS_L2, // å­± + 0x5C6C, KANJI_SJIS_L2, // 屬 + 0x5C6E, KANJI_SJIS_L2, // å±® + 0x4E62, KANJI_SJIS_L2, // ä¹¢ + 0x5C76, KANJI_SJIS_L2, // å±¶ + 0x5C79, KANJI_SJIS_L2, // å±¹ + 0x5C8C, KANJI_SJIS_L2, // 岌 + 0x5C91, KANJI_SJIS_L2, // 岑 + 0x5C94, KANJI_SJIS_L2, // 岔 + 0x599B, KANJI_SJIS_L2, // 力 + 0x5CAB, KANJI_SJIS_L2, // 岫 + 0x5CBB, KANJI_SJIS_L2, // å²» + 0x5CB6, KANJI_SJIS_L2, // å²¶ + 0x5CBC, KANJI_SJIS_L2, // 岌 + 0x5CB7, KANJI_SJIS_L2, // å²· + 0x5CC5, KANJI_SJIS_L2, // 峅 + 0x5CBE, KANJI_SJIS_L2, // 岟 + 0x5CC7, KANJI_SJIS_L2, // 峇 + 0x5CD9, KANJI_SJIS_L2, // 峙 + 0x5CE9, KANJI_SJIS_L2, // 峩 + 0x5CFD, KANJI_SJIS_L2, // 峜 + 0x5CFA, KANJI_SJIS_L2, // 峺 + 0x5CED, KANJI_SJIS_L2, // å³­ + 0x5D8C, KANJI_SJIS_L2, // 嶌 + 0x5CEA, KANJI_SJIS_L2, // 峪 + 0x5D0B, KANJI_SJIS_L2, // 压 + 0x5D15, KANJI_SJIS_L2, // 厕 + 0x5D17, KANJI_SJIS_L2, // 厗 + 0x5D5C, KANJI_SJIS_L2, // 嵜 + 0x5D1F, KANJI_SJIS_L2, // 原 + 0x5D1B, KANJI_SJIS_L2, // 厛 + 0x5D11, KANJI_SJIS_L2, // 厑 + 0x5D14, KANJI_SJIS_L2, // 厔 + 0x5D22, KANJI_SJIS_L2, // 厢 + 0x5D1A, KANJI_SJIS_L2, // 厚 + 0x5D19, KANJI_SJIS_L2, // 厙 + 0x5D18, KANJI_SJIS_L2, // 厘 + 0x5D4C, KANJI_SJIS_L2, // 嵌 + 0x5D52, KANJI_SJIS_L2, // 嵒 + 0x5D4E, KANJI_SJIS_L2, // 嵎 + 0x5D4B, KANJI_SJIS_L2, // 嵋 + 0x5D6C, KANJI_SJIS_L2, // 嵬 + 0x5D73, KANJI_SJIS_L2, // åµ³ + 0x5D76, KANJI_SJIS_L2, // åµ¶ + 0x5D87, KANJI_SJIS_L2, // 嶇 + 0x5D84, KANJI_SJIS_L2, // 嶄 + 0x5D82, KANJI_SJIS_L2, // 嶂 + 0x5DA2, KANJI_SJIS_L2, // å¶¢ + 0x5D9D, KANJI_SJIS_L2, // 嶝 + 0x5DAC, KANJI_SJIS_L2, // 嶬 + 0x5DAE, KANJI_SJIS_L2, // å¶® + 0x5DBD, KANJI_SJIS_L2, // å¶œ + 0x5D90, KANJI_SJIS_L2, // 嶐 + 0x5DB7, KANJI_SJIS_L2, // å¶· + 0x5DBC, KANJI_SJIS_L2, // å¶Œ + 0x5DC9, KANJI_SJIS_L2, // 巉 + 0x5DCD, KANJI_SJIS_L2, // 巍 + 0x5DD3, KANJI_SJIS_L2, // 巓 + 0x5DD2, KANJI_SJIS_L2, // 巒 + 0x5DD6, KANJI_SJIS_L2, // 巖 + 0x5DDB, KANJI_SJIS_L2, // 巛 + 0x5DEB, KANJI_SJIS_L2, // å·« + 0x5DF2, KANJI_SJIS_L2, // å·² + 0x5DF5, KANJI_SJIS_L2, // å·µ + 0x5E0B, KANJI_SJIS_L2, // åž‹ + 0x5E1A, KANJI_SJIS_L2, // åžš + 0x5E19, KANJI_SJIS_L2, // åž™ + 0x5E11, KANJI_SJIS_L2, // åž‘ + 0x5E1B, KANJI_SJIS_L2, // åž› + 0x5E36, KANJI_SJIS_L2, // åž¶ + 0x5E37, KANJI_SJIS_L2, // åž· + 0x5E44, KANJI_SJIS_L2, // 幄 + 0x5E43, KANJI_SJIS_L2, // 幃 + 0x5E40, KANJI_SJIS_L2, // 幀 + 0x5E4E, KANJI_SJIS_L2, // 幎 + 0x5E57, KANJI_SJIS_L2, // 幗 + 0x5E54, KANJI_SJIS_L2, // 幔 + 0x5E5F, KANJI_SJIS_L2, // 幟 + 0x5E62, KANJI_SJIS_L2, // å¹¢ + 0x5E64, KANJI_SJIS_L2, // å¹€ + 0x5E47, KANJI_SJIS_L2, // 幇 + 0x5E75, KANJI_SJIS_L2, // å¹µ + 0x5E76, KANJI_SJIS_L2, // å¹¶ + 0x5E7A, KANJI_SJIS_L2, // 幺 + 0x9EBC, KANJI_SJIS_L2, // 麌 + 0x5E7F, KANJI_SJIS_L2, // 广 + 0x5EA0, KANJI_SJIS_L2, // 庠 + 0x5EC1, KANJI_SJIS_L2, // 廁 + 0x5EC2, KANJI_SJIS_L2, // 廂 + 0x5EC8, KANJI_SJIS_L2, // 廈 + 0x5ED0, KANJI_SJIS_L2, // 廐 + 0x5ECF, KANJI_SJIS_L2, // 廏 + 0x5ED6, KANJI_SJIS_L2, // 廖 + 0x5EE3, KANJI_SJIS_L2, // 廣 + 0x5EDD, KANJI_SJIS_L2, // 廝 + 0x5EDA, KANJI_SJIS_L2, // 廚 + 0x5EDB, KANJI_SJIS_L2, // 廛 + 0x5EE2, KANJI_SJIS_L2, // 廢 + 0x5EE1, KANJI_SJIS_L2, // 廡 + 0x5EE8, KANJI_SJIS_L2, // 廚 + 0x5EE9, KANJI_SJIS_L2, // 廩 + 0x5EEC, KANJI_SJIS_L2, // 廬 + 0x5EF1, KANJI_SJIS_L2, // å»± + 0x5EF3, KANJI_SJIS_L2, // 廳 + 0x5EF0, KANJI_SJIS_L2, // å»° + 0x5EF4, KANJI_SJIS_L2, // 廎 + 0x5EF8, KANJI_SJIS_L2, // 廞 + 0x5EFE, KANJI_SJIS_L2, // 廟 + 0x5F03, KANJI_SJIS_L2, // 匃 + 0x5F09, KANJI_SJIS_L2, // 匉 + 0x5F5D, KANJI_SJIS_L2, // 圝 + 0x5F5C, KANJI_SJIS_L2, // 圜 + 0x5F0B, KANJI_SJIS_L2, // 匋 + 0x5F11, KANJI_SJIS_L2, // 匑 + 0x5F16, KANJI_SJIS_L2, // 化 + 0x5F29, KANJI_SJIS_L2, // 匩 + 0x5F2D, KANJI_SJIS_L2, // 匭 + 0x5F38, KANJI_SJIS_L2, // 匞 + 0x5F41, KANJI_SJIS_L2, // 圁 + 0x5F48, KANJI_SJIS_L2, // 圈 + 0x5F4C, KANJI_SJIS_L2, // 圌 + 0x5F4E, KANJI_SJIS_L2, // 圎 + 0x5F2F, KANJI_SJIS_L2, // 匯 + 0x5F51, KANJI_SJIS_L2, // 圑 + 0x5F56, KANJI_SJIS_L2, // 圖 + 0x5F57, KANJI_SJIS_L2, // 圗 + 0x5F59, KANJI_SJIS_L2, // 圙 + 0x5F61, KANJI_SJIS_L2, // 圡 + 0x5F6D, KANJI_SJIS_L2, // 圭 + 0x5F73, KANJI_SJIS_L2, // 圳 + 0x5F77, KANJI_SJIS_L2, // 圷 + 0x5F83, KANJI_SJIS_L2, // 埃 + 0x5F82, KANJI_SJIS_L2, // 埂 + 0x5F7F, KANJI_SJIS_L2, // 圿 + 0x5F8A, KANJI_SJIS_L2, // 埊 + 0x5F88, KANJI_SJIS_L2, // 埈 + 0x5F91, KANJI_SJIS_L2, // 埑 + 0x5F87, KANJI_SJIS_L2, // 埇 + 0x5F9E, KANJI_SJIS_L2, // 埞 + 0x5F99, KANJI_SJIS_L2, // 埙 + 0x5F98, KANJI_SJIS_L2, // 埘 + 0x5FA0, KANJI_SJIS_L2, // 埠 + 0x5FA8, KANJI_SJIS_L2, // 埚 + 0x5FAD, KANJI_SJIS_L2, // 埭 + 0x5FBC, KANJI_SJIS_L2, // 埌 + 0x5FD6, KANJI_SJIS_L2, // 忖 + 0x5FFB, KANJI_SJIS_L2, // å¿» + 0x5FE4, KANJI_SJIS_L2, // å¿€ + 0x5FF8, KANJI_SJIS_L2, // 忞 + 0x5FF1, KANJI_SJIS_L2, // 忱 + 0x5FDD, KANJI_SJIS_L2, // 忝 + 0x60B3, KANJI_SJIS_L2, // 悳 + 0x5FFF, KANJI_SJIS_L2, // å¿¿ + 0x6021, KANJI_SJIS_L2, // 怡 + 0x6060, KANJI_SJIS_L2, // 恠 + 0x3000, KANJI_SJIS_L2, //   + 0x6019, KANJI_SJIS_L2, // 怙 + 0x6010, KANJI_SJIS_L2, // 怐 + 0x6029, KANJI_SJIS_L2, // 怩 + 0x600E, KANJI_SJIS_L2, // 怎 + 0x6031, KANJI_SJIS_L2, // 怱 + 0x601B, KANJI_SJIS_L2, // 怛 + 0x6015, KANJI_SJIS_L2, // 怕 + 0x602B, KANJI_SJIS_L2, // 怫 + 0x6026, KANJI_SJIS_L2, // 怊 + 0x600F, KANJI_SJIS_L2, // 怏 + 0x603A, KANJI_SJIS_L2, // 怺 + 0x605A, KANJI_SJIS_L2, // 恚 + 0x6041, KANJI_SJIS_L2, // 恁 + 0x606A, KANJI_SJIS_L2, // 恪 + 0x6077, KANJI_SJIS_L2, // 恷 + 0x605F, KANJI_SJIS_L2, // 恟 + 0x604A, KANJI_SJIS_L2, // 恊 + 0x6046, KANJI_SJIS_L2, // 恆 + 0x604D, KANJI_SJIS_L2, // 恍 + 0x6063, KANJI_SJIS_L2, // 恣 + 0x6043, KANJI_SJIS_L2, // 恃 + 0x6064, KANJI_SJIS_L2, // 恀 + 0x6042, KANJI_SJIS_L2, // 恂 + 0x606C, KANJI_SJIS_L2, // 恬 + 0x606B, KANJI_SJIS_L2, // 恫 + 0x6059, KANJI_SJIS_L2, // 恙 + 0x6081, KANJI_SJIS_L2, // 悁 + 0x608D, KANJI_SJIS_L2, // 悍 + 0x60E7, KANJI_SJIS_L2, // 惧 + 0x6083, KANJI_SJIS_L2, // 悃 + 0x609A, KANJI_SJIS_L2, // 悚 + 0x6084, KANJI_SJIS_L2, // 悄 + 0x609B, KANJI_SJIS_L2, // 悛 + 0x6096, KANJI_SJIS_L2, // 悖 + 0x6097, KANJI_SJIS_L2, // 悗 + 0x6092, KANJI_SJIS_L2, // 悒 + 0x60A7, KANJI_SJIS_L2, // 悧 + 0x608B, KANJI_SJIS_L2, // 悋 + 0x60E1, KANJI_SJIS_L2, // 惡 + 0x60B8, KANJI_SJIS_L2, // 悞 + 0x60E0, KANJI_SJIS_L2, // 惠 + 0x60D3, KANJI_SJIS_L2, // 惓 + 0x60B4, KANJI_SJIS_L2, // 悎 + 0x5FF0, KANJI_SJIS_L2, // å¿° + 0x60BD, KANJI_SJIS_L2, // 悜 + 0x60C6, KANJI_SJIS_L2, // 惆 + 0x60B5, KANJI_SJIS_L2, // 悵 + 0x60D8, KANJI_SJIS_L2, // 惘 + 0x614D, KANJI_SJIS_L2, // 慍 + 0x6115, KANJI_SJIS_L2, // 愕 + 0x6106, KANJI_SJIS_L2, // 愆 + 0x60F6, KANJI_SJIS_L2, // 惶 + 0x60F7, KANJI_SJIS_L2, // 惷 + 0x6100, KANJI_SJIS_L2, // 愀 + 0x60F4, KANJI_SJIS_L2, // 惎 + 0x60FA, KANJI_SJIS_L2, // 惺 + 0x6103, KANJI_SJIS_L2, // 愃 + 0x6121, KANJI_SJIS_L2, // 愡 + 0x60FB, KANJI_SJIS_L2, // 惻 + 0x60F1, KANJI_SJIS_L2, // 惱 + 0x610D, KANJI_SJIS_L2, // 愍 + 0x610E, KANJI_SJIS_L2, // 愎 + 0x6147, KANJI_SJIS_L2, // 慇 + 0x613E, KANJI_SJIS_L2, // 感 + 0x6128, KANJI_SJIS_L2, // 愚 + 0x6127, KANJI_SJIS_L2, // 愧 + 0x614A, KANJI_SJIS_L2, // 慊 + 0x613F, KANJI_SJIS_L2, // 愿 + 0x613C, KANJI_SJIS_L2, // 愌 + 0x612C, KANJI_SJIS_L2, // 愬 + 0x6134, KANJI_SJIS_L2, // 愎 + 0x613D, KANJI_SJIS_L2, // 愜 + 0x6142, KANJI_SJIS_L2, // 慂 + 0x6144, KANJI_SJIS_L2, // 慄 + 0x6173, KANJI_SJIS_L2, // 慳 + 0x6177, KANJI_SJIS_L2, // 慷 + 0x6158, KANJI_SJIS_L2, // 慘 + 0x6159, KANJI_SJIS_L2, // 慙 + 0x615A, KANJI_SJIS_L2, // 慚 + 0x616B, KANJI_SJIS_L2, // 慫 + 0x6174, KANJI_SJIS_L2, // æ…Ž + 0x616F, KANJI_SJIS_L2, // 慯 + 0x6165, KANJI_SJIS_L2, // 慥 + 0x6171, KANJI_SJIS_L2, // 慱 + 0x615F, KANJI_SJIS_L2, // 慟 + 0x615D, KANJI_SJIS_L2, // 慝 + 0x6153, KANJI_SJIS_L2, // 慓 + 0x6175, KANJI_SJIS_L2, // 慵 + 0x6199, KANJI_SJIS_L2, // 憙 + 0x6196, KANJI_SJIS_L2, // 憖 + 0x6187, KANJI_SJIS_L2, // 憇 + 0x61AC, KANJI_SJIS_L2, // 憬 + 0x6194, KANJI_SJIS_L2, // 憔 + 0x619A, KANJI_SJIS_L2, // 憚 + 0x618A, KANJI_SJIS_L2, // 憊 + 0x6191, KANJI_SJIS_L2, // 憑 + 0x61AB, KANJI_SJIS_L2, // 憫 + 0x61AE, KANJI_SJIS_L2, // 憮 + 0x61CC, KANJI_SJIS_L2, // 懌 + 0x61CA, KANJI_SJIS_L2, // 懊 + 0x61C9, KANJI_SJIS_L2, // 應 + 0x61F7, KANJI_SJIS_L2, // 懷 + 0x61C8, KANJI_SJIS_L2, // 懈 + 0x61C3, KANJI_SJIS_L2, // 懃 + 0x61C6, KANJI_SJIS_L2, // 懆 + 0x61BA, KANJI_SJIS_L2, // 憺 + 0x61CB, KANJI_SJIS_L2, // 懋 + 0x7F79, KANJI_SJIS_L2, // 眹 + 0x61CD, KANJI_SJIS_L2, // 懍 + 0x61E6, KANJI_SJIS_L2, // 懊 + 0x61E3, KANJI_SJIS_L2, // 懣 + 0x61F6, KANJI_SJIS_L2, // 懶 + 0x61FA, KANJI_SJIS_L2, // 懺 + 0x61F4, KANJI_SJIS_L2, // 懎 + 0x61FF, KANJI_SJIS_L2, // 懿 + 0x61FD, KANJI_SJIS_L2, // 懜 + 0x61FC, KANJI_SJIS_L2, // 懌 + 0x61FE, KANJI_SJIS_L2, // 懟 + 0x6200, KANJI_SJIS_L2, // 戀 + 0x6208, KANJI_SJIS_L2, // 戈 + 0x6209, KANJI_SJIS_L2, // 戉 + 0x620D, KANJI_SJIS_L2, // 戍 + 0x620C, KANJI_SJIS_L2, // 戌 + 0x6214, KANJI_SJIS_L2, // 戔 + 0x621B, KANJI_SJIS_L2, // 戛 + 0x621E, KANJI_SJIS_L2, // 戞 + 0x6221, KANJI_SJIS_L2, // 戡 + 0x622A, KANJI_SJIS_L2, // 截 + 0x622E, KANJI_SJIS_L2, // 戮 + 0x6230, KANJI_SJIS_L2, // 戰 + 0x6232, KANJI_SJIS_L2, // 戲 + 0x6233, KANJI_SJIS_L2, // 戳 + 0x6241, KANJI_SJIS_L2, // 扁 + 0x624E, KANJI_SJIS_L2, // 扎 + 0x625E, KANJI_SJIS_L2, // 扞 + 0x6263, KANJI_SJIS_L2, // 扣 + 0x625B, KANJI_SJIS_L2, // 扛 + 0x6260, KANJI_SJIS_L2, // 扠 + 0x6268, KANJI_SJIS_L2, // 扚 + 0x627C, KANJI_SJIS_L2, // 扌 + 0x6282, KANJI_SJIS_L2, // 抂 + 0x6289, KANJI_SJIS_L2, // 抉 + 0x627E, KANJI_SJIS_L2, // 扟 + 0x6292, KANJI_SJIS_L2, // 抒 + 0x6293, KANJI_SJIS_L2, // 抓 + 0x6296, KANJI_SJIS_L2, // 抖 + 0x62D4, KANJI_SJIS_L2, // 拔 + 0x6283, KANJI_SJIS_L2, // 抃 + 0x6294, KANJI_SJIS_L2, // 抔 + 0x62D7, KANJI_SJIS_L2, // 拗 + 0x62D1, KANJI_SJIS_L2, // 拑 + 0x62BB, KANJI_SJIS_L2, // 抻 + 0x62CF, KANJI_SJIS_L2, // 拏 + 0x62FF, KANJI_SJIS_L2, // 拿 + 0x62C6, KANJI_SJIS_L2, // 拆 + 0x64D4, KANJI_SJIS_L2, // 擔 + 0x62C8, KANJI_SJIS_L2, // 拈 + 0x62DC, KANJI_SJIS_L2, // 拜 + 0x62CC, KANJI_SJIS_L2, // 拌 + 0x62CA, KANJI_SJIS_L2, // 拊 + 0x62C2, KANJI_SJIS_L2, // 拂 + 0x62C7, KANJI_SJIS_L2, // 拇 + 0x629B, KANJI_SJIS_L2, // 抛 + 0x62C9, KANJI_SJIS_L2, // 拉 + 0x630C, KANJI_SJIS_L2, // 挌 + 0x62EE, KANJI_SJIS_L2, // 拮 + 0x62F1, KANJI_SJIS_L2, // 拱 + 0x6327, KANJI_SJIS_L2, // 挧 + 0x6302, KANJI_SJIS_L2, // 挂 + 0x6308, KANJI_SJIS_L2, // 挈 + 0x62EF, KANJI_SJIS_L2, // 拯 + 0x62F5, KANJI_SJIS_L2, // 拵 + 0x6350, KANJI_SJIS_L2, // 捐 + 0x633E, KANJI_SJIS_L2, // 挟 + 0x634D, KANJI_SJIS_L2, // 捍 + 0x641C, KANJI_SJIS_L2, // 搜 + 0x634F, KANJI_SJIS_L2, // 捏 + 0x6396, KANJI_SJIS_L2, // 掖 + 0x638E, KANJI_SJIS_L2, // 掎 + 0x6380, KANJI_SJIS_L2, // 掀 + 0x63AB, KANJI_SJIS_L2, // 掫 + 0x6376, KANJI_SJIS_L2, // 捶 + 0x63A3, KANJI_SJIS_L2, // 掣 + 0x638F, KANJI_SJIS_L2, // 掏 + 0x6389, KANJI_SJIS_L2, // 掉 + 0x639F, KANJI_SJIS_L2, // 掟 + 0x63B5, KANJI_SJIS_L2, // 掵 + 0x636B, KANJI_SJIS_L2, // 捫 + 0x3000, KANJI_SJIS_L2, //   + 0x6369, KANJI_SJIS_L2, // 捩 + 0x63BE, KANJI_SJIS_L2, // 掟 + 0x63E9, KANJI_SJIS_L2, // 揩 + 0x63C0, KANJI_SJIS_L2, // 揀 + 0x63C6, KANJI_SJIS_L2, // 揆 + 0x63E3, KANJI_SJIS_L2, // 揣 + 0x63C9, KANJI_SJIS_L2, // 揉 + 0x63D2, KANJI_SJIS_L2, // 插 + 0x63F6, KANJI_SJIS_L2, // 揶 + 0x63C4, KANJI_SJIS_L2, // 揄 + 0x6416, KANJI_SJIS_L2, // 搖 + 0x6434, KANJI_SJIS_L2, // 搎 + 0x6406, KANJI_SJIS_L2, // 搆 + 0x6413, KANJI_SJIS_L2, // 搓 + 0x6426, KANJI_SJIS_L2, // 搊 + 0x6436, KANJI_SJIS_L2, // 搶 + 0x651D, KANJI_SJIS_L2, // 攝 + 0x6417, KANJI_SJIS_L2, // 搗 + 0x6428, KANJI_SJIS_L2, // 搚 + 0x640F, KANJI_SJIS_L2, // 搏 + 0x6467, KANJI_SJIS_L2, // 摧 + 0x646F, KANJI_SJIS_L2, // 摯 + 0x6476, KANJI_SJIS_L2, // 摶 + 0x644E, KANJI_SJIS_L2, // 摎 + 0x652A, KANJI_SJIS_L2, // 攪 + 0x6495, KANJI_SJIS_L2, // 撕 + 0x6493, KANJI_SJIS_L2, // 撓 + 0x64A5, KANJI_SJIS_L2, // 撥 + 0x64A9, KANJI_SJIS_L2, // 撩 + 0x6488, KANJI_SJIS_L2, // 撈 + 0x64BC, KANJI_SJIS_L2, // æ’Œ + 0x64DA, KANJI_SJIS_L2, // 據 + 0x64D2, KANJI_SJIS_L2, // 擒 + 0x64C5, KANJI_SJIS_L2, // 擅 + 0x64C7, KANJI_SJIS_L2, // 擇 + 0x64BB, KANJI_SJIS_L2, // 撻 + 0x64D8, KANJI_SJIS_L2, // 擘 + 0x64C2, KANJI_SJIS_L2, // 擂 + 0x64F1, KANJI_SJIS_L2, // 擱 + 0x64E7, KANJI_SJIS_L2, // 擧 + 0x8209, KANJI_SJIS_L2, // 舉 + 0x64E0, KANJI_SJIS_L2, // 擠 + 0x64E1, KANJI_SJIS_L2, // 擡 + 0x62AC, KANJI_SJIS_L2, // 抬 + 0x64E3, KANJI_SJIS_L2, // 擣 + 0x64EF, KANJI_SJIS_L2, // 擯 + 0x652C, KANJI_SJIS_L2, // 攬 + 0x64F6, KANJI_SJIS_L2, // 擶 + 0x64F4, KANJI_SJIS_L2, // 擎 + 0x64F2, KANJI_SJIS_L2, // 擲 + 0x64FA, KANJI_SJIS_L2, // 擺 + 0x6500, KANJI_SJIS_L2, // 攀 + 0x64FD, KANJI_SJIS_L2, // 擜 + 0x6518, KANJI_SJIS_L2, // 攘 + 0x651C, KANJI_SJIS_L2, // 攜 + 0x6505, KANJI_SJIS_L2, // 攅 + 0x6524, KANJI_SJIS_L2, // 攀 + 0x6523, KANJI_SJIS_L2, // 攣 + 0x652B, KANJI_SJIS_L2, // 攫 + 0x6534, KANJI_SJIS_L2, // 攎 + 0x6535, KANJI_SJIS_L2, // 攵 + 0x6537, KANJI_SJIS_L2, // 攷 + 0x6536, KANJI_SJIS_L2, // 收 + 0x6538, KANJI_SJIS_L2, // 攞 + 0x754B, KANJI_SJIS_L2, // 畋 + 0x6548, KANJI_SJIS_L2, // 效 + 0x6556, KANJI_SJIS_L2, // 敖 + 0x6555, KANJI_SJIS_L2, // 敕 + 0x654D, KANJI_SJIS_L2, // 敍 + 0x6558, KANJI_SJIS_L2, // 敘 + 0x655E, KANJI_SJIS_L2, // 敞 + 0x655D, KANJI_SJIS_L2, // 敝 + 0x6572, KANJI_SJIS_L2, // 敲 + 0x6578, KANJI_SJIS_L2, // 敞 + 0x6582, KANJI_SJIS_L2, // 斂 + 0x6583, KANJI_SJIS_L2, // 斃 + 0x8B8A, KANJI_SJIS_L2, // 變 + 0x659B, KANJI_SJIS_L2, // 斛 + 0x659F, KANJI_SJIS_L2, // 斟 + 0x65AB, KANJI_SJIS_L2, // 斫 + 0x65B7, KANJI_SJIS_L2, // 斷 + 0x65C3, KANJI_SJIS_L2, // 旃 + 0x65C6, KANJI_SJIS_L2, // 旆 + 0x65C1, KANJI_SJIS_L2, // 旁 + 0x65C4, KANJI_SJIS_L2, // 旄 + 0x65CC, KANJI_SJIS_L2, // 旌 + 0x65D2, KANJI_SJIS_L2, // 旒 + 0x65DB, KANJI_SJIS_L2, // 旛 + 0x65D9, KANJI_SJIS_L2, // 旙 + 0x65E0, KANJI_SJIS_L2, // 无 + 0x65E1, KANJI_SJIS_L2, // 旡 + 0x65F1, KANJI_SJIS_L2, // 旱 + 0x6772, KANJI_SJIS_L2, // 杲 + 0x660A, KANJI_SJIS_L2, // 昊 + 0x6603, KANJI_SJIS_L2, // 昃 + 0x65FB, KANJI_SJIS_L2, // 旻 + 0x6773, KANJI_SJIS_L2, // 杳 + 0x6635, KANJI_SJIS_L2, // 昵 + 0x6636, KANJI_SJIS_L2, // 昶 + 0x6634, KANJI_SJIS_L2, // 明 + 0x661C, KANJI_SJIS_L2, // 昜 + 0x664F, KANJI_SJIS_L2, // 晏 + 0x6644, KANJI_SJIS_L2, // 晄 + 0x6649, KANJI_SJIS_L2, // 晉 + 0x6641, KANJI_SJIS_L2, // 晁 + 0x665E, KANJI_SJIS_L2, // 晞 + 0x665D, KANJI_SJIS_L2, // 晝 + 0x6664, KANJI_SJIS_L2, // 晀 + 0x6667, KANJI_SJIS_L2, // 晧 + 0x6668, KANJI_SJIS_L2, // 晚 + 0x665F, KANJI_SJIS_L2, // 晟 + 0x6662, KANJI_SJIS_L2, // 晢 + 0x6670, KANJI_SJIS_L2, // 晰 + 0x6683, KANJI_SJIS_L2, // 暃 + 0x6688, KANJI_SJIS_L2, // 暈 + 0x668E, KANJI_SJIS_L2, // 暎 + 0x6689, KANJI_SJIS_L2, // 暉 + 0x6684, KANJI_SJIS_L2, // 暄 + 0x6698, KANJI_SJIS_L2, // 暘 + 0x669D, KANJI_SJIS_L2, // 暝 + 0x66C1, KANJI_SJIS_L2, // 曁 + 0x66B9, KANJI_SJIS_L2, // 暹 + 0x66C9, KANJI_SJIS_L2, // 曉 + 0x66BE, KANJI_SJIS_L2, // 暟 + 0x66BC, KANJI_SJIS_L2, // 暌 + 0x66C4, KANJI_SJIS_L2, // 曄 + 0x66B8, KANJI_SJIS_L2, // æšž + 0x66D6, KANJI_SJIS_L2, // 曖 + 0x66DA, KANJI_SJIS_L2, // 曚 + 0x66E0, KANJI_SJIS_L2, // 曠 + 0x663F, KANJI_SJIS_L2, // 昿 + 0x66E6, KANJI_SJIS_L2, // 曊 + 0x66E9, KANJI_SJIS_L2, // 曩 + 0x66F0, KANJI_SJIS_L2, // 曰 + 0x66F5, KANJI_SJIS_L2, // 曵 + 0x66F7, KANJI_SJIS_L2, // 曷 + 0x670F, KANJI_SJIS_L2, // 朏 + 0x6716, KANJI_SJIS_L2, // 朖 + 0x671E, KANJI_SJIS_L2, // 朞 + 0x6726, KANJI_SJIS_L2, // 朊 + 0x6727, KANJI_SJIS_L2, // 朧 + 0x9738, KANJI_SJIS_L2, // 霾 + 0x672E, KANJI_SJIS_L2, // 朮 + 0x673F, KANJI_SJIS_L2, // 朿 + 0x6736, KANJI_SJIS_L2, // 朶 + 0x6741, KANJI_SJIS_L2, // 杁 + 0x6738, KANJI_SJIS_L2, // 朞 + 0x6737, KANJI_SJIS_L2, // 朷 + 0x6746, KANJI_SJIS_L2, // 杆 + 0x675E, KANJI_SJIS_L2, // 杞 + 0x6760, KANJI_SJIS_L2, // 杠 + 0x6759, KANJI_SJIS_L2, // 杙 + 0x6763, KANJI_SJIS_L2, // 杣 + 0x6764, KANJI_SJIS_L2, // 杀 + 0x6789, KANJI_SJIS_L2, // 枉 + 0x6770, KANJI_SJIS_L2, // 杰 + 0x67A9, KANJI_SJIS_L2, // 枩 + 0x677C, KANJI_SJIS_L2, // 杌 + 0x676A, KANJI_SJIS_L2, // 杪 + 0x678C, KANJI_SJIS_L2, // 枌 + 0x678B, KANJI_SJIS_L2, // 枋 + 0x67A6, KANJI_SJIS_L2, // 枊 + 0x67A1, KANJI_SJIS_L2, // 枡 + 0x6785, KANJI_SJIS_L2, // 枅 + 0x67B7, KANJI_SJIS_L2, // 枷 + 0x67EF, KANJI_SJIS_L2, // 柯 + 0x67B4, KANJI_SJIS_L2, // 枎 + 0x67EC, KANJI_SJIS_L2, // 柬 + 0x67B3, KANJI_SJIS_L2, // 枳 + 0x67E9, KANJI_SJIS_L2, // 柩 + 0x67B8, KANJI_SJIS_L2, // æžž + 0x67E4, KANJI_SJIS_L2, // 柀 + 0x67DE, KANJI_SJIS_L2, // 柞 + 0x67DD, KANJI_SJIS_L2, // 柝 + 0x67E2, KANJI_SJIS_L2, // 柢 + 0x67EE, KANJI_SJIS_L2, // 柮 + 0x67B9, KANJI_SJIS_L2, // 枹 + 0x67CE, KANJI_SJIS_L2, // 柎 + 0x67C6, KANJI_SJIS_L2, // 柆 + 0x67E7, KANJI_SJIS_L2, // 柧 + 0x6A9C, KANJI_SJIS_L2, // 檜 + 0x681E, KANJI_SJIS_L2, // 栞 + 0x6846, KANJI_SJIS_L2, // 框 + 0x6829, KANJI_SJIS_L2, // æ © + 0x6840, KANJI_SJIS_L2, // 桀 + 0x684D, KANJI_SJIS_L2, // 桍 + 0x6832, KANJI_SJIS_L2, // æ ² + 0x684E, KANJI_SJIS_L2, // 桎 + 0x3000, KANJI_SJIS_L2, //   + 0x68B3, KANJI_SJIS_L2, // 梳 + 0x682B, KANJI_SJIS_L2, // æ « + 0x6859, KANJI_SJIS_L2, // 桙 + 0x6863, KANJI_SJIS_L2, // æ¡£ + 0x6877, KANJI_SJIS_L2, // æ¡· + 0x687F, KANJI_SJIS_L2, // æ¡¿ + 0x689F, KANJI_SJIS_L2, // 梟 + 0x688F, KANJI_SJIS_L2, // 梏 + 0x68AD, KANJI_SJIS_L2, // 梭 + 0x6894, KANJI_SJIS_L2, // 梔 + 0x689D, KANJI_SJIS_L2, // 條 + 0x689B, KANJI_SJIS_L2, // 梛 + 0x6883, KANJI_SJIS_L2, // 梃 + 0x6AAE, KANJI_SJIS_L2, // 檮 + 0x68B9, KANJI_SJIS_L2, // 梹 + 0x6874, KANJI_SJIS_L2, // 桎 + 0x68B5, KANJI_SJIS_L2, // 梵 + 0x68A0, KANJI_SJIS_L2, // 梠 + 0x68BA, KANJI_SJIS_L2, // 梺 + 0x690F, KANJI_SJIS_L2, // 怏 + 0x688D, KANJI_SJIS_L2, // 梍 + 0x687E, KANJI_SJIS_L2, // 桟 + 0x6901, KANJI_SJIS_L2, // 态 + 0x68CA, KANJI_SJIS_L2, // 棊 + 0x6908, KANJI_SJIS_L2, // 怈 + 0x68D8, KANJI_SJIS_L2, // 棘 + 0x6922, KANJI_SJIS_L2, // 怢 + 0x6926, KANJI_SJIS_L2, // 怊 + 0x68E1, KANJI_SJIS_L2, // 棡 + 0x690C, KANJI_SJIS_L2, // 怌 + 0x68CD, KANJI_SJIS_L2, // 棍 + 0x68D4, KANJI_SJIS_L2, // 棔 + 0x68E7, KANJI_SJIS_L2, // 棧 + 0x68D5, KANJI_SJIS_L2, // 棕 + 0x6936, KANJI_SJIS_L2, // 怶 + 0x6912, KANJI_SJIS_L2, // 怒 + 0x6904, KANJI_SJIS_L2, // 怄 + 0x68D7, KANJI_SJIS_L2, // 棗 + 0x68E3, KANJI_SJIS_L2, // 棣 + 0x6925, KANJI_SJIS_L2, // 急 + 0x68F9, KANJI_SJIS_L2, // 棹 + 0x68E0, KANJI_SJIS_L2, // 棠 + 0x68EF, KANJI_SJIS_L2, // 棯 + 0x6928, KANJI_SJIS_L2, // 怚 + 0x692A, KANJI_SJIS_L2, // 怪 + 0x691A, KANJI_SJIS_L2, // 怚 + 0x6923, KANJI_SJIS_L2, // 怣 + 0x6921, KANJI_SJIS_L2, // 怡 + 0x68C6, KANJI_SJIS_L2, // 棆 + 0x6979, KANJI_SJIS_L2, // 楹 + 0x6977, KANJI_SJIS_L2, // 楷 + 0x695C, KANJI_SJIS_L2, // 楜 + 0x6978, KANJI_SJIS_L2, // 楞 + 0x696B, KANJI_SJIS_L2, // 楫 + 0x6954, KANJI_SJIS_L2, // 楔 + 0x697E, KANJI_SJIS_L2, // 楟 + 0x696E, KANJI_SJIS_L2, // 楮 + 0x6939, KANJI_SJIS_L2, // 怹 + 0x6974, KANJI_SJIS_L2, // 楎 + 0x693D, KANJI_SJIS_L2, // 怜 + 0x6959, KANJI_SJIS_L2, // 楙 + 0x6930, KANJI_SJIS_L2, // 怰 + 0x6961, KANJI_SJIS_L2, // 楡 + 0x695E, KANJI_SJIS_L2, // 楞 + 0x695D, KANJI_SJIS_L2, // 楝 + 0x6981, KANJI_SJIS_L2, // 抁 + 0x696A, KANJI_SJIS_L2, // 楪 + 0x69B2, KANJI_SJIS_L2, // 抲 + 0x69AE, KANJI_SJIS_L2, // 抮 + 0x69D0, KANJI_SJIS_L2, // 槐 + 0x69BF, KANJI_SJIS_L2, // 抿 + 0x69C1, KANJI_SJIS_L2, // 槁 + 0x69D3, KANJI_SJIS_L2, // 槓 + 0x69BE, KANJI_SJIS_L2, // 抟 + 0x69CE, KANJI_SJIS_L2, // 槎 + 0x5BE8, KANJI_SJIS_L2, // 寚 + 0x69CA, KANJI_SJIS_L2, // 槊 + 0x69DD, KANJI_SJIS_L2, // 槝 + 0x69BB, KANJI_SJIS_L2, // 抻 + 0x69C3, KANJI_SJIS_L2, // 槃 + 0x69A7, KANJI_SJIS_L2, // 抧 + 0x6A2E, KANJI_SJIS_L2, // æš® + 0x6991, KANJI_SJIS_L2, // 抑 + 0x69A0, KANJI_SJIS_L2, // 抠 + 0x699C, KANJI_SJIS_L2, // 抜 + 0x6995, KANJI_SJIS_L2, // 投 + 0x69B4, KANJI_SJIS_L2, // 抎 + 0x69DE, KANJI_SJIS_L2, // 槞 + 0x69E8, KANJI_SJIS_L2, // æ§š + 0x6A02, KANJI_SJIS_L2, // æš‚ + 0x6A1B, KANJI_SJIS_L2, // æš› + 0x69FF, KANJI_SJIS_L2, // æ§¿ + 0x6B0A, KANJI_SJIS_L2, // 權 + 0x69F9, KANJI_SJIS_L2, // æ§¹ + 0x69F2, KANJI_SJIS_L2, // æ§² + 0x69E7, KANJI_SJIS_L2, // æ§§ + 0x6A05, KANJI_SJIS_L2, // æš… + 0x69B1, KANJI_SJIS_L2, // 抱 + 0x6A1E, KANJI_SJIS_L2, // 暞 + 0x69ED, KANJI_SJIS_L2, // æ§­ + 0x6A14, KANJI_SJIS_L2, // æš” + 0x69EB, KANJI_SJIS_L2, // æ§« + 0x6A0A, KANJI_SJIS_L2, // 暊 + 0x6A12, KANJI_SJIS_L2, // æš’ + 0x6AC1, KANJI_SJIS_L2, // 櫁 + 0x6A23, KANJI_SJIS_L2, // 暣 + 0x6A13, KANJI_SJIS_L2, // æš“ + 0x6A44, KANJI_SJIS_L2, // 橄 + 0x6A0C, KANJI_SJIS_L2, // 暌 + 0x6A72, KANJI_SJIS_L2, // 橲 + 0x6A36, KANJI_SJIS_L2, // æš¶ + 0x6A78, KANJI_SJIS_L2, // 橞 + 0x6A47, KANJI_SJIS_L2, // 橇 + 0x6A62, KANJI_SJIS_L2, // æ©¢ + 0x6A59, KANJI_SJIS_L2, // 橙 + 0x6A66, KANJI_SJIS_L2, // 橊 + 0x6A48, KANJI_SJIS_L2, // 橈 + 0x6A38, KANJI_SJIS_L2, // æšž + 0x6A22, KANJI_SJIS_L2, // 暢 + 0x6A90, KANJI_SJIS_L2, // 檐 + 0x6A8D, KANJI_SJIS_L2, // 檍 + 0x6AA0, KANJI_SJIS_L2, // 檠 + 0x6A84, KANJI_SJIS_L2, // 檄 + 0x6AA2, KANJI_SJIS_L2, // 檢 + 0x6AA3, KANJI_SJIS_L2, // 檣 + 0x6A97, KANJI_SJIS_L2, // 檗 + 0x8617, KANJI_SJIS_L2, // 蘗 + 0x6ABB, KANJI_SJIS_L2, // 檻 + 0x6AC3, KANJI_SJIS_L2, // 櫃 + 0x6AC2, KANJI_SJIS_L2, // 櫂 + 0x6AB8, KANJI_SJIS_L2, // 檞 + 0x6AB3, KANJI_SJIS_L2, // 檳 + 0x6AAC, KANJI_SJIS_L2, // 檬 + 0x6ADE, KANJI_SJIS_L2, // 櫞 + 0x6AD1, KANJI_SJIS_L2, // 櫑 + 0x6ADF, KANJI_SJIS_L2, // 櫟 + 0x6AAA, KANJI_SJIS_L2, // 檪 + 0x6ADA, KANJI_SJIS_L2, // 櫚 + 0x6AEA, KANJI_SJIS_L2, // 櫪 + 0x6AFB, KANJI_SJIS_L2, // æ«» + 0x6B05, KANJI_SJIS_L2, // 欅 + 0x8616, KANJI_SJIS_L2, // 蘖 + 0x6AFA, KANJI_SJIS_L2, // 櫺 + 0x6B12, KANJI_SJIS_L2, // 欒 + 0x6B16, KANJI_SJIS_L2, // 欖 + 0x9B31, KANJI_SJIS_L2, // 鬱 + 0x6B1F, KANJI_SJIS_L2, // 欟 + 0x6B38, KANJI_SJIS_L2, // 欞 + 0x6B37, KANJI_SJIS_L2, // 欷 + 0x76DC, KANJI_SJIS_L2, // 盜 + 0x6B39, KANJI_SJIS_L2, // 欹 + 0x98EE, KANJI_SJIS_L2, // 飮 + 0x6B47, KANJI_SJIS_L2, // 歇 + 0x6B43, KANJI_SJIS_L2, // 歃 + 0x6B49, KANJI_SJIS_L2, // 歉 + 0x6B50, KANJI_SJIS_L2, // 歐 + 0x6B59, KANJI_SJIS_L2, // 歙 + 0x6B54, KANJI_SJIS_L2, // 歔 + 0x6B5B, KANJI_SJIS_L2, // 歛 + 0x6B5F, KANJI_SJIS_L2, // 歟 + 0x6B61, KANJI_SJIS_L2, // æ­¡ + 0x6B78, KANJI_SJIS_L2, // æ­ž + 0x6B79, KANJI_SJIS_L2, // æ­¹ + 0x6B7F, KANJI_SJIS_L2, // æ­¿ + 0x6B80, KANJI_SJIS_L2, // 殀 + 0x6B84, KANJI_SJIS_L2, // 殄 + 0x6B83, KANJI_SJIS_L2, // 殃 + 0x6B8D, KANJI_SJIS_L2, // 殍 + 0x6B98, KANJI_SJIS_L2, // 殘 + 0x6B95, KANJI_SJIS_L2, // 殕 + 0x6B9E, KANJI_SJIS_L2, // 殞 + 0x6BA4, KANJI_SJIS_L2, // 殀 + 0x6BAA, KANJI_SJIS_L2, // 殪 + 0x6BAB, KANJI_SJIS_L2, // 殫 + 0x6BAF, KANJI_SJIS_L2, // 殯 + 0x6BB2, KANJI_SJIS_L2, // 殲 + 0x6BB1, KANJI_SJIS_L2, // æ®± + 0x6BB3, KANJI_SJIS_L2, // 殳 + 0x6BB7, KANJI_SJIS_L2, // æ®· + 0x6BBC, KANJI_SJIS_L2, // 殌 + 0x6BC6, KANJI_SJIS_L2, // 毆 + 0x6BCB, KANJI_SJIS_L2, // 毋 + 0x6BD3, KANJI_SJIS_L2, // 毓 + 0x6BDF, KANJI_SJIS_L2, // 毟 + 0x6BEC, KANJI_SJIS_L2, // 毬 + 0x6BEB, KANJI_SJIS_L2, // 毫 + 0x6BF3, KANJI_SJIS_L2, // 毳 + 0x6BEF, KANJI_SJIS_L2, // 毯 + 0x3000, KANJI_SJIS_L2, //   + 0x9EBE, KANJI_SJIS_L2, // 麟 + 0x6C08, KANJI_SJIS_L2, // 氈 + 0x6C13, KANJI_SJIS_L2, // 氓 + 0x6C14, KANJI_SJIS_L2, // 气 + 0x6C1B, KANJI_SJIS_L2, // 氛 + 0x6C24, KANJI_SJIS_L2, // æ°€ + 0x6C23, KANJI_SJIS_L2, // æ°£ + 0x6C5E, KANJI_SJIS_L2, // 汞 + 0x6C55, KANJI_SJIS_L2, // 汕 + 0x6C62, KANJI_SJIS_L2, // æ±¢ + 0x6C6A, KANJI_SJIS_L2, // 汪 + 0x6C82, KANJI_SJIS_L2, // 沂 + 0x6C8D, KANJI_SJIS_L2, // 沍 + 0x6C9A, KANJI_SJIS_L2, // 沚 + 0x6C81, KANJI_SJIS_L2, // 沁 + 0x6C9B, KANJI_SJIS_L2, // 沛 + 0x6C7E, KANJI_SJIS_L2, // 江 + 0x6C68, KANJI_SJIS_L2, // 汚 + 0x6C73, KANJI_SJIS_L2, // æ±³ + 0x6C92, KANJI_SJIS_L2, // 沒 + 0x6C90, KANJI_SJIS_L2, // 沐 + 0x6CC4, KANJI_SJIS_L2, // 泄 + 0x6CF1, KANJI_SJIS_L2, // æ³± + 0x6CD3, KANJI_SJIS_L2, // 泓 + 0x6CBD, KANJI_SJIS_L2, // 沜 + 0x6CD7, KANJI_SJIS_L2, // 泗 + 0x6CC5, KANJI_SJIS_L2, // 泅 + 0x6CDD, KANJI_SJIS_L2, // 泝 + 0x6CAE, KANJI_SJIS_L2, // æ²® + 0x6CB1, KANJI_SJIS_L2, // æ²± + 0x6CBE, KANJI_SJIS_L2, // 沟 + 0x6CBA, KANJI_SJIS_L2, // 沺 + 0x6CDB, KANJI_SJIS_L2, // 泛 + 0x6CEF, KANJI_SJIS_L2, // 泯 + 0x6CD9, KANJI_SJIS_L2, // 泙 + 0x6CEA, KANJI_SJIS_L2, // 泪 + 0x6D1F, KANJI_SJIS_L2, // 掟 + 0x884D, KANJI_SJIS_L2, // 衍 + 0x6D36, KANJI_SJIS_L2, // 掶 + 0x6D2B, KANJI_SJIS_L2, // 掫 + 0x6D3D, KANJI_SJIS_L2, // 掜 + 0x6D38, KANJI_SJIS_L2, // 掞 + 0x6D19, KANJI_SJIS_L2, // 掙 + 0x6D35, KANJI_SJIS_L2, // 掵 + 0x6D33, KANJI_SJIS_L2, // 掳 + 0x6D12, KANJI_SJIS_L2, // 排 + 0x6D0C, KANJI_SJIS_L2, // 掌 + 0x6D63, KANJI_SJIS_L2, // æµ£ + 0x6D93, KANJI_SJIS_L2, // 涓 + 0x6D64, KANJI_SJIS_L2, // æµ€ + 0x6D5A, KANJI_SJIS_L2, // 浚 + 0x6D79, KANJI_SJIS_L2, // æµ¹ + 0x6D59, KANJI_SJIS_L2, // 浙 + 0x6D8E, KANJI_SJIS_L2, // 涎 + 0x6D95, KANJI_SJIS_L2, // 涕 + 0x6FE4, KANJI_SJIS_L2, // æ¿€ + 0x6D85, KANJI_SJIS_L2, // 涅 + 0x6DF9, KANJI_SJIS_L2, // æ·¹ + 0x6E15, KANJI_SJIS_L2, // æž• + 0x6E0A, KANJI_SJIS_L2, // 枊 + 0x6DB5, KANJI_SJIS_L2, // æ¶µ + 0x6DC7, KANJI_SJIS_L2, // 淇 + 0x6DE6, KANJI_SJIS_L2, // æ·Š + 0x6DB8, KANJI_SJIS_L2, // æ¶ž + 0x6DC6, KANJI_SJIS_L2, // 淆 + 0x6DEC, KANJI_SJIS_L2, // æ·¬ + 0x6DDE, KANJI_SJIS_L2, // 淞 + 0x6DCC, KANJI_SJIS_L2, // 淌 + 0x6DE8, KANJI_SJIS_L2, // æ·š + 0x6DD2, KANJI_SJIS_L2, // 淒 + 0x6DC5, KANJI_SJIS_L2, // 淅 + 0x6DFA, KANJI_SJIS_L2, // æ·º + 0x6DD9, KANJI_SJIS_L2, // 淙 + 0x6DE4, KANJI_SJIS_L2, // æ·€ + 0x6DD5, KANJI_SJIS_L2, // 淕 + 0x6DEA, KANJI_SJIS_L2, // æ·ª + 0x6DEE, KANJI_SJIS_L2, // æ·® + 0x6E2D, KANJI_SJIS_L2, // æž­ + 0x6E6E, KANJI_SJIS_L2, // æ¹® + 0x6E2E, KANJI_SJIS_L2, // æž® + 0x6E19, KANJI_SJIS_L2, // æž™ + 0x6E72, KANJI_SJIS_L2, // æ¹² + 0x6E5F, KANJI_SJIS_L2, // 湟 + 0x6E3E, KANJI_SJIS_L2, // 枟 + 0x6E23, KANJI_SJIS_L2, // 枣 + 0x6E6B, KANJI_SJIS_L2, // 湫 + 0x6E2B, KANJI_SJIS_L2, // æž« + 0x6E76, KANJI_SJIS_L2, // æ¹¶ + 0x6E4D, KANJI_SJIS_L2, // 湍 + 0x6E1F, KANJI_SJIS_L2, // 枟 + 0x6E43, KANJI_SJIS_L2, // 湃 + 0x6E3A, KANJI_SJIS_L2, // 枺 + 0x6E4E, KANJI_SJIS_L2, // 湎 + 0x6E24, KANJI_SJIS_L2, // 枀 + 0x6EFF, KANJI_SJIS_L2, // 滿 + 0x6E1D, KANJI_SJIS_L2, // 枝 + 0x6E38, KANJI_SJIS_L2, // æžž + 0x6E82, KANJI_SJIS_L2, // 溂 + 0x6EAA, KANJI_SJIS_L2, // 溪 + 0x6E98, KANJI_SJIS_L2, // 溘 + 0x6EC9, KANJI_SJIS_L2, // 滉 + 0x6EB7, KANJI_SJIS_L2, // 溷 + 0x6ED3, KANJI_SJIS_L2, // 滓 + 0x6EBD, KANJI_SJIS_L2, // 溜 + 0x6EAF, KANJI_SJIS_L2, // 溯 + 0x6EC4, KANJI_SJIS_L2, // 滄 + 0x6EB2, KANJI_SJIS_L2, // 溲 + 0x6ED4, KANJI_SJIS_L2, // 滔 + 0x6ED5, KANJI_SJIS_L2, // 滕 + 0x6E8F, KANJI_SJIS_L2, // 溏 + 0x6EA5, KANJI_SJIS_L2, // 溥 + 0x6EC2, KANJI_SJIS_L2, // 滂 + 0x6E9F, KANJI_SJIS_L2, // 溟 + 0x6F41, KANJI_SJIS_L2, // 朁 + 0x6F11, KANJI_SJIS_L2, // 挑 + 0x704C, KANJI_SJIS_L2, // 灌 + 0x6EEC, KANJI_SJIS_L2, // 滬 + 0x6EF8, KANJI_SJIS_L2, // 滞 + 0x6EFE, KANJI_SJIS_L2, // 滟 + 0x6F3F, KANJI_SJIS_L2, // 挿 + 0x6EF2, KANJI_SJIS_L2, // 滲 + 0x6F31, KANJI_SJIS_L2, // 挱 + 0x6EEF, KANJI_SJIS_L2, // 滯 + 0x6F32, KANJI_SJIS_L2, // 挲 + 0x6ECC, KANJI_SJIS_L2, // 滌 + 0x6F3E, KANJI_SJIS_L2, // 挟 + 0x6F13, KANJI_SJIS_L2, // 挓 + 0x6EF7, KANJI_SJIS_L2, // æ»· + 0x6F86, KANJI_SJIS_L2, // 柆 + 0x6F7A, KANJI_SJIS_L2, // 机 + 0x6F78, KANJI_SJIS_L2, // 朞 + 0x6F81, KANJI_SJIS_L2, // 柁 + 0x6F80, KANJI_SJIS_L2, // 柀 + 0x6F6F, KANJI_SJIS_L2, // 术 + 0x6F5B, KANJI_SJIS_L2, // 望 + 0x6FF3, KANJI_SJIS_L2, // 濳 + 0x6F6D, KANJI_SJIS_L2, // 札 + 0x6F82, KANJI_SJIS_L2, // 柂 + 0x6F7C, KANJI_SJIS_L2, // 朌 + 0x6F58, KANJI_SJIS_L2, // 朘 + 0x6F8E, KANJI_SJIS_L2, // 柎 + 0x6F91, KANJI_SJIS_L2, // 柑 + 0x6FC2, KANJI_SJIS_L2, // 濂 + 0x6F66, KANJI_SJIS_L2, // 朊 + 0x6FB3, KANJI_SJIS_L2, // 柳 + 0x6FA3, KANJI_SJIS_L2, // 柣 + 0x6FA1, KANJI_SJIS_L2, // 柡 + 0x6FA4, KANJI_SJIS_L2, // 柀 + 0x6FB9, KANJI_SJIS_L2, // 柹 + 0x6FC6, KANJI_SJIS_L2, // 濆 + 0x6FAA, KANJI_SJIS_L2, // 柪 + 0x6FDF, KANJI_SJIS_L2, // 濟 + 0x6FD5, KANJI_SJIS_L2, // 濕 + 0x6FEC, KANJI_SJIS_L2, // 濬 + 0x6FD4, KANJI_SJIS_L2, // 濔 + 0x6FD8, KANJI_SJIS_L2, // 濘 + 0x6FF1, KANJI_SJIS_L2, // 濱 + 0x6FEE, KANJI_SJIS_L2, // æ¿® + 0x6FDB, KANJI_SJIS_L2, // 濛 + 0x7009, KANJI_SJIS_L2, // 瀉 + 0x700B, KANJI_SJIS_L2, // 瀋 + 0x6FFA, KANJI_SJIS_L2, // 濺 + 0x7011, KANJI_SJIS_L2, // 瀑 + 0x7001, KANJI_SJIS_L2, // 瀁 + 0x700F, KANJI_SJIS_L2, // 瀏 + 0x6FFE, KANJI_SJIS_L2, // 濟 + 0x701B, KANJI_SJIS_L2, // 瀛 + 0x701A, KANJI_SJIS_L2, // 瀚 + 0x6F74, KANJI_SJIS_L2, // 朎 + 0x701D, KANJI_SJIS_L2, // 瀝 + 0x7018, KANJI_SJIS_L2, // 瀘 + 0x701F, KANJI_SJIS_L2, // 瀟 + 0x7030, KANJI_SJIS_L2, // 瀰 + 0x703E, KANJI_SJIS_L2, // 瀟 + 0x7032, KANJI_SJIS_L2, // 瀲 + 0x7051, KANJI_SJIS_L2, // 灑 + 0x7063, KANJI_SJIS_L2, // 灣 + 0x7099, KANJI_SJIS_L2, // 炙 + 0x7092, KANJI_SJIS_L2, // 炒 + 0x70AF, KANJI_SJIS_L2, // 炯 + 0x70F1, KANJI_SJIS_L2, // 烱 + 0x70AC, KANJI_SJIS_L2, // 炬 + 0x70B8, KANJI_SJIS_L2, // 炾 + 0x70B3, KANJI_SJIS_L2, // 炳 + 0x70AE, KANJI_SJIS_L2, // 炮 + 0x70DF, KANJI_SJIS_L2, // 烟 + 0x70CB, KANJI_SJIS_L2, // 烋 + 0x70DD, KANJI_SJIS_L2, // 烝 + 0x3000, KANJI_SJIS_L2, //   + 0x70D9, KANJI_SJIS_L2, // 烙 + 0x7109, KANJI_SJIS_L2, // 焉 + 0x70FD, KANJI_SJIS_L2, // 烜 + 0x711C, KANJI_SJIS_L2, // 焜 + 0x7119, KANJI_SJIS_L2, // 焙 + 0x7165, KANJI_SJIS_L2, // 煥 + 0x7155, KANJI_SJIS_L2, // 煕 + 0x7188, KANJI_SJIS_L2, // 熈 + 0x7166, KANJI_SJIS_L2, // 煩 + 0x7162, KANJI_SJIS_L2, // 煢 + 0x714C, KANJI_SJIS_L2, // 煌 + 0x7156, KANJI_SJIS_L2, // 煖 + 0x716C, KANJI_SJIS_L2, // 煬 + 0x718F, KANJI_SJIS_L2, // 熏 + 0x71FB, KANJI_SJIS_L2, // 燻 + 0x7184, KANJI_SJIS_L2, // 熄 + 0x7195, KANJI_SJIS_L2, // 熕 + 0x71A8, KANJI_SJIS_L2, // 熹 + 0x71AC, KANJI_SJIS_L2, // 熬 + 0x71D7, KANJI_SJIS_L2, // 燗 + 0x71B9, KANJI_SJIS_L2, // 熹 + 0x71BE, KANJI_SJIS_L2, // 熟 + 0x71D2, KANJI_SJIS_L2, // 燒 + 0x71C9, KANJI_SJIS_L2, // 燉 + 0x71D4, KANJI_SJIS_L2, // 燔 + 0x71CE, KANJI_SJIS_L2, // 燎 + 0x71E0, KANJI_SJIS_L2, // 燠 + 0x71EC, KANJI_SJIS_L2, // 燬 + 0x71E7, KANJI_SJIS_L2, // 燧 + 0x71F5, KANJI_SJIS_L2, // 燵 + 0x71FC, KANJI_SJIS_L2, // 燌 + 0x71F9, KANJI_SJIS_L2, // 燹 + 0x71FF, KANJI_SJIS_L2, // 燿 + 0x720D, KANJI_SJIS_L2, // 爍 + 0x7210, KANJI_SJIS_L2, // 爐 + 0x721B, KANJI_SJIS_L2, // 爛 + 0x7228, KANJI_SJIS_L2, // 爚 + 0x722D, KANJI_SJIS_L2, // 爭 + 0x722C, KANJI_SJIS_L2, // 爬 + 0x7230, KANJI_SJIS_L2, // 爰 + 0x7232, KANJI_SJIS_L2, // 爲 + 0x723B, KANJI_SJIS_L2, // 爻 + 0x723C, KANJI_SJIS_L2, // 爌 + 0x723F, KANJI_SJIS_L2, // 爿 + 0x7240, KANJI_SJIS_L2, // 牀 + 0x7246, KANJI_SJIS_L2, // 牆 + 0x724B, KANJI_SJIS_L2, // 牋 + 0x7258, KANJI_SJIS_L2, // 牘 + 0x7274, KANJI_SJIS_L2, // 牮 + 0x727E, KANJI_SJIS_L2, // 牟 + 0x7282, KANJI_SJIS_L2, // 犂 + 0x7281, KANJI_SJIS_L2, // 犁 + 0x7287, KANJI_SJIS_L2, // 犇 + 0x7292, KANJI_SJIS_L2, // 犒 + 0x7296, KANJI_SJIS_L2, // 犖 + 0x72A2, KANJI_SJIS_L2, // 犢 + 0x72A7, KANJI_SJIS_L2, // 犧 + 0x72B9, KANJI_SJIS_L2, // 犹 + 0x72B2, KANJI_SJIS_L2, // 犲 + 0x72C3, KANJI_SJIS_L2, // 狃 + 0x72C6, KANJI_SJIS_L2, // 狆 + 0x72C4, KANJI_SJIS_L2, // 狄 + 0x72CE, KANJI_SJIS_L2, // 狎 + 0x72D2, KANJI_SJIS_L2, // 狒 + 0x72E2, KANJI_SJIS_L2, // 狢 + 0x72E0, KANJI_SJIS_L2, // 狠 + 0x72E1, KANJI_SJIS_L2, // 狡 + 0x72F9, KANJI_SJIS_L2, // 狹 + 0x72F7, KANJI_SJIS_L2, // 狷 + 0x500F, KANJI_SJIS_L2, // 倏 + 0x7317, KANJI_SJIS_L2, // 猗 + 0x730A, KANJI_SJIS_L2, // 猊 + 0x731C, KANJI_SJIS_L2, // 猜 + 0x7316, KANJI_SJIS_L2, // 猖 + 0x731D, KANJI_SJIS_L2, // 猝 + 0x7334, KANJI_SJIS_L2, // 献 + 0x732F, KANJI_SJIS_L2, // 猯 + 0x7329, KANJI_SJIS_L2, // 猩 + 0x7325, KANJI_SJIS_L2, // 猥 + 0x733E, KANJI_SJIS_L2, // 猟 + 0x734E, KANJI_SJIS_L2, // 獎 + 0x734F, KANJI_SJIS_L2, // 獏 + 0x9ED8, KANJI_SJIS_L2, // 默 + 0x7357, KANJI_SJIS_L2, // 獗 + 0x736A, KANJI_SJIS_L2, // 獪 + 0x7368, KANJI_SJIS_L2, // 獚 + 0x7370, KANJI_SJIS_L2, // 獰 + 0x7378, KANJI_SJIS_L2, // 獞 + 0x7375, KANJI_SJIS_L2, // 獵 + 0x737B, KANJI_SJIS_L2, // 獻 + 0x737A, KANJI_SJIS_L2, // 獺 + 0x73C8, KANJI_SJIS_L2, // 珈 + 0x73B3, KANJI_SJIS_L2, // 玳 + 0x73CE, KANJI_SJIS_L2, // 珎 + 0x73BB, KANJI_SJIS_L2, // 玻 + 0x73C0, KANJI_SJIS_L2, // 珀 + 0x73E5, KANJI_SJIS_L2, // 珥 + 0x73EE, KANJI_SJIS_L2, // 珮 + 0x73DE, KANJI_SJIS_L2, // 珞 + 0x74A2, KANJI_SJIS_L2, // 璢 + 0x7405, KANJI_SJIS_L2, // 琅 + 0x746F, KANJI_SJIS_L2, // 瑯 + 0x7425, KANJI_SJIS_L2, // 琥 + 0x73F8, KANJI_SJIS_L2, // 珞 + 0x7432, KANJI_SJIS_L2, // 琲 + 0x743A, KANJI_SJIS_L2, // 琺 + 0x7455, KANJI_SJIS_L2, // 瑕 + 0x743F, KANJI_SJIS_L2, // 琿 + 0x745F, KANJI_SJIS_L2, // 瑟 + 0x7459, KANJI_SJIS_L2, // 瑙 + 0x7441, KANJI_SJIS_L2, // 瑁 + 0x745C, KANJI_SJIS_L2, // 瑜 + 0x7469, KANJI_SJIS_L2, // 瑩 + 0x7470, KANJI_SJIS_L2, // 瑰 + 0x7463, KANJI_SJIS_L2, // 瑣 + 0x746A, KANJI_SJIS_L2, // 瑪 + 0x7476, KANJI_SJIS_L2, // 瑶 + 0x747E, KANJI_SJIS_L2, // 瑟 + 0x748B, KANJI_SJIS_L2, // 璋 + 0x749E, KANJI_SJIS_L2, // 璞 + 0x74A7, KANJI_SJIS_L2, // 璧 + 0x74CA, KANJI_SJIS_L2, // 瓊 + 0x74CF, KANJI_SJIS_L2, // 瓏 + 0x74D4, KANJI_SJIS_L2, // 瓔 + 0x73F1, KANJI_SJIS_L2, // 珱 + 0x74E0, KANJI_SJIS_L2, // 瓠 + 0x74E3, KANJI_SJIS_L2, // 瓣 + 0x74E7, KANJI_SJIS_L2, // 瓧 + 0x74E9, KANJI_SJIS_L2, // 瓩 + 0x74EE, KANJI_SJIS_L2, // 瓮 + 0x74F2, KANJI_SJIS_L2, // 瓲 + 0x74F0, KANJI_SJIS_L2, // 瓰 + 0x74F1, KANJI_SJIS_L2, // 瓱 + 0x74F8, KANJI_SJIS_L2, // 瓾 + 0x74F7, KANJI_SJIS_L2, // 瓷 + 0x7504, KANJI_SJIS_L2, // 甄 + 0x7503, KANJI_SJIS_L2, // 甃 + 0x7505, KANJI_SJIS_L2, // 甅 + 0x750C, KANJI_SJIS_L2, // 甌 + 0x750E, KANJI_SJIS_L2, // 甎 + 0x750D, KANJI_SJIS_L2, // 甍 + 0x7515, KANJI_SJIS_L2, // 甕 + 0x7513, KANJI_SJIS_L2, // 甓 + 0x751E, KANJI_SJIS_L2, // 甞 + 0x7526, KANJI_SJIS_L2, // 甩 + 0x752C, KANJI_SJIS_L2, // 甬 + 0x753C, KANJI_SJIS_L2, // 甌 + 0x7544, KANJI_SJIS_L2, // 畄 + 0x754D, KANJI_SJIS_L2, // 畍 + 0x754A, KANJI_SJIS_L2, // 畊 + 0x7549, KANJI_SJIS_L2, // 畉 + 0x755B, KANJI_SJIS_L2, // 畛 + 0x7546, KANJI_SJIS_L2, // 畆 + 0x755A, KANJI_SJIS_L2, // 畚 + 0x7569, KANJI_SJIS_L2, // 畩 + 0x7564, KANJI_SJIS_L2, // ç•€ + 0x7567, KANJI_SJIS_L2, // 畧 + 0x756B, KANJI_SJIS_L2, // 畫 + 0x756D, KANJI_SJIS_L2, // 畭 + 0x7578, KANJI_SJIS_L2, // 畾 + 0x7576, KANJI_SJIS_L2, // 當 + 0x7586, KANJI_SJIS_L2, // 疆 + 0x7587, KANJI_SJIS_L2, // 疇 + 0x7574, KANJI_SJIS_L2, // 畮 + 0x758A, KANJI_SJIS_L2, // 疊 + 0x7589, KANJI_SJIS_L2, // 疉 + 0x7582, KANJI_SJIS_L2, // 疂 + 0x7594, KANJI_SJIS_L2, // 疔 + 0x759A, KANJI_SJIS_L2, // 疚 + 0x759D, KANJI_SJIS_L2, // 疝 + 0x75A5, KANJI_SJIS_L2, // 疥 + 0x75A3, KANJI_SJIS_L2, // 疣 + 0x75C2, KANJI_SJIS_L2, // 痂 + 0x75B3, KANJI_SJIS_L2, // 疳 + 0x75C3, KANJI_SJIS_L2, // 痃 + 0x75B5, KANJI_SJIS_L2, // 疵 + 0x75BD, KANJI_SJIS_L2, // ç–œ + 0x75B8, KANJI_SJIS_L2, // 疾 + 0x75BC, KANJI_SJIS_L2, // ç–Œ + 0x75B1, KANJI_SJIS_L2, // 疱 + 0x75CD, KANJI_SJIS_L2, // 痍 + 0x75CA, KANJI_SJIS_L2, // 痊 + 0x75D2, KANJI_SJIS_L2, // 痒 + 0x75D9, KANJI_SJIS_L2, // 痙 + 0x75E3, KANJI_SJIS_L2, // 痣 + 0x75DE, KANJI_SJIS_L2, // 痞 + 0x75FE, KANJI_SJIS_L2, // ç—Ÿ + 0x75FF, KANJI_SJIS_L2, // 痿 + 0x3000, KANJI_SJIS_L2, //   + 0x75FC, KANJI_SJIS_L2, // ç—Œ + 0x7601, KANJI_SJIS_L2, // 瘁 + 0x75F0, KANJI_SJIS_L2, // 痰 + 0x75FA, KANJI_SJIS_L2, // 痺 + 0x75F2, KANJI_SJIS_L2, // 痲 + 0x75F3, KANJI_SJIS_L2, // 痳 + 0x760B, KANJI_SJIS_L2, // 瘋 + 0x760D, KANJI_SJIS_L2, // 瘍 + 0x7609, KANJI_SJIS_L2, // 瘉 + 0x761F, KANJI_SJIS_L2, // 瘟 + 0x7627, KANJI_SJIS_L2, // 瘧 + 0x7620, KANJI_SJIS_L2, // 瘠 + 0x7621, KANJI_SJIS_L2, // 瘡 + 0x7622, KANJI_SJIS_L2, // 瘢 + 0x7624, KANJI_SJIS_L2, // 瘀 + 0x7634, KANJI_SJIS_L2, // 瘎 + 0x7630, KANJI_SJIS_L2, // 瘰 + 0x763B, KANJI_SJIS_L2, // 瘻 + 0x7647, KANJI_SJIS_L2, // 癇 + 0x7648, KANJI_SJIS_L2, // 癈 + 0x7646, KANJI_SJIS_L2, // 癆 + 0x765C, KANJI_SJIS_L2, // 癜 + 0x7658, KANJI_SJIS_L2, // 癘 + 0x7661, KANJI_SJIS_L2, // 癡 + 0x7662, KANJI_SJIS_L2, // 癢 + 0x7668, KANJI_SJIS_L2, // 癹 + 0x7669, KANJI_SJIS_L2, // 癩 + 0x766A, KANJI_SJIS_L2, // 癪 + 0x7667, KANJI_SJIS_L2, // 癧 + 0x766C, KANJI_SJIS_L2, // 癬 + 0x7670, KANJI_SJIS_L2, // 癰 + 0x7672, KANJI_SJIS_L2, // 癲 + 0x7676, KANJI_SJIS_L2, // 癶 + 0x7678, KANJI_SJIS_L2, // 百 + 0x767C, KANJI_SJIS_L2, // 癌 + 0x7680, KANJI_SJIS_L2, // 皀 + 0x7683, KANJI_SJIS_L2, // 皃 + 0x7688, KANJI_SJIS_L2, // 皈 + 0x768B, KANJI_SJIS_L2, // 皋 + 0x768E, KANJI_SJIS_L2, // 皎 + 0x7696, KANJI_SJIS_L2, // 皖 + 0x7693, KANJI_SJIS_L2, // 皓 + 0x7699, KANJI_SJIS_L2, // 皙 + 0x769A, KANJI_SJIS_L2, // 皚 + 0x76B0, KANJI_SJIS_L2, // 皰 + 0x76B4, KANJI_SJIS_L2, // 皮 + 0x76B8, KANJI_SJIS_L2, // 皾 + 0x76B9, KANJI_SJIS_L2, // 皹 + 0x76BA, KANJI_SJIS_L2, // 皺 + 0x76C2, KANJI_SJIS_L2, // 盂 + 0x76CD, KANJI_SJIS_L2, // 盍 + 0x76D6, KANJI_SJIS_L2, // 盖 + 0x76D2, KANJI_SJIS_L2, // 盒 + 0x76DE, KANJI_SJIS_L2, // 盞 + 0x76E1, KANJI_SJIS_L2, // 盡 + 0x76E5, KANJI_SJIS_L2, // 盥 + 0x76E7, KANJI_SJIS_L2, // 盧 + 0x76EA, KANJI_SJIS_L2, // 盪 + 0x862F, KANJI_SJIS_L2, // 蘯 + 0x76FB, KANJI_SJIS_L2, // 盻 + 0x7708, KANJI_SJIS_L2, // 眈 + 0x7707, KANJI_SJIS_L2, // 眇 + 0x7704, KANJI_SJIS_L2, // 眄 + 0x7729, KANJI_SJIS_L2, // 眩 + 0x7724, KANJI_SJIS_L2, // 眀 + 0x771E, KANJI_SJIS_L2, // 眞 + 0x7725, KANJI_SJIS_L2, // 眥 + 0x7726, KANJI_SJIS_L2, // 眩 + 0x771B, KANJI_SJIS_L2, // 眛 + 0x7737, KANJI_SJIS_L2, // 眷 + 0x7738, KANJI_SJIS_L2, // 眾 + 0x7747, KANJI_SJIS_L2, // 睇 + 0x775A, KANJI_SJIS_L2, // 睚 + 0x7768, KANJI_SJIS_L2, // 睚 + 0x776B, KANJI_SJIS_L2, // 睫 + 0x775B, KANJI_SJIS_L2, // 睛 + 0x7765, KANJI_SJIS_L2, // 睥 + 0x777F, KANJI_SJIS_L2, // 睿 + 0x777E, KANJI_SJIS_L2, // 睟 + 0x7779, KANJI_SJIS_L2, // 睹 + 0x778E, KANJI_SJIS_L2, // 瞎 + 0x778B, KANJI_SJIS_L2, // 瞋 + 0x7791, KANJI_SJIS_L2, // 瞑 + 0x77A0, KANJI_SJIS_L2, // 瞠 + 0x779E, KANJI_SJIS_L2, // 瞞 + 0x77B0, KANJI_SJIS_L2, // 瞰 + 0x77B6, KANJI_SJIS_L2, // 瞶 + 0x77B9, KANJI_SJIS_L2, // 瞹 + 0x77BF, KANJI_SJIS_L2, // 瞿 + 0x77BC, KANJI_SJIS_L2, // 瞌 + 0x77BD, KANJI_SJIS_L2, // 瞜 + 0x77BB, KANJI_SJIS_L2, // 瞻 + 0x77C7, KANJI_SJIS_L2, // 矇 + 0x77CD, KANJI_SJIS_L2, // 矍 + 0x77D7, KANJI_SJIS_L2, // 矗 + 0x77DA, KANJI_SJIS_L2, // 矚 + 0x77DC, KANJI_SJIS_L2, // 矜 + 0x77E3, KANJI_SJIS_L2, // 矣 + 0x77EE, KANJI_SJIS_L2, // 矮 + 0x77FC, KANJI_SJIS_L2, // 矌 + 0x780C, KANJI_SJIS_L2, // 砌 + 0x7812, KANJI_SJIS_L2, // 砒 + 0x7926, KANJI_SJIS_L2, // 瀊 + 0x7820, KANJI_SJIS_L2, // ç   + 0x792A, KANJI_SJIS_L2, // 瀪 + 0x7845, KANJI_SJIS_L2, // 硅 + 0x788E, KANJI_SJIS_L2, // 碎 + 0x7874, KANJI_SJIS_L2, // 硎 + 0x7886, KANJI_SJIS_L2, // 碆 + 0x787C, KANJI_SJIS_L2, // 硌 + 0x789A, KANJI_SJIS_L2, // 碚 + 0x788C, KANJI_SJIS_L2, // 碌 + 0x78A3, KANJI_SJIS_L2, // 碣 + 0x78B5, KANJI_SJIS_L2, // 碵 + 0x78AA, KANJI_SJIS_L2, // 碪 + 0x78AF, KANJI_SJIS_L2, // 碯 + 0x78D1, KANJI_SJIS_L2, // 磑 + 0x78C6, KANJI_SJIS_L2, // 磆 + 0x78CB, KANJI_SJIS_L2, // 磋 + 0x78D4, KANJI_SJIS_L2, // 磔 + 0x78BE, KANJI_SJIS_L2, // 碟 + 0x78BC, KANJI_SJIS_L2, // 碌 + 0x78C5, KANJI_SJIS_L2, // 磅 + 0x78CA, KANJI_SJIS_L2, // 磊 + 0x78EC, KANJI_SJIS_L2, // 磬 + 0x78E7, KANJI_SJIS_L2, // 磧 + 0x78DA, KANJI_SJIS_L2, // 磚 + 0x78FD, KANJI_SJIS_L2, // 磜 + 0x78F4, KANJI_SJIS_L2, // 磎 + 0x7907, KANJI_SJIS_L2, // 瀇 + 0x7912, KANJI_SJIS_L2, // 瀒 + 0x7911, KANJI_SJIS_L2, // 瀑 + 0x7919, KANJI_SJIS_L2, // 瀙 + 0x792C, KANJI_SJIS_L2, // 瀬 + 0x792B, KANJI_SJIS_L2, // 瀫 + 0x7940, KANJI_SJIS_L2, // 祀 + 0x7960, KANJI_SJIS_L2, // 祠 + 0x7957, KANJI_SJIS_L2, // 祗 + 0x795F, KANJI_SJIS_L2, // 祟 + 0x795A, KANJI_SJIS_L2, // 祚 + 0x7955, KANJI_SJIS_L2, // 祕 + 0x7953, KANJI_SJIS_L2, // 祓 + 0x797A, KANJI_SJIS_L2, // 祺 + 0x797F, KANJI_SJIS_L2, // 祿 + 0x798A, KANJI_SJIS_L2, // 穊 + 0x799D, KANJI_SJIS_L2, // 犝 + 0x79A7, KANJI_SJIS_L2, // 犧 + 0x9F4B, KANJI_SJIS_L2, // 霋 + 0x79AA, KANJI_SJIS_L2, // 犪 + 0x79AE, KANJI_SJIS_L2, // 犮 + 0x79B3, KANJI_SJIS_L2, // 犳 + 0x79B9, KANJI_SJIS_L2, // 犹 + 0x79BA, KANJI_SJIS_L2, // 犺 + 0x79C9, KANJI_SJIS_L2, // 秉 + 0x79D5, KANJI_SJIS_L2, // 秕 + 0x79E7, KANJI_SJIS_L2, // ç§§ + 0x79EC, KANJI_SJIS_L2, // 秬 + 0x79E1, KANJI_SJIS_L2, // ç§¡ + 0x79E3, KANJI_SJIS_L2, // ç§£ + 0x7A08, KANJI_SJIS_L2, // 皈 + 0x7A0D, KANJI_SJIS_L2, // 皍 + 0x7A18, KANJI_SJIS_L2, // 皘 + 0x7A19, KANJI_SJIS_L2, // 繙 + 0x7A20, KANJI_SJIS_L2, // çš  + 0x7A1F, KANJI_SJIS_L2, // 繟 + 0x7980, KANJI_SJIS_L2, // 穀 + 0x7A31, KANJI_SJIS_L2, // çš± + 0x7A3B, KANJI_SJIS_L2, // çš» + 0x7A3E, KANJI_SJIS_L2, // 皟 + 0x7A37, KANJI_SJIS_L2, // çš· + 0x7A43, KANJI_SJIS_L2, // 穃 + 0x7A57, KANJI_SJIS_L2, // 穗 + 0x7A49, KANJI_SJIS_L2, // 穉 + 0x7A61, KANJI_SJIS_L2, // ç©¡ + 0x7A62, KANJI_SJIS_L2, // ç©¢ + 0x7A69, KANJI_SJIS_L2, // ç©© + 0x9F9D, KANJI_SJIS_L2, // 韝 + 0x7A70, KANJI_SJIS_L2, // ç©° + 0x7A79, KANJI_SJIS_L2, // 穹 + 0x7A7D, KANJI_SJIS_L2, // 穜 + 0x7A88, KANJI_SJIS_L2, // 窈 + 0x7A97, KANJI_SJIS_L2, // 窗 + 0x7A95, KANJI_SJIS_L2, // 窕 + 0x7A98, KANJI_SJIS_L2, // 窘 + 0x7A96, KANJI_SJIS_L2, // 窖 + 0x7AA9, KANJI_SJIS_L2, // 窩 + 0x7AC8, KANJI_SJIS_L2, // 竈 + 0x7AB0, KANJI_SJIS_L2, // 窰 + 0x3000, KANJI_SJIS_L2, //   + 0x7AB6, KANJI_SJIS_L2, // 窶 + 0x7AC5, KANJI_SJIS_L2, // 竅 + 0x7AC4, KANJI_SJIS_L2, // 竄 + 0x7ABF, KANJI_SJIS_L2, // 窿 + 0x9083, KANJI_SJIS_L2, // 邃 + 0x7AC7, KANJI_SJIS_L2, // 竇 + 0x7ACA, KANJI_SJIS_L2, // 竊 + 0x7ACD, KANJI_SJIS_L2, // 竍 + 0x7ACF, KANJI_SJIS_L2, // 竏 + 0x7AD5, KANJI_SJIS_L2, // 竕 + 0x7AD3, KANJI_SJIS_L2, // 竓 + 0x7AD9, KANJI_SJIS_L2, // 站 + 0x7ADA, KANJI_SJIS_L2, // 竚 + 0x7ADD, KANJI_SJIS_L2, // 竝 + 0x7AE1, KANJI_SJIS_L2, // ç«¡ + 0x7AE2, KANJI_SJIS_L2, // ç«¢ + 0x7AE6, KANJI_SJIS_L2, // 竊 + 0x7AED, KANJI_SJIS_L2, // ç«­ + 0x7AF0, KANJI_SJIS_L2, // ç«° + 0x7B02, KANJI_SJIS_L2, // 笂 + 0x7B0F, KANJI_SJIS_L2, // 笏 + 0x7B0A, KANJI_SJIS_L2, // 笊 + 0x7B06, KANJI_SJIS_L2, // 笆 + 0x7B33, KANJI_SJIS_L2, // 笳 + 0x7B18, KANJI_SJIS_L2, // 笘 + 0x7B19, KANJI_SJIS_L2, // 笙 + 0x7B1E, KANJI_SJIS_L2, // 笞 + 0x7B35, KANJI_SJIS_L2, // 笵 + 0x7B28, KANJI_SJIS_L2, // 笚 + 0x7B36, KANJI_SJIS_L2, // 笶 + 0x7B50, KANJI_SJIS_L2, // 筐 + 0x7B7A, KANJI_SJIS_L2, // ç­º + 0x7B04, KANJI_SJIS_L2, // 笄 + 0x7B4D, KANJI_SJIS_L2, // 筍 + 0x7B0B, KANJI_SJIS_L2, // 笋 + 0x7B4C, KANJI_SJIS_L2, // 筌 + 0x7B45, KANJI_SJIS_L2, // 筅 + 0x7B75, KANJI_SJIS_L2, // ç­µ + 0x7B65, KANJI_SJIS_L2, // ç­¥ + 0x7B74, KANJI_SJIS_L2, // ç­Ž + 0x7B67, KANJI_SJIS_L2, // ç­§ + 0x7B70, KANJI_SJIS_L2, // ç­° + 0x7B71, KANJI_SJIS_L2, // ç­± + 0x7B6C, KANJI_SJIS_L2, // ç­¬ + 0x7B6E, KANJI_SJIS_L2, // ç­® + 0x7B9D, KANJI_SJIS_L2, // 箝 + 0x7B98, KANJI_SJIS_L2, // 箘 + 0x7B9F, KANJI_SJIS_L2, // 箟 + 0x7B8D, KANJI_SJIS_L2, // 箍 + 0x7B9C, KANJI_SJIS_L2, // 箜 + 0x7B9A, KANJI_SJIS_L2, // 箚 + 0x7B8B, KANJI_SJIS_L2, // 箋 + 0x7B92, KANJI_SJIS_L2, // 箒 + 0x7B8F, KANJI_SJIS_L2, // 箏 + 0x7B5D, KANJI_SJIS_L2, // 筝 + 0x7B99, KANJI_SJIS_L2, // 箙 + 0x7BCB, KANJI_SJIS_L2, // 篋 + 0x7BC1, KANJI_SJIS_L2, // 篁 + 0x7BCC, KANJI_SJIS_L2, // 篌 + 0x7BCF, KANJI_SJIS_L2, // 篏 + 0x7BB4, KANJI_SJIS_L2, // 箎 + 0x7BC6, KANJI_SJIS_L2, // 篆 + 0x7BDD, KANJI_SJIS_L2, // 篝 + 0x7BE9, KANJI_SJIS_L2, // 篩 + 0x7C11, KANJI_SJIS_L2, // 簑 + 0x7C14, KANJI_SJIS_L2, // 簔 + 0x7BE6, KANJI_SJIS_L2, // 篊 + 0x7BE5, KANJI_SJIS_L2, // 篥 + 0x7C60, KANJI_SJIS_L2, // ç±  + 0x7C00, KANJI_SJIS_L2, // 簀 + 0x7C07, KANJI_SJIS_L2, // 簇 + 0x7C13, KANJI_SJIS_L2, // 簓 + 0x7BF3, KANJI_SJIS_L2, // 篳 + 0x7BF7, KANJI_SJIS_L2, // 篷 + 0x7C17, KANJI_SJIS_L2, // 簗 + 0x7C0D, KANJI_SJIS_L2, // 簍 + 0x7BF6, KANJI_SJIS_L2, // 篶 + 0x7C23, KANJI_SJIS_L2, // ç°£ + 0x7C27, KANJI_SJIS_L2, // ç°§ + 0x7C2A, KANJI_SJIS_L2, // ç°ª + 0x7C1F, KANJI_SJIS_L2, // 簟 + 0x7C37, KANJI_SJIS_L2, // ç°· + 0x7C2B, KANJI_SJIS_L2, // ç°« + 0x7C3D, KANJI_SJIS_L2, // ç°œ + 0x7C4C, KANJI_SJIS_L2, // 籌 + 0x7C43, KANJI_SJIS_L2, // 籃 + 0x7C54, KANJI_SJIS_L2, // 籔 + 0x7C4F, KANJI_SJIS_L2, // 籏 + 0x7C40, KANJI_SJIS_L2, // 籀 + 0x7C50, KANJI_SJIS_L2, // 籐 + 0x7C58, KANJI_SJIS_L2, // 籘 + 0x7C5F, KANJI_SJIS_L2, // 籟 + 0x7C64, KANJI_SJIS_L2, // ç±€ + 0x7C56, KANJI_SJIS_L2, // 籖 + 0x7C65, KANJI_SJIS_L2, // ç±¥ + 0x7C6C, KANJI_SJIS_L2, // 籬 + 0x7C75, KANJI_SJIS_L2, // ç±µ + 0x7C83, KANJI_SJIS_L2, // 粃 + 0x7C90, KANJI_SJIS_L2, // 粐 + 0x7CA4, KANJI_SJIS_L2, // ç²€ + 0x7CAD, KANJI_SJIS_L2, // ç²­ + 0x7CA2, KANJI_SJIS_L2, // ç²¢ + 0x7CAB, KANJI_SJIS_L2, // 粫 + 0x7CA1, KANJI_SJIS_L2, // 粡 + 0x7CA8, KANJI_SJIS_L2, // 粚 + 0x7CB3, KANJI_SJIS_L2, // ç²³ + 0x7CB2, KANJI_SJIS_L2, // ç²² + 0x7CB1, KANJI_SJIS_L2, // ç²± + 0x7CAE, KANJI_SJIS_L2, // ç²® + 0x7CB9, KANJI_SJIS_L2, // ç²¹ + 0x7CBD, KANJI_SJIS_L2, // 粜 + 0x7CC0, KANJI_SJIS_L2, // 糀 + 0x7CC5, KANJI_SJIS_L2, // 糅 + 0x7CC2, KANJI_SJIS_L2, // 糂 + 0x7CD8, KANJI_SJIS_L2, // 糘 + 0x7CD2, KANJI_SJIS_L2, // 糒 + 0x7CDC, KANJI_SJIS_L2, // 糜 + 0x7CE2, KANJI_SJIS_L2, // ç³¢ + 0x9B3B, KANJI_SJIS_L2, // 鬻 + 0x7CEF, KANJI_SJIS_L2, // 糯 + 0x7CF2, KANJI_SJIS_L2, // ç³² + 0x7CF4, KANJI_SJIS_L2, // 糎 + 0x7CF6, KANJI_SJIS_L2, // ç³¶ + 0x7CFA, KANJI_SJIS_L2, // 糺 + 0x7D06, KANJI_SJIS_L2, // 箆 + 0x7D02, KANJI_SJIS_L2, // 箂 + 0x7D1C, KANJI_SJIS_L2, // 箜 + 0x7D15, KANJI_SJIS_L2, // 箕 + 0x7D0A, KANJI_SJIS_L2, // 箊 + 0x7D45, KANJI_SJIS_L2, // 絅 + 0x7D4B, KANJI_SJIS_L2, // 絋 + 0x7D2E, KANJI_SJIS_L2, // 玮 + 0x7D32, KANJI_SJIS_L2, // 玲 + 0x7D3F, KANJI_SJIS_L2, // 玿 + 0x7D35, KANJI_SJIS_L2, // 玵 + 0x7D46, KANJI_SJIS_L2, // 絆 + 0x7D73, KANJI_SJIS_L2, // çµ³ + 0x7D56, KANJI_SJIS_L2, // 絖 + 0x7D4E, KANJI_SJIS_L2, // 絎 + 0x7D72, KANJI_SJIS_L2, // çµ² + 0x7D68, KANJI_SJIS_L2, // 絚 + 0x7D6E, KANJI_SJIS_L2, // çµ® + 0x7D4F, KANJI_SJIS_L2, // 絏 + 0x7D63, KANJI_SJIS_L2, // çµ£ + 0x7D93, KANJI_SJIS_L2, // 經 + 0x7D89, KANJI_SJIS_L2, // 綉 + 0x7D5B, KANJI_SJIS_L2, // 絛 + 0x7D8F, KANJI_SJIS_L2, // 綏 + 0x7D7D, KANJI_SJIS_L2, // 絜 + 0x7D9B, KANJI_SJIS_L2, // 綛 + 0x7DBA, KANJI_SJIS_L2, // 綺 + 0x7DAE, KANJI_SJIS_L2, // ç¶® + 0x7DA3, KANJI_SJIS_L2, // ç¶£ + 0x7DB5, KANJI_SJIS_L2, // ç¶µ + 0x7DC7, KANJI_SJIS_L2, // 緇 + 0x7DBD, KANJI_SJIS_L2, // ç¶œ + 0x7DAB, KANJI_SJIS_L2, // ç¶« + 0x7E3D, KANJI_SJIS_L2, // çžœ + 0x7DA2, KANJI_SJIS_L2, // ç¶¢ + 0x7DAF, KANJI_SJIS_L2, // 綯 + 0x7DDC, KANJI_SJIS_L2, // 緜 + 0x7DB8, KANJI_SJIS_L2, // ç¶ž + 0x7D9F, KANJI_SJIS_L2, // 綟 + 0x7DB0, KANJI_SJIS_L2, // ç¶° + 0x7DD8, KANJI_SJIS_L2, // 緘 + 0x7DDD, KANJI_SJIS_L2, // 緝 + 0x7DE4, KANJI_SJIS_L2, // ç·€ + 0x7DDE, KANJI_SJIS_L2, // 緞 + 0x7DFB, KANJI_SJIS_L2, // ç·» + 0x7DF2, KANJI_SJIS_L2, // ç·² + 0x7DE1, KANJI_SJIS_L2, // ç·¡ + 0x7E05, KANJI_SJIS_L2, // 羅 + 0x7E0A, KANJI_SJIS_L2, // 羊 + 0x7E23, KANJI_SJIS_L2, // 瞣 + 0x7E21, KANJI_SJIS_L2, // çž¡ + 0x7E12, KANJI_SJIS_L2, // 羒 + 0x7E31, KANJI_SJIS_L2, // çž± + 0x7E1F, KANJI_SJIS_L2, // 羟 + 0x7E09, KANJI_SJIS_L2, // 羉 + 0x7E0B, KANJI_SJIS_L2, // 羋 + 0x7E22, KANJI_SJIS_L2, // 瞢 + 0x7E46, KANJI_SJIS_L2, // 繆 + 0x7E66, KANJI_SJIS_L2, // 繊 + 0x7E3B, KANJI_SJIS_L2, // çž» + 0x7E35, KANJI_SJIS_L2, // çžµ + 0x7E39, KANJI_SJIS_L2, // çž¹ + 0x7E43, KANJI_SJIS_L2, // 繃 + 0x7E37, KANJI_SJIS_L2, // çž· + 0x3000, KANJI_SJIS_L2, //   + 0x7E32, KANJI_SJIS_L2, // çž² + 0x7E3A, KANJI_SJIS_L2, // 瞺 + 0x7E67, KANJI_SJIS_L2, // ç¹§ + 0x7E5D, KANJI_SJIS_L2, // 繝 + 0x7E56, KANJI_SJIS_L2, // 繖 + 0x7E5E, KANJI_SJIS_L2, // 繞 + 0x7E59, KANJI_SJIS_L2, // 繙 + 0x7E5A, KANJI_SJIS_L2, // 繚 + 0x7E79, KANJI_SJIS_L2, // ç¹¹ + 0x7E6A, KANJI_SJIS_L2, // 繪 + 0x7E69, KANJI_SJIS_L2, // 繩 + 0x7E7C, KANJI_SJIS_L2, // 繌 + 0x7E7B, KANJI_SJIS_L2, // ç¹» + 0x7E83, KANJI_SJIS_L2, // 纃 + 0x7DD5, KANJI_SJIS_L2, // 緕 + 0x7E7D, KANJI_SJIS_L2, // 繜 + 0x8FAE, KANJI_SJIS_L2, // 蟮 + 0x7E7F, KANJI_SJIS_L2, // 繿 + 0x7E88, KANJI_SJIS_L2, // 纈 + 0x7E89, KANJI_SJIS_L2, // 纉 + 0x7E8C, KANJI_SJIS_L2, // 續 + 0x7E92, KANJI_SJIS_L2, // 纒 + 0x7E90, KANJI_SJIS_L2, // 纐 + 0x7E93, KANJI_SJIS_L2, // 纓 + 0x7E94, KANJI_SJIS_L2, // 纔 + 0x7E96, KANJI_SJIS_L2, // 纖 + 0x7E8E, KANJI_SJIS_L2, // 纎 + 0x7E9B, KANJI_SJIS_L2, // 纛 + 0x7E9C, KANJI_SJIS_L2, // 纜 + 0x7F38, KANJI_SJIS_L2, // 猞 + 0x7F3A, KANJI_SJIS_L2, // 猺 + 0x7F45, KANJI_SJIS_L2, // 眅 + 0x7F4C, KANJI_SJIS_L2, // 県 + 0x7F4D, KANJI_SJIS_L2, // 眍 + 0x7F4E, KANJI_SJIS_L2, // 眎 + 0x7F50, KANJI_SJIS_L2, // 眐 + 0x7F51, KANJI_SJIS_L2, // 眑 + 0x7F55, KANJI_SJIS_L2, // 眕 + 0x7F54, KANJI_SJIS_L2, // 眔 + 0x7F58, KANJI_SJIS_L2, // 眘 + 0x7F5F, KANJI_SJIS_L2, // 真 + 0x7F60, KANJI_SJIS_L2, // 眠 + 0x7F68, KANJI_SJIS_L2, // 眚 + 0x7F69, KANJI_SJIS_L2, // 眩 + 0x7F67, KANJI_SJIS_L2, // 眧 + 0x7F78, KANJI_SJIS_L2, // 眞 + 0x7F82, KANJI_SJIS_L2, // 矂 + 0x7F86, KANJI_SJIS_L2, // 矆 + 0x7F83, KANJI_SJIS_L2, // 矃 + 0x7F88, KANJI_SJIS_L2, // 矈 + 0x7F87, KANJI_SJIS_L2, // 矇 + 0x7F8C, KANJI_SJIS_L2, // 矌 + 0x7F94, KANJI_SJIS_L2, // 矔 + 0x7F9E, KANJI_SJIS_L2, // 矞 + 0x7F9D, KANJI_SJIS_L2, // 矝 + 0x7F9A, KANJI_SJIS_L2, // 矚 + 0x7FA3, KANJI_SJIS_L2, // 矣 + 0x7FAF, KANJI_SJIS_L2, // 矯 + 0x7FB2, KANJI_SJIS_L2, // 矲 + 0x7FB9, KANJI_SJIS_L2, // 矹 + 0x7FAE, KANJI_SJIS_L2, // 矮 + 0x7FB6, KANJI_SJIS_L2, // 矶 + 0x7FB8, KANJI_SJIS_L2, // 矞 + 0x8B71, KANJI_SJIS_L2, // è­± + 0x7FC5, KANJI_SJIS_L2, // 翅 + 0x7FC6, KANJI_SJIS_L2, // 翆 + 0x7FCA, KANJI_SJIS_L2, // 翊 + 0x7FD5, KANJI_SJIS_L2, // 翕 + 0x7FD4, KANJI_SJIS_L2, // 翔 + 0x7FE1, KANJI_SJIS_L2, // ç¿¡ + 0x7FE6, KANJI_SJIS_L2, // 翊 + 0x7FE9, KANJI_SJIS_L2, // ç¿© + 0x7FF3, KANJI_SJIS_L2, // 翳 + 0x7FF9, KANJI_SJIS_L2, // 翹 + 0x98DC, KANJI_SJIS_L2, // 飜 + 0x8006, KANJI_SJIS_L2, // 耆 + 0x8004, KANJI_SJIS_L2, // 耄 + 0x800B, KANJI_SJIS_L2, // 耋 + 0x8012, KANJI_SJIS_L2, // 耒 + 0x8018, KANJI_SJIS_L2, // 耘 + 0x8019, KANJI_SJIS_L2, // 耙 + 0x801C, KANJI_SJIS_L2, // 耜 + 0x8021, KANJI_SJIS_L2, // 耡 + 0x8028, KANJI_SJIS_L2, // 耚 + 0x803F, KANJI_SJIS_L2, // 耿 + 0x803B, KANJI_SJIS_L2, // 耻 + 0x804A, KANJI_SJIS_L2, // 聊 + 0x8046, KANJI_SJIS_L2, // 聆 + 0x8052, KANJI_SJIS_L2, // 聒 + 0x8058, KANJI_SJIS_L2, // 聘 + 0x805A, KANJI_SJIS_L2, // 聚 + 0x805F, KANJI_SJIS_L2, // 聟 + 0x8062, KANJI_SJIS_L2, // 聢 + 0x8068, KANJI_SJIS_L2, // 聚 + 0x8073, KANJI_SJIS_L2, // 聳 + 0x8072, KANJI_SJIS_L2, // 聲 + 0x8070, KANJI_SJIS_L2, // 聰 + 0x8076, KANJI_SJIS_L2, // 聶 + 0x8079, KANJI_SJIS_L2, // 聹 + 0x807D, KANJI_SJIS_L2, // 聜 + 0x807F, KANJI_SJIS_L2, // 聿 + 0x8084, KANJI_SJIS_L2, // 肄 + 0x8086, KANJI_SJIS_L2, // 肆 + 0x8085, KANJI_SJIS_L2, // 肅 + 0x809B, KANJI_SJIS_L2, // 肛 + 0x8093, KANJI_SJIS_L2, // 肓 + 0x809A, KANJI_SJIS_L2, // 肚 + 0x80AD, KANJI_SJIS_L2, // 肭 + 0x5190, KANJI_SJIS_L2, // 冐 + 0x80AC, KANJI_SJIS_L2, // 肬 + 0x80DB, KANJI_SJIS_L2, // 胛 + 0x80E5, KANJI_SJIS_L2, // 胥 + 0x80D9, KANJI_SJIS_L2, // 胙 + 0x80DD, KANJI_SJIS_L2, // 胝 + 0x80C4, KANJI_SJIS_L2, // 胄 + 0x80DA, KANJI_SJIS_L2, // 胚 + 0x80D6, KANJI_SJIS_L2, // 胖 + 0x8109, KANJI_SJIS_L2, // 脉 + 0x80EF, KANJI_SJIS_L2, // 胯 + 0x80F1, KANJI_SJIS_L2, // 胱 + 0x811B, KANJI_SJIS_L2, // 脛 + 0x8129, KANJI_SJIS_L2, // 脩 + 0x8123, KANJI_SJIS_L2, // 脣 + 0x812F, KANJI_SJIS_L2, // 脯 + 0x814B, KANJI_SJIS_L2, // 腋 + 0x968B, KANJI_SJIS_L2, // 隋 + 0x8146, KANJI_SJIS_L2, // 腆 + 0x813E, KANJI_SJIS_L2, // 脟 + 0x8153, KANJI_SJIS_L2, // 腓 + 0x8151, KANJI_SJIS_L2, // 腑 + 0x80FC, KANJI_SJIS_L2, // 背 + 0x8171, KANJI_SJIS_L2, // 腱 + 0x816E, KANJI_SJIS_L2, // 腮 + 0x8165, KANJI_SJIS_L2, // 腥 + 0x8166, KANJI_SJIS_L2, // è…Š + 0x8174, KANJI_SJIS_L2, // è…Ž + 0x8183, KANJI_SJIS_L2, // 膃 + 0x8188, KANJI_SJIS_L2, // 膈 + 0x818A, KANJI_SJIS_L2, // 膊 + 0x8180, KANJI_SJIS_L2, // 膀 + 0x8182, KANJI_SJIS_L2, // 膂 + 0x81A0, KANJI_SJIS_L2, // 膠 + 0x8195, KANJI_SJIS_L2, // 膕 + 0x81A4, KANJI_SJIS_L2, // 膀 + 0x81A3, KANJI_SJIS_L2, // 膣 + 0x815F, KANJI_SJIS_L2, // 腟 + 0x8193, KANJI_SJIS_L2, // 膓 + 0x81A9, KANJI_SJIS_L2, // 膩 + 0x81B0, KANJI_SJIS_L2, // 膰 + 0x81B5, KANJI_SJIS_L2, // 膵 + 0x81BE, KANJI_SJIS_L2, // 膟 + 0x81B8, KANJI_SJIS_L2, // 膞 + 0x81BD, KANJI_SJIS_L2, // 膜 + 0x81C0, KANJI_SJIS_L2, // 臀 + 0x81C2, KANJI_SJIS_L2, // 臂 + 0x81BA, KANJI_SJIS_L2, // 膺 + 0x81C9, KANJI_SJIS_L2, // 臉 + 0x81CD, KANJI_SJIS_L2, // 臍 + 0x81D1, KANJI_SJIS_L2, // 臑 + 0x81D9, KANJI_SJIS_L2, // 臙 + 0x81D8, KANJI_SJIS_L2, // 臘 + 0x81C8, KANJI_SJIS_L2, // 臈 + 0x81DA, KANJI_SJIS_L2, // 臚 + 0x81DF, KANJI_SJIS_L2, // 臟 + 0x81E0, KANJI_SJIS_L2, // 臠 + 0x81E7, KANJI_SJIS_L2, // 臧 + 0x81FA, KANJI_SJIS_L2, // 臺 + 0x81FB, KANJI_SJIS_L2, // 臻 + 0x81FE, KANJI_SJIS_L2, // 臟 + 0x8201, KANJI_SJIS_L2, // 舁 + 0x8202, KANJI_SJIS_L2, // 舂 + 0x8205, KANJI_SJIS_L2, // 舅 + 0x8207, KANJI_SJIS_L2, // 與 + 0x820A, KANJI_SJIS_L2, // 舊 + 0x820D, KANJI_SJIS_L2, // 舍 + 0x8210, KANJI_SJIS_L2, // 舐 + 0x8216, KANJI_SJIS_L2, // 舖 + 0x8229, KANJI_SJIS_L2, // 舩 + 0x822B, KANJI_SJIS_L2, // 舫 + 0x8238, KANJI_SJIS_L2, // 舞 + 0x8233, KANJI_SJIS_L2, // 舳 + 0x8240, KANJI_SJIS_L2, // 艀 + 0x8259, KANJI_SJIS_L2, // 艙 + 0x8258, KANJI_SJIS_L2, // 艘 + 0x825D, KANJI_SJIS_L2, // 艝 + 0x825A, KANJI_SJIS_L2, // 艚 + 0x825F, KANJI_SJIS_L2, // 艟 + 0x8264, KANJI_SJIS_L2, // 艀 + 0x3000, KANJI_SJIS_L2, //   + 0x8262, KANJI_SJIS_L2, // 艢 + 0x8268, KANJI_SJIS_L2, // 艚 + 0x826A, KANJI_SJIS_L2, // 艪 + 0x826B, KANJI_SJIS_L2, // 艫 + 0x822E, KANJI_SJIS_L2, // 舮 + 0x8271, KANJI_SJIS_L2, // 艱 + 0x8277, KANJI_SJIS_L2, // 艷 + 0x8278, KANJI_SJIS_L2, // 艞 + 0x827E, KANJI_SJIS_L2, // 艟 + 0x828D, KANJI_SJIS_L2, // 芍 + 0x8292, KANJI_SJIS_L2, // 芒 + 0x82AB, KANJI_SJIS_L2, // 芫 + 0x829F, KANJI_SJIS_L2, // 芟 + 0x82BB, KANJI_SJIS_L2, // 芻 + 0x82AC, KANJI_SJIS_L2, // 芬 + 0x82E1, KANJI_SJIS_L2, // 苡 + 0x82E3, KANJI_SJIS_L2, // 苣 + 0x82DF, KANJI_SJIS_L2, // 苟 + 0x82D2, KANJI_SJIS_L2, // 苒 + 0x82F4, KANJI_SJIS_L2, // 苎 + 0x82F3, KANJI_SJIS_L2, // 苳 + 0x82FA, KANJI_SJIS_L2, // 苺 + 0x8393, KANJI_SJIS_L2, // 莓 + 0x8303, KANJI_SJIS_L2, // 范 + 0x82FB, KANJI_SJIS_L2, // 苻 + 0x82F9, KANJI_SJIS_L2, // 苹 + 0x82DE, KANJI_SJIS_L2, // 苞 + 0x8306, KANJI_SJIS_L2, // 茆 + 0x82DC, KANJI_SJIS_L2, // 苜 + 0x8309, KANJI_SJIS_L2, // 茉 + 0x82D9, KANJI_SJIS_L2, // 苙 + 0x8335, KANJI_SJIS_L2, // 茵 + 0x8334, KANJI_SJIS_L2, // 茎 + 0x8316, KANJI_SJIS_L2, // 茖 + 0x8332, KANJI_SJIS_L2, // 茲 + 0x8331, KANJI_SJIS_L2, // 茱 + 0x8340, KANJI_SJIS_L2, // 荀 + 0x8339, KANJI_SJIS_L2, // 茹 + 0x8350, KANJI_SJIS_L2, // 荐 + 0x8345, KANJI_SJIS_L2, // 荅 + 0x832F, KANJI_SJIS_L2, // 茯 + 0x832B, KANJI_SJIS_L2, // 茫 + 0x8317, KANJI_SJIS_L2, // 茗 + 0x8318, KANJI_SJIS_L2, // 茘 + 0x8385, KANJI_SJIS_L2, // 莅 + 0x839A, KANJI_SJIS_L2, // 莚 + 0x83AA, KANJI_SJIS_L2, // 莪 + 0x839F, KANJI_SJIS_L2, // 莟 + 0x83A2, KANJI_SJIS_L2, // 莢 + 0x8396, KANJI_SJIS_L2, // 莖 + 0x8323, KANJI_SJIS_L2, // 茣 + 0x838E, KANJI_SJIS_L2, // 莎 + 0x8387, KANJI_SJIS_L2, // 莇 + 0x838A, KANJI_SJIS_L2, // 莊 + 0x837C, KANJI_SJIS_L2, // 荌 + 0x83B5, KANJI_SJIS_L2, // 莵 + 0x8373, KANJI_SJIS_L2, // 荳 + 0x8375, KANJI_SJIS_L2, // 荵 + 0x83A0, KANJI_SJIS_L2, // 莠 + 0x8389, KANJI_SJIS_L2, // 莉 + 0x83A8, KANJI_SJIS_L2, // 莚 + 0x83F4, KANJI_SJIS_L2, // 菎 + 0x8413, KANJI_SJIS_L2, // 萓 + 0x83EB, KANJI_SJIS_L2, // 菫 + 0x83CE, KANJI_SJIS_L2, // 菎 + 0x83FD, KANJI_SJIS_L2, // 菜 + 0x8403, KANJI_SJIS_L2, // 萃 + 0x83D8, KANJI_SJIS_L2, // 菘 + 0x840B, KANJI_SJIS_L2, // 萋 + 0x83C1, KANJI_SJIS_L2, // 菁 + 0x83F7, KANJI_SJIS_L2, // 菷 + 0x8407, KANJI_SJIS_L2, // 萇 + 0x83E0, KANJI_SJIS_L2, // 菠 + 0x83F2, KANJI_SJIS_L2, // 菲 + 0x840D, KANJI_SJIS_L2, // 萍 + 0x8422, KANJI_SJIS_L2, // 萢 + 0x8420, KANJI_SJIS_L2, // 萠 + 0x83BD, KANJI_SJIS_L2, // 莜 + 0x8438, KANJI_SJIS_L2, // 萞 + 0x8506, KANJI_SJIS_L2, // 蔆 + 0x83FB, KANJI_SJIS_L2, // 菻 + 0x846D, KANJI_SJIS_L2, // 葭 + 0x842A, KANJI_SJIS_L2, // 萪 + 0x843C, KANJI_SJIS_L2, // 萌 + 0x855A, KANJI_SJIS_L2, // 蕚 + 0x8484, KANJI_SJIS_L2, // 蒄 + 0x8477, KANJI_SJIS_L2, // 葷 + 0x846B, KANJI_SJIS_L2, // 葫 + 0x84AD, KANJI_SJIS_L2, // 蒭 + 0x846E, KANJI_SJIS_L2, // 葮 + 0x8482, KANJI_SJIS_L2, // 蒂 + 0x8469, KANJI_SJIS_L2, // 葩 + 0x8446, KANJI_SJIS_L2, // 葆 + 0x842C, KANJI_SJIS_L2, // 萬 + 0x846F, KANJI_SJIS_L2, // 葯 + 0x8479, KANJI_SJIS_L2, // 葹 + 0x8435, KANJI_SJIS_L2, // 萵 + 0x84CA, KANJI_SJIS_L2, // 蓊 + 0x8462, KANJI_SJIS_L2, // 葢 + 0x84B9, KANJI_SJIS_L2, // 蒹 + 0x84BF, KANJI_SJIS_L2, // 蒿 + 0x849F, KANJI_SJIS_L2, // 蒟 + 0x84D9, KANJI_SJIS_L2, // 蓙 + 0x84CD, KANJI_SJIS_L2, // 蓍 + 0x84BB, KANJI_SJIS_L2, // 蒻 + 0x84DA, KANJI_SJIS_L2, // 蓚 + 0x84D0, KANJI_SJIS_L2, // 蓐 + 0x84C1, KANJI_SJIS_L2, // 蓁 + 0x84C6, KANJI_SJIS_L2, // 蓆 + 0x84D6, KANJI_SJIS_L2, // 蓖 + 0x84A1, KANJI_SJIS_L2, // 蒡 + 0x8521, KANJI_SJIS_L2, // 蔡 + 0x84FF, KANJI_SJIS_L2, // 蓿 + 0x84F4, KANJI_SJIS_L2, // 蓎 + 0x8517, KANJI_SJIS_L2, // 蔗 + 0x8518, KANJI_SJIS_L2, // 蔘 + 0x852C, KANJI_SJIS_L2, // 蔬 + 0x851F, KANJI_SJIS_L2, // 蔟 + 0x8515, KANJI_SJIS_L2, // 蔕 + 0x8514, KANJI_SJIS_L2, // 蔔 + 0x84FC, KANJI_SJIS_L2, // 蓌 + 0x8540, KANJI_SJIS_L2, // 蕀 + 0x8563, KANJI_SJIS_L2, // 蕣 + 0x8558, KANJI_SJIS_L2, // 蕘 + 0x8548, KANJI_SJIS_L2, // 蕈 + 0x8541, KANJI_SJIS_L2, // 蕁 + 0x8602, KANJI_SJIS_L2, // 蘂 + 0x854B, KANJI_SJIS_L2, // 蕋 + 0x8555, KANJI_SJIS_L2, // 蕕 + 0x8580, KANJI_SJIS_L2, // 薀 + 0x85A4, KANJI_SJIS_L2, // è–€ + 0x8588, KANJI_SJIS_L2, // 薈 + 0x8591, KANJI_SJIS_L2, // 薑 + 0x858A, KANJI_SJIS_L2, // 薊 + 0x85A8, KANJI_SJIS_L2, // è–š + 0x856D, KANJI_SJIS_L2, // 蕭 + 0x8594, KANJI_SJIS_L2, // 薔 + 0x859B, KANJI_SJIS_L2, // 薛 + 0x85EA, KANJI_SJIS_L2, // 藪 + 0x8587, KANJI_SJIS_L2, // 薇 + 0x859C, KANJI_SJIS_L2, // 薜 + 0x8577, KANJI_SJIS_L2, // 蕷 + 0x857E, KANJI_SJIS_L2, // 蕟 + 0x8590, KANJI_SJIS_L2, // 薐 + 0x85C9, KANJI_SJIS_L2, // 藉 + 0x85BA, KANJI_SJIS_L2, // 薺 + 0x85CF, KANJI_SJIS_L2, // 藏 + 0x85B9, KANJI_SJIS_L2, // 薹 + 0x85D0, KANJI_SJIS_L2, // 藐 + 0x85D5, KANJI_SJIS_L2, // 藕 + 0x85DD, KANJI_SJIS_L2, // 藝 + 0x85E5, KANJI_SJIS_L2, // 藥 + 0x85DC, KANJI_SJIS_L2, // 藜 + 0x85F9, KANJI_SJIS_L2, // 藹 + 0x860A, KANJI_SJIS_L2, // 蘊 + 0x8613, KANJI_SJIS_L2, // 蘓 + 0x860B, KANJI_SJIS_L2, // 蘋 + 0x85FE, KANJI_SJIS_L2, // è—Ÿ + 0x85FA, KANJI_SJIS_L2, // 藺 + 0x8606, KANJI_SJIS_L2, // 蘆 + 0x8622, KANJI_SJIS_L2, // 蘢 + 0x861A, KANJI_SJIS_L2, // 蘚 + 0x8630, KANJI_SJIS_L2, // 蘰 + 0x863F, KANJI_SJIS_L2, // 蘿 + 0x864D, KANJI_SJIS_L2, // 虍 + 0x4E55, KANJI_SJIS_L2, // 乕 + 0x8654, KANJI_SJIS_L2, // 虔 + 0x865F, KANJI_SJIS_L2, // 號 + 0x8667, KANJI_SJIS_L2, // 虧 + 0x8671, KANJI_SJIS_L2, // 虱 + 0x8693, KANJI_SJIS_L2, // 蚓 + 0x86A3, KANJI_SJIS_L2, // 蚣 + 0x86A9, KANJI_SJIS_L2, // 蚩 + 0x86AA, KANJI_SJIS_L2, // 蚪 + 0x868B, KANJI_SJIS_L2, // 蚋 + 0x868C, KANJI_SJIS_L2, // 蚌 + 0x86B6, KANJI_SJIS_L2, // 蚶 + 0x86AF, KANJI_SJIS_L2, // 蚯 + 0x86C4, KANJI_SJIS_L2, // 蛄 + 0x86C6, KANJI_SJIS_L2, // 蛆 + 0x86B0, KANJI_SJIS_L2, // 蚰 + 0x86C9, KANJI_SJIS_L2, // 蛉 + 0x8823, KANJI_SJIS_L2, // è £ + 0x86AB, KANJI_SJIS_L2, // 蚫 + 0x86D4, KANJI_SJIS_L2, // 蛔 + 0x86DE, KANJI_SJIS_L2, // 蛞 + 0x86E9, KANJI_SJIS_L2, // 蛩 + 0x86EC, KANJI_SJIS_L2, // 蛬 + 0x3000, KANJI_SJIS_L2, //   + 0x86DF, KANJI_SJIS_L2, // 蛟 + 0x86DB, KANJI_SJIS_L2, // 蛛 + 0x86EF, KANJI_SJIS_L2, // 蛯 + 0x8712, KANJI_SJIS_L2, // 蜒 + 0x8706, KANJI_SJIS_L2, // 蜆 + 0x8708, KANJI_SJIS_L2, // 蜈 + 0x8700, KANJI_SJIS_L2, // 蜀 + 0x8703, KANJI_SJIS_L2, // 蜃 + 0x86FB, KANJI_SJIS_L2, // 蛻 + 0x8711, KANJI_SJIS_L2, // 蜑 + 0x8709, KANJI_SJIS_L2, // 蜉 + 0x870D, KANJI_SJIS_L2, // 蜍 + 0x86F9, KANJI_SJIS_L2, // 蛹 + 0x870A, KANJI_SJIS_L2, // 蜊 + 0x8734, KANJI_SJIS_L2, // 蜎 + 0x873F, KANJI_SJIS_L2, // 蜿 + 0x8737, KANJI_SJIS_L2, // 蜷 + 0x873B, KANJI_SJIS_L2, // 蜻 + 0x8725, KANJI_SJIS_L2, // 蜥 + 0x8729, KANJI_SJIS_L2, // 蜩 + 0x871A, KANJI_SJIS_L2, // 蜚 + 0x8760, KANJI_SJIS_L2, // 蝠 + 0x875F, KANJI_SJIS_L2, // 蝟 + 0x8778, KANJI_SJIS_L2, // 蝞 + 0x874C, KANJI_SJIS_L2, // 蝌 + 0x874E, KANJI_SJIS_L2, // 蝎 + 0x8774, KANJI_SJIS_L2, // 蝎 + 0x8757, KANJI_SJIS_L2, // 蝗 + 0x8768, KANJI_SJIS_L2, // 蝚 + 0x876E, KANJI_SJIS_L2, // 蝮 + 0x8759, KANJI_SJIS_L2, // 蝙 + 0x8753, KANJI_SJIS_L2, // 蝓 + 0x8763, KANJI_SJIS_L2, // 蝣 + 0x876A, KANJI_SJIS_L2, // 蝪 + 0x8805, KANJI_SJIS_L2, // 蠅 + 0x87A2, KANJI_SJIS_L2, // 螢 + 0x879F, KANJI_SJIS_L2, // 螟 + 0x8782, KANJI_SJIS_L2, // 螂 + 0x87AF, KANJI_SJIS_L2, // 螯 + 0x87CB, KANJI_SJIS_L2, // 蟋 + 0x87BD, KANJI_SJIS_L2, // 螜 + 0x87C0, KANJI_SJIS_L2, // 蟀 + 0x87D0, KANJI_SJIS_L2, // 蟐 + 0x96D6, KANJI_SJIS_L2, // 雖 + 0x87AB, KANJI_SJIS_L2, // 螫 + 0x87C4, KANJI_SJIS_L2, // 蟄 + 0x87B3, KANJI_SJIS_L2, // 螳 + 0x87C7, KANJI_SJIS_L2, // 蟇 + 0x87C6, KANJI_SJIS_L2, // 蟆 + 0x87BB, KANJI_SJIS_L2, // 螻 + 0x87EF, KANJI_SJIS_L2, // 蟯 + 0x87F2, KANJI_SJIS_L2, // 蟲 + 0x87E0, KANJI_SJIS_L2, // 蟠 + 0x880F, KANJI_SJIS_L2, // 蠏 + 0x880D, KANJI_SJIS_L2, // 蠍 + 0x87FE, KANJI_SJIS_L2, // 蟟 + 0x87F6, KANJI_SJIS_L2, // 蟶 + 0x87F7, KANJI_SJIS_L2, // 蟷 + 0x880E, KANJI_SJIS_L2, // 蠎 + 0x87D2, KANJI_SJIS_L2, // 蟒 + 0x8811, KANJI_SJIS_L2, // 蠑 + 0x8816, KANJI_SJIS_L2, // 蠖 + 0x8815, KANJI_SJIS_L2, // 蠕 + 0x8822, KANJI_SJIS_L2, // è ¢ + 0x8821, KANJI_SJIS_L2, // è ¡ + 0x8831, KANJI_SJIS_L2, // è ± + 0x8836, KANJI_SJIS_L2, // è ¶ + 0x8839, KANJI_SJIS_L2, // è ¹ + 0x8827, KANJI_SJIS_L2, // è § + 0x883B, KANJI_SJIS_L2, // è » + 0x8844, KANJI_SJIS_L2, // 衄 + 0x8842, KANJI_SJIS_L2, // 衂 + 0x8852, KANJI_SJIS_L2, // 衒 + 0x8859, KANJI_SJIS_L2, // 衙 + 0x885E, KANJI_SJIS_L2, // 衞 + 0x8862, KANJI_SJIS_L2, // è¡¢ + 0x886B, KANJI_SJIS_L2, // è¡« + 0x8881, KANJI_SJIS_L2, // 袁 + 0x887E, KANJI_SJIS_L2, // 衟 + 0x889E, KANJI_SJIS_L2, // 袞 + 0x8875, KANJI_SJIS_L2, // 衵 + 0x887D, KANJI_SJIS_L2, // 衜 + 0x88B5, KANJI_SJIS_L2, // 袵 + 0x8872, KANJI_SJIS_L2, // 衲 + 0x8882, KANJI_SJIS_L2, // 袂 + 0x8897, KANJI_SJIS_L2, // 袗 + 0x8892, KANJI_SJIS_L2, // 袒 + 0x88AE, KANJI_SJIS_L2, // 袮 + 0x8899, KANJI_SJIS_L2, // 袙 + 0x88A2, KANJI_SJIS_L2, // 袢 + 0x888D, KANJI_SJIS_L2, // 袍 + 0x88A4, KANJI_SJIS_L2, // 袀 + 0x88B0, KANJI_SJIS_L2, // 袰 + 0x88BF, KANJI_SJIS_L2, // 袿 + 0x88B1, KANJI_SJIS_L2, // 袱 + 0x88C3, KANJI_SJIS_L2, // 裃 + 0x88C4, KANJI_SJIS_L2, // 裄 + 0x88D4, KANJI_SJIS_L2, // 裔 + 0x88D8, KANJI_SJIS_L2, // 裘 + 0x88D9, KANJI_SJIS_L2, // 裙 + 0x88DD, KANJI_SJIS_L2, // 裝 + 0x88F9, KANJI_SJIS_L2, // 裹 + 0x8902, KANJI_SJIS_L2, // 耂 + 0x88FC, KANJI_SJIS_L2, // 裌 + 0x88F4, KANJI_SJIS_L2, // 裎 + 0x88E8, KANJI_SJIS_L2, // 裚 + 0x88F2, KANJI_SJIS_L2, // 裲 + 0x8904, KANJI_SJIS_L2, // 耄 + 0x890C, KANJI_SJIS_L2, // 而 + 0x890A, KANJI_SJIS_L2, // 耊 + 0x8913, KANJI_SJIS_L2, // 耓 + 0x8943, KANJI_SJIS_L2, // 襃 + 0x891E, KANJI_SJIS_L2, // 耞 + 0x8925, KANJI_SJIS_L2, // 耥 + 0x892A, KANJI_SJIS_L2, // 耪 + 0x892B, KANJI_SJIS_L2, // 耫 + 0x8941, KANJI_SJIS_L2, // 襁 + 0x8944, KANJI_SJIS_L2, // 襄 + 0x893B, KANJI_SJIS_L2, // 耻 + 0x8936, KANJI_SJIS_L2, // 耶 + 0x8938, KANJI_SJIS_L2, // 耞 + 0x894C, KANJI_SJIS_L2, // 襌 + 0x891D, KANJI_SJIS_L2, // 耝 + 0x8960, KANJI_SJIS_L2, // 襠 + 0x895E, KANJI_SJIS_L2, // 襞 + 0x8966, KANJI_SJIS_L2, // 襊 + 0x8964, KANJI_SJIS_L2, // 襀 + 0x896D, KANJI_SJIS_L2, // 襭 + 0x896A, KANJI_SJIS_L2, // 襪 + 0x896F, KANJI_SJIS_L2, // 襯 + 0x8974, KANJI_SJIS_L2, // 襎 + 0x8977, KANJI_SJIS_L2, // 襷 + 0x897E, KANJI_SJIS_L2, // 襟 + 0x8983, KANJI_SJIS_L2, // 芃 + 0x8988, KANJI_SJIS_L2, // 芈 + 0x898A, KANJI_SJIS_L2, // 芊 + 0x8993, KANJI_SJIS_L2, // 芓 + 0x8998, KANJI_SJIS_L2, // 芘 + 0x89A1, KANJI_SJIS_L2, // 芡 + 0x89A9, KANJI_SJIS_L2, // 芩 + 0x89A6, KANJI_SJIS_L2, // 芊 + 0x89AC, KANJI_SJIS_L2, // 芬 + 0x89AF, KANJI_SJIS_L2, // 芯 + 0x89B2, KANJI_SJIS_L2, // 芲 + 0x89BA, KANJI_SJIS_L2, // 芺 + 0x89BD, KANJI_SJIS_L2, // 芜 + 0x89BF, KANJI_SJIS_L2, // 芿 + 0x89C0, KANJI_SJIS_L2, // 觀 + 0x89DA, KANJI_SJIS_L2, // 觚 + 0x89DC, KANJI_SJIS_L2, // 觜 + 0x89DD, KANJI_SJIS_L2, // 觝 + 0x89E7, KANJI_SJIS_L2, // è§§ + 0x89F4, KANJI_SJIS_L2, // è§Ž + 0x89F8, KANJI_SJIS_L2, // è§ž + 0x8A03, KANJI_SJIS_L2, // 蚃 + 0x8A16, KANJI_SJIS_L2, // èš– + 0x8A10, KANJI_SJIS_L2, // 蚐 + 0x8A0C, KANJI_SJIS_L2, // 蚌 + 0x8A1B, KANJI_SJIS_L2, // èš› + 0x8A1D, KANJI_SJIS_L2, // 蚝 + 0x8A25, KANJI_SJIS_L2, // 蚥 + 0x8A36, KANJI_SJIS_L2, // èš¶ + 0x8A41, KANJI_SJIS_L2, // 詁 + 0x8A5B, KANJI_SJIS_L2, // 詛 + 0x8A52, KANJI_SJIS_L2, // 詒 + 0x8A46, KANJI_SJIS_L2, // 詆 + 0x8A48, KANJI_SJIS_L2, // 詈 + 0x8A7C, KANJI_SJIS_L2, // 詌 + 0x8A6D, KANJI_SJIS_L2, // è©­ + 0x8A6C, KANJI_SJIS_L2, // 詬 + 0x8A62, KANJI_SJIS_L2, // è©¢ + 0x8A85, KANJI_SJIS_L2, // 誅 + 0x8A82, KANJI_SJIS_L2, // 誂 + 0x8A84, KANJI_SJIS_L2, // 誄 + 0x8AA8, KANJI_SJIS_L2, // 誚 + 0x8AA1, KANJI_SJIS_L2, // 誡 + 0x8A91, KANJI_SJIS_L2, // 誑 + 0x8AA5, KANJI_SJIS_L2, // 誥 + 0x8AA6, KANJI_SJIS_L2, // 誊 + 0x8A9A, KANJI_SJIS_L2, // 誚 + 0x8AA3, KANJI_SJIS_L2, // 誣 + 0x8AC4, KANJI_SJIS_L2, // 諄 + 0x8ACD, KANJI_SJIS_L2, // 諍 + 0x8AC2, KANJI_SJIS_L2, // 諂 + 0x8ADA, KANJI_SJIS_L2, // 諚 + 0x8AEB, KANJI_SJIS_L2, // è«« + 0x8AF3, KANJI_SJIS_L2, // 諳 + 0x8AE7, KANJI_SJIS_L2, // è«§ + 0x3000, KANJI_SJIS_L2, //   + 0x8AE4, KANJI_SJIS_L2, // è«€ + 0x8AF1, KANJI_SJIS_L2, // 諱 + 0x8B14, KANJI_SJIS_L2, // 謔 + 0x8AE0, KANJI_SJIS_L2, // è«  + 0x8AE2, KANJI_SJIS_L2, // è«¢ + 0x8AF7, KANJI_SJIS_L2, // è«· + 0x8ADE, KANJI_SJIS_L2, // 諞 + 0x8ADB, KANJI_SJIS_L2, // 諛 + 0x8B0C, KANJI_SJIS_L2, // 謌 + 0x8B07, KANJI_SJIS_L2, // 謇 + 0x8B1A, KANJI_SJIS_L2, // 謚 + 0x8AE1, KANJI_SJIS_L2, // è«¡ + 0x8B16, KANJI_SJIS_L2, // 謖 + 0x8B10, KANJI_SJIS_L2, // 謐 + 0x8B17, KANJI_SJIS_L2, // 謗 + 0x8B20, KANJI_SJIS_L2, // 謠 + 0x8B33, KANJI_SJIS_L2, // 謳 + 0x97AB, KANJI_SJIS_L2, // 鞫 + 0x8B26, KANJI_SJIS_L2, // 謊 + 0x8B2B, KANJI_SJIS_L2, // 謫 + 0x8B3E, KANJI_SJIS_L2, // 謟 + 0x8B28, KANJI_SJIS_L2, // 謚 + 0x8B41, KANJI_SJIS_L2, // 譁 + 0x8B4C, KANJI_SJIS_L2, // 譌 + 0x8B4F, KANJI_SJIS_L2, // 譏 + 0x8B4E, KANJI_SJIS_L2, // 譎 + 0x8B49, KANJI_SJIS_L2, // 證 + 0x8B56, KANJI_SJIS_L2, // 譖 + 0x8B5B, KANJI_SJIS_L2, // 譛 + 0x8B5A, KANJI_SJIS_L2, // 譚 + 0x8B6B, KANJI_SJIS_L2, // è­« + 0x8B5F, KANJI_SJIS_L2, // 譟 + 0x8B6C, KANJI_SJIS_L2, // è­¬ + 0x8B6F, KANJI_SJIS_L2, // è­¯ + 0x8B74, KANJI_SJIS_L2, // è­Ž + 0x8B7D, KANJI_SJIS_L2, // è­œ + 0x8B80, KANJI_SJIS_L2, // 讀 + 0x8B8C, KANJI_SJIS_L2, // 讌 + 0x8B8E, KANJI_SJIS_L2, // 讎 + 0x8B92, KANJI_SJIS_L2, // 讒 + 0x8B93, KANJI_SJIS_L2, // 讓 + 0x8B96, KANJI_SJIS_L2, // 讖 + 0x8B99, KANJI_SJIS_L2, // 讙 + 0x8B9A, KANJI_SJIS_L2, // 讚 + 0x8C3A, KANJI_SJIS_L2, // è°º + 0x8C41, KANJI_SJIS_L2, // 豁 + 0x8C3F, KANJI_SJIS_L2, // è°¿ + 0x8C48, KANJI_SJIS_L2, // 豈 + 0x8C4C, KANJI_SJIS_L2, // 豌 + 0x8C4E, KANJI_SJIS_L2, // 豎 + 0x8C50, KANJI_SJIS_L2, // 豐 + 0x8C55, KANJI_SJIS_L2, // 豕 + 0x8C62, KANJI_SJIS_L2, // è±¢ + 0x8C6C, KANJI_SJIS_L2, // 豬 + 0x8C78, KANJI_SJIS_L2, // 豞 + 0x8C7A, KANJI_SJIS_L2, // 豺 + 0x8C82, KANJI_SJIS_L2, // 貂 + 0x8C89, KANJI_SJIS_L2, // 貉 + 0x8C85, KANJI_SJIS_L2, // 貅 + 0x8C8A, KANJI_SJIS_L2, // 貊 + 0x8C8D, KANJI_SJIS_L2, // 貍 + 0x8C8E, KANJI_SJIS_L2, // 貎 + 0x8C94, KANJI_SJIS_L2, // 貔 + 0x8C7C, KANJI_SJIS_L2, // 豌 + 0x8C98, KANJI_SJIS_L2, // 貘 + 0x621D, KANJI_SJIS_L2, // 戝 + 0x8CAD, KANJI_SJIS_L2, // è²­ + 0x8CAA, KANJI_SJIS_L2, // 貪 + 0x8CBD, KANJI_SJIS_L2, // 貜 + 0x8CB2, KANJI_SJIS_L2, // è²² + 0x8CB3, KANJI_SJIS_L2, // è²³ + 0x8CAE, KANJI_SJIS_L2, // è²® + 0x8CB6, KANJI_SJIS_L2, // è²¶ + 0x8CC8, KANJI_SJIS_L2, // 賈 + 0x8CC1, KANJI_SJIS_L2, // 賁 + 0x8CE4, KANJI_SJIS_L2, // è³€ + 0x8CE3, KANJI_SJIS_L2, // è³£ + 0x8CDA, KANJI_SJIS_L2, // 賚 + 0x8CFD, KANJI_SJIS_L2, // 賜 + 0x8CFA, KANJI_SJIS_L2, // 賺 + 0x8CFB, KANJI_SJIS_L2, // è³» + 0x8D04, KANJI_SJIS_L2, // 莄 + 0x8D05, KANJI_SJIS_L2, // 莅 + 0x8D0A, KANJI_SJIS_L2, // 莊 + 0x8D07, KANJI_SJIS_L2, // 莇 + 0x8D0F, KANJI_SJIS_L2, // 莏 + 0x8D0D, KANJI_SJIS_L2, // 莍 + 0x8D10, KANJI_SJIS_L2, // 莐 + 0x9F4E, KANJI_SJIS_L2, // 霎 + 0x8D13, KANJI_SJIS_L2, // 莓 + 0x8CCD, KANJI_SJIS_L2, // 賍 + 0x8D14, KANJI_SJIS_L2, // 莔 + 0x8D16, KANJI_SJIS_L2, // 莖 + 0x8D67, KANJI_SJIS_L2, // èµ§ + 0x8D6D, KANJI_SJIS_L2, // èµ­ + 0x8D71, KANJI_SJIS_L2, // èµ± + 0x8D73, KANJI_SJIS_L2, // èµ³ + 0x8D81, KANJI_SJIS_L2, // 趁 + 0x8D99, KANJI_SJIS_L2, // 趙 + 0x8DC2, KANJI_SJIS_L2, // 跂 + 0x8DBE, KANJI_SJIS_L2, // è¶Ÿ + 0x8DBA, KANJI_SJIS_L2, // 趺 + 0x8DCF, KANJI_SJIS_L2, // 跏 + 0x8DDA, KANJI_SJIS_L2, // 跚 + 0x8DD6, KANJI_SJIS_L2, // 跖 + 0x8DCC, KANJI_SJIS_L2, // 跌 + 0x8DDB, KANJI_SJIS_L2, // 跛 + 0x8DCB, KANJI_SJIS_L2, // 跋 + 0x8DEA, KANJI_SJIS_L2, // è·ª + 0x8DEB, KANJI_SJIS_L2, // è·« + 0x8DDF, KANJI_SJIS_L2, // 跟 + 0x8DE3, KANJI_SJIS_L2, // è·£ + 0x8DFC, KANJI_SJIS_L2, // è·Œ + 0x8E08, KANJI_SJIS_L2, // 螈 + 0x8E09, KANJI_SJIS_L2, // 螉 + 0x8DFF, KANJI_SJIS_L2, // è·¿ + 0x8E1D, KANJI_SJIS_L2, // 螝 + 0x8E1E, KANJI_SJIS_L2, // èžž + 0x8E10, KANJI_SJIS_L2, // 螐 + 0x8E1F, KANJI_SJIS_L2, // 螟 + 0x8E42, KANJI_SJIS_L2, // 蹂 + 0x8E35, KANJI_SJIS_L2, // èžµ + 0x8E30, KANJI_SJIS_L2, // èž° + 0x8E34, KANJI_SJIS_L2, // 螎 + 0x8E4A, KANJI_SJIS_L2, // 蹊 + 0x8E47, KANJI_SJIS_L2, // 蹇 + 0x8E49, KANJI_SJIS_L2, // 蹉 + 0x8E4C, KANJI_SJIS_L2, // 蹌 + 0x8E50, KANJI_SJIS_L2, // 蹐 + 0x8E48, KANJI_SJIS_L2, // 蹈 + 0x8E59, KANJI_SJIS_L2, // 蹙 + 0x8E64, KANJI_SJIS_L2, // è¹€ + 0x8E60, KANJI_SJIS_L2, // è¹  + 0x8E2A, KANJI_SJIS_L2, // 螪 + 0x8E63, KANJI_SJIS_L2, // è¹£ + 0x8E55, KANJI_SJIS_L2, // 蹕 + 0x8E76, KANJI_SJIS_L2, // è¹¶ + 0x8E72, KANJI_SJIS_L2, // è¹² + 0x8E7C, KANJI_SJIS_L2, // 蹌 + 0x8E81, KANJI_SJIS_L2, // 躁 + 0x8E87, KANJI_SJIS_L2, // 躇 + 0x8E85, KANJI_SJIS_L2, // 躅 + 0x8E84, KANJI_SJIS_L2, // 躄 + 0x8E8B, KANJI_SJIS_L2, // 躋 + 0x8E8A, KANJI_SJIS_L2, // 躊 + 0x8E93, KANJI_SJIS_L2, // 躓 + 0x8E91, KANJI_SJIS_L2, // 躑 + 0x8E94, KANJI_SJIS_L2, // 躔 + 0x8E99, KANJI_SJIS_L2, // 躙 + 0x8EAA, KANJI_SJIS_L2, // 躪 + 0x8EA1, KANJI_SJIS_L2, // 躡 + 0x8EAC, KANJI_SJIS_L2, // 躬 + 0x8EB0, KANJI_SJIS_L2, // 躰 + 0x8EC6, KANJI_SJIS_L2, // 軆 + 0x8EB1, KANJI_SJIS_L2, // 躱 + 0x8EBE, KANJI_SJIS_L2, // 躟 + 0x8EC5, KANJI_SJIS_L2, // 軅 + 0x8EC8, KANJI_SJIS_L2, // 軈 + 0x8ECB, KANJI_SJIS_L2, // 軋 + 0x8EDB, KANJI_SJIS_L2, // 軛 + 0x8EE3, KANJI_SJIS_L2, // 軣 + 0x8EFC, KANJI_SJIS_L2, // 軌 + 0x8EFB, KANJI_SJIS_L2, // è»» + 0x8EEB, KANJI_SJIS_L2, // 軫 + 0x8EFE, KANJI_SJIS_L2, // 軟 + 0x8F0A, KANJI_SJIS_L2, // 茊 + 0x8F05, KANJI_SJIS_L2, // 茅 + 0x8F15, KANJI_SJIS_L2, // 茕 + 0x8F12, KANJI_SJIS_L2, // 茒 + 0x8F19, KANJI_SJIS_L2, // 茙 + 0x8F13, KANJI_SJIS_L2, // 茓 + 0x8F1C, KANJI_SJIS_L2, // 茜 + 0x8F1F, KANJI_SJIS_L2, // 茟 + 0x8F1B, KANJI_SJIS_L2, // 茛 + 0x8F0C, KANJI_SJIS_L2, // 茌 + 0x8F26, KANJI_SJIS_L2, // 茊 + 0x8F33, KANJI_SJIS_L2, // 茳 + 0x8F3B, KANJI_SJIS_L2, // 茻 + 0x8F39, KANJI_SJIS_L2, // 茹 + 0x8F45, KANJI_SJIS_L2, // 蜅 + 0x8F42, KANJI_SJIS_L2, // 蜂 + 0x8F3E, KANJI_SJIS_L2, // 茟 + 0x8F4C, KANJI_SJIS_L2, // 蜌 + 0x8F49, KANJI_SJIS_L2, // 蜉 + 0x8F46, KANJI_SJIS_L2, // 蜆 + 0x8F4E, KANJI_SJIS_L2, // 蜎 + 0x8F57, KANJI_SJIS_L2, // 蜗 + 0x8F5C, KANJI_SJIS_L2, // 蜜 + 0x3000, KANJI_SJIS_L2, //   + 0x8F62, KANJI_SJIS_L2, // 蜢 + 0x8F63, KANJI_SJIS_L2, // 蜣 + 0x8F64, KANJI_SJIS_L2, // 蜀 + 0x8F9C, KANJI_SJIS_L2, // 蟜 + 0x8F9F, KANJI_SJIS_L2, // 蟟 + 0x8FA3, KANJI_SJIS_L2, // 蟣 + 0x8FAD, KANJI_SJIS_L2, // 蟭 + 0x8FAF, KANJI_SJIS_L2, // 蟯 + 0x8FB7, KANJI_SJIS_L2, // 蟷 + 0x8FDA, KANJI_SJIS_L2, // 迚 + 0x8FE5, KANJI_SJIS_L2, // è¿¥ + 0x8FE2, KANJI_SJIS_L2, // è¿¢ + 0x8FEA, KANJI_SJIS_L2, // 迪 + 0x8FEF, KANJI_SJIS_L2, // 迯 + 0x9087, KANJI_SJIS_L2, // 邇 + 0x8FF4, KANJI_SJIS_L2, // 迎 + 0x9005, KANJI_SJIS_L2, // 逅 + 0x8FF9, KANJI_SJIS_L2, // 迹 + 0x8FFA, KANJI_SJIS_L2, // 迺 + 0x9011, KANJI_SJIS_L2, // 逑 + 0x9015, KANJI_SJIS_L2, // 逕 + 0x9021, KANJI_SJIS_L2, // 逡 + 0x900D, KANJI_SJIS_L2, // 逍 + 0x901E, KANJI_SJIS_L2, // 逞 + 0x9016, KANJI_SJIS_L2, // 逖 + 0x900B, KANJI_SJIS_L2, // 逋 + 0x9027, KANJI_SJIS_L2, // 逧 + 0x9036, KANJI_SJIS_L2, // 逶 + 0x9035, KANJI_SJIS_L2, // 逵 + 0x9039, KANJI_SJIS_L2, // 逹 + 0x8FF8, KANJI_SJIS_L2, // 连 + 0x904F, KANJI_SJIS_L2, // 遏 + 0x9050, KANJI_SJIS_L2, // 遐 + 0x9051, KANJI_SJIS_L2, // 遑 + 0x9052, KANJI_SJIS_L2, // 遒 + 0x900E, KANJI_SJIS_L2, // 逎 + 0x9049, KANJI_SJIS_L2, // 遉 + 0x903E, KANJI_SJIS_L2, // 速 + 0x9056, KANJI_SJIS_L2, // 遖 + 0x9058, KANJI_SJIS_L2, // 遘 + 0x905E, KANJI_SJIS_L2, // 遞 + 0x9068, KANJI_SJIS_L2, // 遚 + 0x906F, KANJI_SJIS_L2, // 遯 + 0x9076, KANJI_SJIS_L2, // 遶 + 0x96A8, KANJI_SJIS_L2, // 隹 + 0x9072, KANJI_SJIS_L2, // 遲 + 0x9082, KANJI_SJIS_L2, // 邂 + 0x907D, KANJI_SJIS_L2, // 遜 + 0x9081, KANJI_SJIS_L2, // 邁 + 0x9080, KANJI_SJIS_L2, // 邀 + 0x908A, KANJI_SJIS_L2, // 邊 + 0x9089, KANJI_SJIS_L2, // 邉 + 0x908F, KANJI_SJIS_L2, // 邏 + 0x90A8, KANJI_SJIS_L2, // 邹 + 0x90AF, KANJI_SJIS_L2, // 邯 + 0x90B1, KANJI_SJIS_L2, // 邱 + 0x90B5, KANJI_SJIS_L2, // 邵 + 0x90E2, KANJI_SJIS_L2, // 郢 + 0x90E4, KANJI_SJIS_L2, // 郀 + 0x6248, KANJI_SJIS_L2, // 扈 + 0x90DB, KANJI_SJIS_L2, // 郛 + 0x9102, KANJI_SJIS_L2, // 鄂 + 0x9112, KANJI_SJIS_L2, // 鄒 + 0x9119, KANJI_SJIS_L2, // 鄙 + 0x9132, KANJI_SJIS_L2, // 鄲 + 0x9130, KANJI_SJIS_L2, // 鄰 + 0x914A, KANJI_SJIS_L2, // 酊 + 0x9156, KANJI_SJIS_L2, // 酖 + 0x9158, KANJI_SJIS_L2, // 酘 + 0x9163, KANJI_SJIS_L2, // 酣 + 0x9165, KANJI_SJIS_L2, // 酥 + 0x9169, KANJI_SJIS_L2, // 酩 + 0x9173, KANJI_SJIS_L2, // 酳 + 0x9172, KANJI_SJIS_L2, // 酲 + 0x918B, KANJI_SJIS_L2, // 醋 + 0x9189, KANJI_SJIS_L2, // 醉 + 0x9182, KANJI_SJIS_L2, // 醂 + 0x91A2, KANJI_SJIS_L2, // 醢 + 0x91AB, KANJI_SJIS_L2, // 醫 + 0x91AF, KANJI_SJIS_L2, // 醯 + 0x91AA, KANJI_SJIS_L2, // 醪 + 0x91B5, KANJI_SJIS_L2, // 醵 + 0x91B4, KANJI_SJIS_L2, // 醮 + 0x91BA, KANJI_SJIS_L2, // 醺 + 0x91C0, KANJI_SJIS_L2, // 釀 + 0x91C1, KANJI_SJIS_L2, // 釁 + 0x91C9, KANJI_SJIS_L2, // 釉 + 0x91CB, KANJI_SJIS_L2, // 釋 + 0x91D0, KANJI_SJIS_L2, // 釐 + 0x91D6, KANJI_SJIS_L2, // 釖 + 0x91DF, KANJI_SJIS_L2, // 釟 + 0x91E1, KANJI_SJIS_L2, // 釡 + 0x91DB, KANJI_SJIS_L2, // 釛 + 0x91FC, KANJI_SJIS_L2, // 里 + 0x91F5, KANJI_SJIS_L2, // 釵 + 0x91F6, KANJI_SJIS_L2, // 釶 + 0x921E, KANJI_SJIS_L2, // 鈞 + 0x91FF, KANJI_SJIS_L2, // 釿 + 0x9214, KANJI_SJIS_L2, // 鈔 + 0x922C, KANJI_SJIS_L2, // 鈬 + 0x9215, KANJI_SJIS_L2, // 鈕 + 0x9211, KANJI_SJIS_L2, // 鈑 + 0x925E, KANJI_SJIS_L2, // 鉞 + 0x9257, KANJI_SJIS_L2, // 鉗 + 0x9245, KANJI_SJIS_L2, // 鉅 + 0x9249, KANJI_SJIS_L2, // 鉉 + 0x9264, KANJI_SJIS_L2, // 鉀 + 0x9248, KANJI_SJIS_L2, // 鉈 + 0x9295, KANJI_SJIS_L2, // 銕 + 0x923F, KANJI_SJIS_L2, // 鈿 + 0x924B, KANJI_SJIS_L2, // 鉋 + 0x9250, KANJI_SJIS_L2, // 鉐 + 0x929C, KANJI_SJIS_L2, // 銜 + 0x9296, KANJI_SJIS_L2, // 銖 + 0x9293, KANJI_SJIS_L2, // 銓 + 0x929B, KANJI_SJIS_L2, // 銛 + 0x925A, KANJI_SJIS_L2, // 鉚 + 0x92CF, KANJI_SJIS_L2, // 鋏 + 0x92B9, KANJI_SJIS_L2, // 銹 + 0x92B7, KANJI_SJIS_L2, // 銷 + 0x92E9, KANJI_SJIS_L2, // 鋩 + 0x930F, KANJI_SJIS_L2, // 錏 + 0x92FA, KANJI_SJIS_L2, // 鋺 + 0x9344, KANJI_SJIS_L2, // 鍄 + 0x932E, KANJI_SJIS_L2, // 錮 + 0x9319, KANJI_SJIS_L2, // 錙 + 0x9322, KANJI_SJIS_L2, // 錢 + 0x931A, KANJI_SJIS_L2, // 錚 + 0x9323, KANJI_SJIS_L2, // 錣 + 0x933A, KANJI_SJIS_L2, // 錺 + 0x9335, KANJI_SJIS_L2, // 錵 + 0x933B, KANJI_SJIS_L2, // 錻 + 0x935C, KANJI_SJIS_L2, // 鍜 + 0x9360, KANJI_SJIS_L2, // 鍠 + 0x937C, KANJI_SJIS_L2, // 鍌 + 0x936E, KANJI_SJIS_L2, // 鍮 + 0x9356, KANJI_SJIS_L2, // 鍖 + 0x93B0, KANJI_SJIS_L2, // 鎰 + 0x93AC, KANJI_SJIS_L2, // 鎬 + 0x93AD, KANJI_SJIS_L2, // 鎭 + 0x9394, KANJI_SJIS_L2, // 鎔 + 0x93B9, KANJI_SJIS_L2, // 鎹 + 0x93D6, KANJI_SJIS_L2, // 鏖 + 0x93D7, KANJI_SJIS_L2, // 鏗 + 0x93E8, KANJI_SJIS_L2, // 鏚 + 0x93E5, KANJI_SJIS_L2, // 鏥 + 0x93D8, KANJI_SJIS_L2, // 鏘 + 0x93C3, KANJI_SJIS_L2, // 鏃 + 0x93DD, KANJI_SJIS_L2, // 鏝 + 0x93D0, KANJI_SJIS_L2, // 鏐 + 0x93C8, KANJI_SJIS_L2, // 鏈 + 0x93E4, KANJI_SJIS_L2, // 鏀 + 0x941A, KANJI_SJIS_L2, // 鐚 + 0x9414, KANJI_SJIS_L2, // 鐔 + 0x9413, KANJI_SJIS_L2, // 鐓 + 0x9403, KANJI_SJIS_L2, // 鐃 + 0x9407, KANJI_SJIS_L2, // 鐇 + 0x9410, KANJI_SJIS_L2, // 鐐 + 0x9436, KANJI_SJIS_L2, // 鐶 + 0x942B, KANJI_SJIS_L2, // 鐫 + 0x9435, KANJI_SJIS_L2, // 鐵 + 0x9421, KANJI_SJIS_L2, // 鐡 + 0x943A, KANJI_SJIS_L2, // 鐺 + 0x9441, KANJI_SJIS_L2, // 鑁 + 0x9452, KANJI_SJIS_L2, // 鑒 + 0x9444, KANJI_SJIS_L2, // 鑄 + 0x945B, KANJI_SJIS_L2, // 鑛 + 0x9460, KANJI_SJIS_L2, // 鑠 + 0x9462, KANJI_SJIS_L2, // 鑢 + 0x945E, KANJI_SJIS_L2, // 鑞 + 0x946A, KANJI_SJIS_L2, // 鑪 + 0x9229, KANJI_SJIS_L2, // 鈩 + 0x9470, KANJI_SJIS_L2, // 鑰 + 0x9475, KANJI_SJIS_L2, // 鑵 + 0x9477, KANJI_SJIS_L2, // 鑷 + 0x947D, KANJI_SJIS_L2, // 鑜 + 0x945A, KANJI_SJIS_L2, // 鑚 + 0x947C, KANJI_SJIS_L2, // 鑌 + 0x947E, KANJI_SJIS_L2, // 鑟 + 0x9481, KANJI_SJIS_L2, // 钁 + 0x947F, KANJI_SJIS_L2, // 鑿 + 0x9582, KANJI_SJIS_L2, // 閂 + 0x9587, KANJI_SJIS_L2, // 閇 + 0x958A, KANJI_SJIS_L2, // 閊 + 0x9594, KANJI_SJIS_L2, // 閔 + 0x9596, KANJI_SJIS_L2, // 閖 + 0x9598, KANJI_SJIS_L2, // 閘 + 0x9599, KANJI_SJIS_L2, // 閙 + 0x3000, KANJI_SJIS_L2, //   + 0x95A0, KANJI_SJIS_L2, // 閠 + 0x95A8, KANJI_SJIS_L2, // 閹 + 0x95A7, KANJI_SJIS_L2, // 閧 + 0x95AD, KANJI_SJIS_L2, // 閭 + 0x95BC, KANJI_SJIS_L2, // é–Œ + 0x95BB, KANJI_SJIS_L2, // 閻 + 0x95B9, KANJI_SJIS_L2, // 閹 + 0x95BE, KANJI_SJIS_L2, // é–Ÿ + 0x95CA, KANJI_SJIS_L2, // 闊 + 0x6FF6, KANJI_SJIS_L2, // æ¿¶ + 0x95C3, KANJI_SJIS_L2, // 闃 + 0x95CD, KANJI_SJIS_L2, // 闍 + 0x95CC, KANJI_SJIS_L2, // 闌 + 0x95D5, KANJI_SJIS_L2, // 闕 + 0x95D4, KANJI_SJIS_L2, // 闔 + 0x95D6, KANJI_SJIS_L2, // 闖 + 0x95DC, KANJI_SJIS_L2, // 關 + 0x95E1, KANJI_SJIS_L2, // 闡 + 0x95E5, KANJI_SJIS_L2, // 闥 + 0x95E2, KANJI_SJIS_L2, // 闢 + 0x9621, KANJI_SJIS_L2, // 阡 + 0x9628, KANJI_SJIS_L2, // 阚 + 0x962E, KANJI_SJIS_L2, // 阮 + 0x962F, KANJI_SJIS_L2, // 阯 + 0x9642, KANJI_SJIS_L2, // 陂 + 0x964C, KANJI_SJIS_L2, // 陌 + 0x964F, KANJI_SJIS_L2, // 陏 + 0x964B, KANJI_SJIS_L2, // 陋 + 0x9677, KANJI_SJIS_L2, // 陷 + 0x965C, KANJI_SJIS_L2, // 陜 + 0x965E, KANJI_SJIS_L2, // 陞 + 0x965D, KANJI_SJIS_L2, // 陝 + 0x965F, KANJI_SJIS_L2, // 陟 + 0x9666, KANJI_SJIS_L2, // 险 + 0x9672, KANJI_SJIS_L2, // 陲 + 0x966C, KANJI_SJIS_L2, // 陬 + 0x968D, KANJI_SJIS_L2, // 隍 + 0x9698, KANJI_SJIS_L2, // 隘 + 0x9695, KANJI_SJIS_L2, // 隕 + 0x9697, KANJI_SJIS_L2, // 隗 + 0x96AA, KANJI_SJIS_L2, // 險 + 0x96A7, KANJI_SJIS_L2, // 隧 + 0x96B1, KANJI_SJIS_L2, // 隱 + 0x96B2, KANJI_SJIS_L2, // 隲 + 0x96B0, KANJI_SJIS_L2, // 隰 + 0x96B4, KANJI_SJIS_L2, // 隮 + 0x96B6, KANJI_SJIS_L2, // 隶 + 0x96B8, KANJI_SJIS_L2, // 难 + 0x96B9, KANJI_SJIS_L2, // 隹 + 0x96CE, KANJI_SJIS_L2, // 雎 + 0x96CB, KANJI_SJIS_L2, // 雋 + 0x96C9, KANJI_SJIS_L2, // 雉 + 0x96CD, KANJI_SJIS_L2, // 雍 + 0x894D, KANJI_SJIS_L2, // 襍 + 0x96DC, KANJI_SJIS_L2, // 雜 + 0x970D, KANJI_SJIS_L2, // 霍 + 0x96D5, KANJI_SJIS_L2, // 雕 + 0x96F9, KANJI_SJIS_L2, // 雹 + 0x9704, KANJI_SJIS_L2, // 霄 + 0x9706, KANJI_SJIS_L2, // 霆 + 0x9708, KANJI_SJIS_L2, // 霈 + 0x9713, KANJI_SJIS_L2, // 霓 + 0x970E, KANJI_SJIS_L2, // 霎 + 0x9711, KANJI_SJIS_L2, // 霑 + 0x970F, KANJI_SJIS_L2, // 霏 + 0x9716, KANJI_SJIS_L2, // 霖 + 0x9719, KANJI_SJIS_L2, // 霙 + 0x9724, KANJI_SJIS_L2, // 需 + 0x972A, KANJI_SJIS_L2, // 霪 + 0x9730, KANJI_SJIS_L2, // 霰 + 0x9739, KANJI_SJIS_L2, // 霹 + 0x973D, KANJI_SJIS_L2, // 霜 + 0x973E, KANJI_SJIS_L2, // 霟 + 0x9744, KANJI_SJIS_L2, // 靄 + 0x9746, KANJI_SJIS_L2, // 靆 + 0x9748, KANJI_SJIS_L2, // 靈 + 0x9742, KANJI_SJIS_L2, // 靂 + 0x9749, KANJI_SJIS_L2, // 靉 + 0x975C, KANJI_SJIS_L2, // 靜 + 0x9760, KANJI_SJIS_L2, // 靠 + 0x9764, KANJI_SJIS_L2, // 靀 + 0x9766, KANJI_SJIS_L2, // 靊 + 0x9768, KANJI_SJIS_L2, // 靚 + 0x52D2, KANJI_SJIS_L2, // 勒 + 0x976B, KANJI_SJIS_L2, // 靫 + 0x9771, KANJI_SJIS_L2, // 靱 + 0x9779, KANJI_SJIS_L2, // 靹 + 0x9785, KANJI_SJIS_L2, // 鞅 + 0x977C, KANJI_SJIS_L2, // 靌 + 0x9781, KANJI_SJIS_L2, // 鞁 + 0x977A, KANJI_SJIS_L2, // 靺 + 0x9786, KANJI_SJIS_L2, // 鞆 + 0x978B, KANJI_SJIS_L2, // 鞋 + 0x978F, KANJI_SJIS_L2, // 鞏 + 0x9790, KANJI_SJIS_L2, // 鞐 + 0x979C, KANJI_SJIS_L2, // 鞜 + 0x97A8, KANJI_SJIS_L2, // 鞚 + 0x97A6, KANJI_SJIS_L2, // 鞊 + 0x97A3, KANJI_SJIS_L2, // 鞣 + 0x97B3, KANJI_SJIS_L2, // 鞳 + 0x97B4, KANJI_SJIS_L2, // 鞮 + 0x97C3, KANJI_SJIS_L2, // 韃 + 0x97C6, KANJI_SJIS_L2, // 韆 + 0x97C8, KANJI_SJIS_L2, // 韈 + 0x97CB, KANJI_SJIS_L2, // 韋 + 0x97DC, KANJI_SJIS_L2, // 韜 + 0x97ED, KANJI_SJIS_L2, // 韭 + 0x9F4F, KANJI_SJIS_L2, // 霏 + 0x97F2, KANJI_SJIS_L2, // 韲 + 0x7ADF, KANJI_SJIS_L2, // 竟 + 0x97F6, KANJI_SJIS_L2, // 韶 + 0x97F5, KANJI_SJIS_L2, // 韵 + 0x980F, KANJI_SJIS_L2, // 頏 + 0x980C, KANJI_SJIS_L2, // 頌 + 0x9838, KANJI_SJIS_L2, // é ž + 0x9824, KANJI_SJIS_L2, // é € + 0x9821, KANJI_SJIS_L2, // é ¡ + 0x9837, KANJI_SJIS_L2, // é · + 0x983D, KANJI_SJIS_L2, // é œ + 0x9846, KANJI_SJIS_L2, // 顆 + 0x984F, KANJI_SJIS_L2, // 顏 + 0x984B, KANJI_SJIS_L2, // 顋 + 0x986B, KANJI_SJIS_L2, // é¡« + 0x986F, KANJI_SJIS_L2, // 顯 + 0x9870, KANJI_SJIS_L2, // é¡° + 0x9871, KANJI_SJIS_L2, // 顱 + 0x9874, KANJI_SJIS_L2, // 顎 + 0x9873, KANJI_SJIS_L2, // 顳 + 0x98AA, KANJI_SJIS_L2, // 颪 + 0x98AF, KANJI_SJIS_L2, // 颯 + 0x98B1, KANJI_SJIS_L2, // 颱 + 0x98B6, KANJI_SJIS_L2, // 颶 + 0x98C4, KANJI_SJIS_L2, // 飄 + 0x98C3, KANJI_SJIS_L2, // 飃 + 0x98C6, KANJI_SJIS_L2, // 飆 + 0x98E9, KANJI_SJIS_L2, // 飩 + 0x98EB, KANJI_SJIS_L2, // 飫 + 0x9903, KANJI_SJIS_L2, // 逃 + 0x9909, KANJI_SJIS_L2, // 选 + 0x9912, KANJI_SJIS_L2, // 递 + 0x9914, KANJI_SJIS_L2, // 途 + 0x9918, KANJI_SJIS_L2, // 逘 + 0x9921, KANJI_SJIS_L2, // 逡 + 0x991D, KANJI_SJIS_L2, // 逝 + 0x991E, KANJI_SJIS_L2, // 逞 + 0x9924, KANJI_SJIS_L2, // 退 + 0x9920, KANJI_SJIS_L2, // 造 + 0x992C, KANJI_SJIS_L2, // 逬 + 0x992E, KANJI_SJIS_L2, // 逮 + 0x993D, KANJI_SJIS_L2, // 逜 + 0x993E, KANJI_SJIS_L2, // 速 + 0x9942, KANJI_SJIS_L2, // 饂 + 0x9949, KANJI_SJIS_L2, // 饉 + 0x9945, KANJI_SJIS_L2, // 饅 + 0x9950, KANJI_SJIS_L2, // 饐 + 0x994B, KANJI_SJIS_L2, // 饋 + 0x9951, KANJI_SJIS_L2, // 饑 + 0x9952, KANJI_SJIS_L2, // 饒 + 0x994C, KANJI_SJIS_L2, // 饌 + 0x9955, KANJI_SJIS_L2, // 饕 + 0x9997, KANJI_SJIS_L2, // 驗 + 0x9998, KANJI_SJIS_L2, // 銘 + 0x99A5, KANJI_SJIS_L2, // 銥 + 0x99AD, KANJI_SJIS_L2, // 銭 + 0x99AE, KANJI_SJIS_L2, // 銮 + 0x99BC, KANJI_SJIS_L2, // 銌 + 0x99DF, KANJI_SJIS_L2, // 駟 + 0x99DB, KANJI_SJIS_L2, // 駛 + 0x99DD, KANJI_SJIS_L2, // 駝 + 0x99D8, KANJI_SJIS_L2, // 駘 + 0x99D1, KANJI_SJIS_L2, // 駑 + 0x99ED, KANJI_SJIS_L2, // é§­ + 0x99EE, KANJI_SJIS_L2, // é§® + 0x99F1, KANJI_SJIS_L2, // é§± + 0x99F2, KANJI_SJIS_L2, // é§² + 0x99FB, KANJI_SJIS_L2, // é§» + 0x99F8, KANJI_SJIS_L2, // é§ž + 0x9A01, KANJI_SJIS_L2, // 隁 + 0x9A0F, KANJI_SJIS_L2, // 随 + 0x9A05, KANJI_SJIS_L2, // 鹅 + 0x99E2, KANJI_SJIS_L2, // é§¢ + 0x9A19, KANJI_SJIS_L2, // 鹙 + 0x9A2B, KANJI_SJIS_L2, // éš« + 0x9A37, KANJI_SJIS_L2, // éš· + 0x9A45, KANJI_SJIS_L2, // 驅 + 0x9A42, KANJI_SJIS_L2, // 驂 + 0x9A40, KANJI_SJIS_L2, // 驀 + 0x9A43, KANJI_SJIS_L2, // 驃 + 0x3000, KANJI_SJIS_L2, //   + 0x9A3E, KANJI_SJIS_L2, // 隟 + 0x9A55, KANJI_SJIS_L2, // 驕 + 0x9A4D, KANJI_SJIS_L2, // 驍 + 0x9A5B, KANJI_SJIS_L2, // 驛 + 0x9A57, KANJI_SJIS_L2, // 驗 + 0x9A5F, KANJI_SJIS_L2, // 驟 + 0x9A62, KANJI_SJIS_L2, // é©¢ + 0x9A65, KANJI_SJIS_L2, // é©¥ + 0x9A64, KANJI_SJIS_L2, // é©€ + 0x9A69, KANJI_SJIS_L2, // é©© + 0x9A6B, KANJI_SJIS_L2, // é©« + 0x9A6A, KANJI_SJIS_L2, // 驪 + 0x9AAD, KANJI_SJIS_L2, // 骭 + 0x9AB0, KANJI_SJIS_L2, // 骰 + 0x9ABC, KANJI_SJIS_L2, // 验 + 0x9AC0, KANJI_SJIS_L2, // 髀 + 0x9ACF, KANJI_SJIS_L2, // 髏 + 0x9AD1, KANJI_SJIS_L2, // 髑 + 0x9AD3, KANJI_SJIS_L2, // 髓 + 0x9AD4, KANJI_SJIS_L2, // 體 + 0x9ADE, KANJI_SJIS_L2, // 髞 + 0x9ADF, KANJI_SJIS_L2, // 髟 + 0x9AE2, KANJI_SJIS_L2, // é«¢ + 0x9AE3, KANJI_SJIS_L2, // é«£ + 0x9AE6, KANJI_SJIS_L2, // 髊 + 0x9AEF, KANJI_SJIS_L2, // 髯 + 0x9AEB, KANJI_SJIS_L2, // é«« + 0x9AEE, KANJI_SJIS_L2, // é«® + 0x9AF4, KANJI_SJIS_L2, // 髎 + 0x9AF1, KANJI_SJIS_L2, // 髱 + 0x9AF7, KANJI_SJIS_L2, // é«· + 0x9AFB, KANJI_SJIS_L2, // é«» + 0x9B06, KANJI_SJIS_L2, // 鬆 + 0x9B18, KANJI_SJIS_L2, // 鬘 + 0x9B1A, KANJI_SJIS_L2, // 鬚 + 0x9B1F, KANJI_SJIS_L2, // 鬟 + 0x9B22, KANJI_SJIS_L2, // 鬢 + 0x9B23, KANJI_SJIS_L2, // 鬣 + 0x9B25, KANJI_SJIS_L2, // 鬥 + 0x9B27, KANJI_SJIS_L2, // 鬧 + 0x9B28, KANJI_SJIS_L2, // 鬚 + 0x9B29, KANJI_SJIS_L2, // 鬩 + 0x9B2A, KANJI_SJIS_L2, // 鬪 + 0x9B2E, KANJI_SJIS_L2, // 鬮 + 0x9B2F, KANJI_SJIS_L2, // 鬯 + 0x9B32, KANJI_SJIS_L2, // 鬲 + 0x9B44, KANJI_SJIS_L2, // 魄 + 0x9B43, KANJI_SJIS_L2, // 魃 + 0x9B4F, KANJI_SJIS_L2, // 魏 + 0x9B4D, KANJI_SJIS_L2, // 魍 + 0x9B4E, KANJI_SJIS_L2, // 魎 + 0x9B51, KANJI_SJIS_L2, // 魑 + 0x9B58, KANJI_SJIS_L2, // 魘 + 0x9B74, KANJI_SJIS_L2, // é­Ž + 0x9B93, KANJI_SJIS_L2, // 鮓 + 0x9B83, KANJI_SJIS_L2, // 鮃 + 0x9B91, KANJI_SJIS_L2, // 鮑 + 0x9B96, KANJI_SJIS_L2, // 鮖 + 0x9B97, KANJI_SJIS_L2, // 鮗 + 0x9B9F, KANJI_SJIS_L2, // 鮟 + 0x9BA0, KANJI_SJIS_L2, // é®  + 0x9BA8, KANJI_SJIS_L2, // 鮚 + 0x9BB4, KANJI_SJIS_L2, // 鮎 + 0x9BC0, KANJI_SJIS_L2, // 鯀 + 0x9BCA, KANJI_SJIS_L2, // 鯊 + 0x9BB9, KANJI_SJIS_L2, // 鮹 + 0x9BC6, KANJI_SJIS_L2, // 鯆 + 0x9BCF, KANJI_SJIS_L2, // 鯏 + 0x9BD1, KANJI_SJIS_L2, // 鯑 + 0x9BD2, KANJI_SJIS_L2, // 鯒 + 0x9BE3, KANJI_SJIS_L2, // 鯣 + 0x9BE2, KANJI_SJIS_L2, // 鯢 + 0x9BE4, KANJI_SJIS_L2, // 鯀 + 0x9BD4, KANJI_SJIS_L2, // 鯔 + 0x9BE1, KANJI_SJIS_L2, // 鯡 + 0x9C3A, KANJI_SJIS_L2, // é°º + 0x9BF2, KANJI_SJIS_L2, // 鯲 + 0x9BF1, KANJI_SJIS_L2, // 鯱 + 0x9BF0, KANJI_SJIS_L2, // 鯰 + 0x9C15, KANJI_SJIS_L2, // 鰕 + 0x9C14, KANJI_SJIS_L2, // 鰔 + 0x9C09, KANJI_SJIS_L2, // 鰉 + 0x9C13, KANJI_SJIS_L2, // 鰓 + 0x9C0C, KANJI_SJIS_L2, // 鰌 + 0x9C06, KANJI_SJIS_L2, // 鰆 + 0x9C08, KANJI_SJIS_L2, // 鰈 + 0x9C12, KANJI_SJIS_L2, // 鰒 + 0x9C0A, KANJI_SJIS_L2, // 鰊 + 0x9C04, KANJI_SJIS_L2, // 鰄 + 0x9C2E, KANJI_SJIS_L2, // é°® + 0x9C1B, KANJI_SJIS_L2, // 鰛 + 0x9C25, KANJI_SJIS_L2, // é°¥ + 0x9C24, KANJI_SJIS_L2, // é°€ + 0x9C21, KANJI_SJIS_L2, // é°¡ + 0x9C30, KANJI_SJIS_L2, // é°° + 0x9C47, KANJI_SJIS_L2, // 鱇 + 0x9C32, KANJI_SJIS_L2, // é°² + 0x9C46, KANJI_SJIS_L2, // 鱆 + 0x9C3E, KANJI_SJIS_L2, // é°Ÿ + 0x9C5A, KANJI_SJIS_L2, // 鱚 + 0x9C60, KANJI_SJIS_L2, // é±  + 0x9C67, KANJI_SJIS_L2, // é±§ + 0x9C76, KANJI_SJIS_L2, // é±¶ + 0x9C78, KANJI_SJIS_L2, // 鱞 + 0x9CE7, KANJI_SJIS_L2, // é³§ + 0x9CEC, KANJI_SJIS_L2, // 鳬 + 0x9CF0, KANJI_SJIS_L2, // é³° + 0x9D09, KANJI_SJIS_L2, // 鮉 + 0x9D08, KANJI_SJIS_L2, // 鎈 + 0x9CEB, KANJI_SJIS_L2, // 鳫 + 0x9D03, KANJI_SJIS_L2, // 鎃 + 0x9D06, KANJI_SJIS_L2, // 鮆 + 0x9D2A, KANJI_SJIS_L2, // 鎪 + 0x9D26, KANJI_SJIS_L2, // 鎊 + 0x9DAF, KANJI_SJIS_L2, // 鶯 + 0x9D23, KANJI_SJIS_L2, // 鎣 + 0x9D1F, KANJI_SJIS_L2, // 鮟 + 0x9D44, KANJI_SJIS_L2, // 鵄 + 0x9D15, KANJI_SJIS_L2, // 鮕 + 0x9D12, KANJI_SJIS_L2, // 鮒 + 0x9D41, KANJI_SJIS_L2, // 鵁 + 0x9D3F, KANJI_SJIS_L2, // 鎿 + 0x9D3E, KANJI_SJIS_L2, // 鎟 + 0x9D46, KANJI_SJIS_L2, // 鵆 + 0x9D48, KANJI_SJIS_L2, // 鵈 + 0x9D5D, KANJI_SJIS_L2, // 鵝 + 0x9D5E, KANJI_SJIS_L2, // 鵞 + 0x9D64, KANJI_SJIS_L2, // éµ€ + 0x9D51, KANJI_SJIS_L2, // 鵑 + 0x9D50, KANJI_SJIS_L2, // 鵐 + 0x9D59, KANJI_SJIS_L2, // 鵙 + 0x9D72, KANJI_SJIS_L2, // éµ² + 0x9D89, KANJI_SJIS_L2, // 鶉 + 0x9D87, KANJI_SJIS_L2, // 鶇 + 0x9DAB, KANJI_SJIS_L2, // é¶« + 0x9D6F, KANJI_SJIS_L2, // 鵯 + 0x9D7A, KANJI_SJIS_L2, // 鵺 + 0x9D9A, KANJI_SJIS_L2, // 鶚 + 0x9DA4, KANJI_SJIS_L2, // é¶€ + 0x9DA9, KANJI_SJIS_L2, // é¶© + 0x9DB2, KANJI_SJIS_L2, // é¶² + 0x9DC4, KANJI_SJIS_L2, // 鷄 + 0x9DC1, KANJI_SJIS_L2, // 鷁 + 0x9DBB, KANJI_SJIS_L2, // é¶» + 0x9DB8, KANJI_SJIS_L2, // é¶ž + 0x9DBA, KANJI_SJIS_L2, // 鶺 + 0x9DC6, KANJI_SJIS_L2, // 鷆 + 0x9DCF, KANJI_SJIS_L2, // 鷏 + 0x9DC2, KANJI_SJIS_L2, // 鷂 + 0x9DD9, KANJI_SJIS_L2, // 鷙 + 0x9DD3, KANJI_SJIS_L2, // 鷓 + 0x9DF8, KANJI_SJIS_L2, // é·ž + 0x9DE6, KANJI_SJIS_L2, // é·Š + 0x9DED, KANJI_SJIS_L2, // é·­ + 0x9DEF, KANJI_SJIS_L2, // é·¯ + 0x9DFD, KANJI_SJIS_L2, // é·œ + 0x9E1A, KANJI_SJIS_L2, // 龚 + 0x9E1B, KANJI_SJIS_L2, // 龛 + 0x9E1E, KANJI_SJIS_L2, // 龞 + 0x9E75, KANJI_SJIS_L2, // é¹µ + 0x9E79, KANJI_SJIS_L2, // é¹¹ + 0x9E7D, KANJI_SJIS_L2, // 鹜 + 0x9E81, KANJI_SJIS_L2, // 麁 + 0x9E88, KANJI_SJIS_L2, // 麈 + 0x9E8B, KANJI_SJIS_L2, // 麋 + 0x9E8C, KANJI_SJIS_L2, // 麌 + 0x9E92, KANJI_SJIS_L2, // 麒 + 0x9E95, KANJI_SJIS_L2, // 麕 + 0x9E91, KANJI_SJIS_L2, // 麑 + 0x9E9D, KANJI_SJIS_L2, // 麝 + 0x9EA5, KANJI_SJIS_L2, // 麥 + 0x9EA9, KANJI_SJIS_L2, // 麩 + 0x9EB8, KANJI_SJIS_L2, // 麞 + 0x9EAA, KANJI_SJIS_L2, // 麪 + 0x9EAD, KANJI_SJIS_L2, // 麭 + 0x9761, KANJI_SJIS_L2, // 靡 + 0x9ECC, KANJI_SJIS_L2, // 黌 + 0x9ECE, KANJI_SJIS_L2, // 黎 + 0x9ECF, KANJI_SJIS_L2, // 黏 + 0x9ED0, KANJI_SJIS_L2, // 黐 + 0x9ED4, KANJI_SJIS_L2, // 黔 + 0x9EDC, KANJI_SJIS_L2, // 黜 + 0x9EDE, KANJI_SJIS_L2, // 點 + 0x9EDD, KANJI_SJIS_L2, // 黝 + 0x9EE0, KANJI_SJIS_L2, // é»  + 0x9EE5, KANJI_SJIS_L2, // 黥 + 0x9EE8, KANJI_SJIS_L2, // 黚 + 0x9EEF, KANJI_SJIS_L2, // 黯 + 0x3000, KANJI_SJIS_L2, //   + 0x9EF4, KANJI_SJIS_L2, // 黎 + 0x9EF6, KANJI_SJIS_L2, // é»¶ + 0x9EF7, KANJI_SJIS_L2, // é»· + 0x9EF9, KANJI_SJIS_L2, // 黹 + 0x9EFB, KANJI_SJIS_L2, // é»» + 0x9EFC, KANJI_SJIS_L2, // 黌 + 0x9EFD, KANJI_SJIS_L2, // 黜 + 0x9F07, KANJI_SJIS_L2, // 錇 + 0x9F08, KANJI_SJIS_L2, // 錈 + 0x76B7, KANJI_SJIS_L2, // 皷 + 0x9F15, KANJI_SJIS_L2, // 錕 + 0x9F21, KANJI_SJIS_L2, // 錡 + 0x9F2C, KANJI_SJIS_L2, // 錬 + 0x9F3E, KANJI_SJIS_L2, // 錟 + 0x9F4A, KANJI_SJIS_L2, // 霊 + 0x9F52, KANJI_SJIS_L2, // 霒 + 0x9F54, KANJI_SJIS_L2, // 霔 + 0x9F63, KANJI_SJIS_L2, // 霣 + 0x9F5F, KANJI_SJIS_L2, // 霟 + 0x9F60, KANJI_SJIS_L2, // 霠 + 0x9F61, KANJI_SJIS_L2, // 霡 + 0x9F66, KANJI_SJIS_L2, // 霊 + 0x9F67, KANJI_SJIS_L2, // 霧 + 0x9F6C, KANJI_SJIS_L2, // 霬 + 0x9F6A, KANJI_SJIS_L2, // 霪 + 0x9F77, KANJI_SJIS_L2, // 霷 + 0x9F72, KANJI_SJIS_L2, // 露 + 0x9F76, KANJI_SJIS_L2, // 霶 + 0x9F95, KANJI_SJIS_L2, // 韕 + 0x9F9C, KANJI_SJIS_L2, // 韜 + 0x9FA0, KANJI_SJIS_L2, // 韠 + 0x582F, KANJI_SJIS_L2, // å ¯ + 0x69C7, KANJI_SJIS_L2, // 槇 + 0x9059, KANJI_SJIS_L2, // 遙 + 0x7464, KANJI_SJIS_L2, // ç‘€ + 0x51DC, KANJI_SJIS_L2, // 凜 + 0x7199, KANJI_SJIS_L2, // 熙 + 0x7E8A, KANJI_SJIS_L3, // 纊 + 0x891C, KANJI_SJIS_L3, // 耜 + 0x9348, KANJI_SJIS_L3, // 鍈 + 0x9288, KANJI_SJIS_L3, // 銈 + 0x84DC, KANJI_SJIS_L3, // 蓜 + 0x4FC9, KANJI_SJIS_L3, // 俉 + 0x70BB, KANJI_SJIS_L3, // 炻 + 0x6631, KANJI_SJIS_L3, // 昱 + 0x68C8, KANJI_SJIS_L3, // 棈 + 0x92F9, KANJI_SJIS_L3, // 鋹 + 0x66FB, KANJI_SJIS_L3, // 曻 + 0x5F45, KANJI_SJIS_L3, // 圅 + 0x4E28, KANJI_SJIS_L3, // äžš + 0x4EE1, KANJI_SJIS_L3, // 仡 + 0x4EFC, KANJI_SJIS_L3, // 仌 + 0x4F00, KANJI_SJIS_L3, // 䌀 + 0x4F03, KANJI_SJIS_L3, // 䌃 + 0x4F39, KANJI_SJIS_L3, // 䌹 + 0x4F56, KANJI_SJIS_L3, // 䜖 + 0x4F92, KANJI_SJIS_L3, // 䟒 + 0x4F8A, KANJI_SJIS_L3, // 䟊 + 0x4F9A, KANJI_SJIS_L3, // 䟚 + 0x4F94, KANJI_SJIS_L3, // 䟔 + 0x4FCD, KANJI_SJIS_L3, // 俍 + 0x5040, KANJI_SJIS_L3, // 偀 + 0x5022, KANJI_SJIS_L3, // 倢 + 0x4FFF, KANJI_SJIS_L3, // ä¿¿ + 0x501E, KANJI_SJIS_L3, // 倞 + 0x5046, KANJI_SJIS_L3, // 偆 + 0x5070, KANJI_SJIS_L3, // 偰 + 0x5042, KANJI_SJIS_L3, // 偂 + 0x5094, KANJI_SJIS_L3, // 傔 + 0x50F4, KANJI_SJIS_L3, // 僎 + 0x50D8, KANJI_SJIS_L3, // 僘 + 0x514A, KANJI_SJIS_L3, // 兊 + 0x5164, KANJI_SJIS_L3, // å…€ + 0x519D, KANJI_SJIS_L3, // 冝 + 0x51BE, KANJI_SJIS_L3, // 冟 + 0x51EC, KANJI_SJIS_L3, // 凬 + 0x5215, KANJI_SJIS_L3, // 刕 + 0x529C, KANJI_SJIS_L3, // 劜 + 0x52A6, KANJI_SJIS_L3, // 劊 + 0x52C0, KANJI_SJIS_L3, // 勀 + 0x52DB, KANJI_SJIS_L3, // 勛 + 0x5300, KANJI_SJIS_L3, // 匀 + 0x5307, KANJI_SJIS_L3, // 匇 + 0x5324, KANJI_SJIS_L3, // 匀 + 0x5372, KANJI_SJIS_L3, // 卲 + 0x5393, KANJI_SJIS_L3, // 厓 + 0x53B2, KANJI_SJIS_L3, // 厲 + 0x53DD, KANJI_SJIS_L3, // 叝 + 0xFA0E, KANJI_SJIS_L3, //  + 0x549C, KANJI_SJIS_L3, // 咜 + 0x548A, KANJI_SJIS_L3, // 咊 + 0x54A9, KANJI_SJIS_L3, // 咩 + 0x54FF, KANJI_SJIS_L3, // 哿 + 0x5586, KANJI_SJIS_L3, // 喆 + 0x5759, KANJI_SJIS_L3, // 坙 + 0x5765, KANJI_SJIS_L3, // 坥 + 0x57AC, KANJI_SJIS_L3, // 垬 + 0x57C8, KANJI_SJIS_L3, // 埈 + 0x57C7, KANJI_SJIS_L3, // 埇 + 0xFA0F, KANJI_SJIS_L3, //  + 0x3000, KANJI_SJIS_L3, //   + 0xFA10, KANJI_SJIS_L3, //  + 0x589E, KANJI_SJIS_L3, // 增 + 0x58B2, KANJI_SJIS_L3, // 墲 + 0x590B, KANJI_SJIS_L3, // 個 + 0x5953, KANJI_SJIS_L3, // 奓 + 0x595B, KANJI_SJIS_L3, // 奛 + 0x595D, KANJI_SJIS_L3, // 奝 + 0x5963, KANJI_SJIS_L3, // 奣 + 0x59A4, KANJI_SJIS_L3, // 劀 + 0x59BA, KANJI_SJIS_L3, // 劺 + 0x5B56, KANJI_SJIS_L3, // 孖 + 0x5BC0, KANJI_SJIS_L3, // 寀 + 0x752F, KANJI_SJIS_L3, // 甯 + 0x5BD8, KANJI_SJIS_L3, // 寘 + 0x5BEC, KANJI_SJIS_L3, // 寬 + 0x5C1E, KANJI_SJIS_L3, // 尞 + 0x5CA6, KANJI_SJIS_L3, // 岊 + 0x5CBA, KANJI_SJIS_L3, // 岺 + 0x5CF5, KANJI_SJIS_L3, // å³µ + 0x5D27, KANJI_SJIS_L3, // 厧 + 0x5D53, KANJI_SJIS_L3, // 嵓 + 0xFA11, KANJI_SJIS_L3, // ïš‘ + 0x5D42, KANJI_SJIS_L3, // 嵂 + 0x5D6D, KANJI_SJIS_L3, // åµ­ + 0x5DB8, KANJI_SJIS_L3, // å¶ž + 0x5DB9, KANJI_SJIS_L3, // å¶¹ + 0x5DD0, KANJI_SJIS_L3, // 巐 + 0x5F21, KANJI_SJIS_L3, // 匡 + 0x5F34, KANJI_SJIS_L3, // 匎 + 0x5F67, KANJI_SJIS_L3, // 圧 + 0x5FB7, KANJI_SJIS_L3, // 執 + 0x5FDE, KANJI_SJIS_L3, // 忞 + 0x605D, KANJI_SJIS_L3, // 恝 + 0x6085, KANJI_SJIS_L3, // 悅 + 0x608A, KANJI_SJIS_L3, // 悊 + 0x60DE, KANJI_SJIS_L3, // 惞 + 0x60D5, KANJI_SJIS_L3, // 惕 + 0x6120, KANJI_SJIS_L3, // 愠 + 0x60F2, KANJI_SJIS_L3, // 惲 + 0x6111, KANJI_SJIS_L3, // 愑 + 0x6137, KANJI_SJIS_L3, // 愷 + 0x6130, KANJI_SJIS_L3, // 愰 + 0x6198, KANJI_SJIS_L3, // 憘 + 0x6213, KANJI_SJIS_L3, // 戓 + 0x62A6, KANJI_SJIS_L3, // 把 + 0x63F5, KANJI_SJIS_L3, // 揵 + 0x6460, KANJI_SJIS_L3, // 摠 + 0x649D, KANJI_SJIS_L3, // 撝 + 0x64CE, KANJI_SJIS_L3, // 擎 + 0x654E, KANJI_SJIS_L3, // 敎 + 0x6600, KANJI_SJIS_L3, // 昀 + 0x6615, KANJI_SJIS_L3, // 昕 + 0x663B, KANJI_SJIS_L3, // 昻 + 0x6609, KANJI_SJIS_L3, // 昉 + 0x662E, KANJI_SJIS_L3, // 昮 + 0x661E, KANJI_SJIS_L3, // 昞 + 0x6624, KANJI_SJIS_L3, // 昀 + 0x6665, KANJI_SJIS_L3, // 晥 + 0x6657, KANJI_SJIS_L3, // 晗 + 0x6659, KANJI_SJIS_L3, // 晙 + 0xFA12, KANJI_SJIS_L3, // ïš’ + 0x6673, KANJI_SJIS_L3, // 晳 + 0x6699, KANJI_SJIS_L3, // 暙 + 0x66A0, KANJI_SJIS_L3, // 暠 + 0x66B2, KANJI_SJIS_L3, // 暲 + 0x66BF, KANJI_SJIS_L3, // 暿 + 0x66FA, KANJI_SJIS_L3, // 曺 + 0x670E, KANJI_SJIS_L3, // 朎 + 0xF929, KANJI_SJIS_L3, //  + 0x6766, KANJI_SJIS_L3, // 杊 + 0x67BB, KANJI_SJIS_L3, // 枻 + 0x6852, KANJI_SJIS_L3, // 桒 + 0x67C0, KANJI_SJIS_L3, // 柀 + 0x6801, KANJI_SJIS_L3, // 栁 + 0x6844, KANJI_SJIS_L3, // 桄 + 0x68CF, KANJI_SJIS_L3, // 棏 + 0xFA13, KANJI_SJIS_L3, // ïš“ + 0x6968, KANJI_SJIS_L3, // 楚 + 0xFA14, KANJI_SJIS_L3, // ïš” + 0x6998, KANJI_SJIS_L3, // 折 + 0x69E2, KANJI_SJIS_L3, // æ§¢ + 0x6A30, KANJI_SJIS_L3, // æš° + 0x6A6B, KANJI_SJIS_L3, // æ©« + 0x6A46, KANJI_SJIS_L3, // 橆 + 0x6A73, KANJI_SJIS_L3, // 橳 + 0x6A7E, KANJI_SJIS_L3, // 機 + 0x6AE2, KANJI_SJIS_L3, // æ«¢ + 0x6AE4, KANJI_SJIS_L3, // æ«€ + 0x6BD6, KANJI_SJIS_L3, // 毖 + 0x6C3F, KANJI_SJIS_L3, // æ°¿ + 0x6C5C, KANJI_SJIS_L3, // 汜 + 0x6C86, KANJI_SJIS_L3, // 沆 + 0x6C6F, KANJI_SJIS_L3, // 汯 + 0x6CDA, KANJI_SJIS_L3, // 泚 + 0x6D04, KANJI_SJIS_L3, // 掄 + 0x6D87, KANJI_SJIS_L3, // 涇 + 0x6D6F, KANJI_SJIS_L3, // 浯 + 0x6D96, KANJI_SJIS_L3, // 涖 + 0x6DAC, KANJI_SJIS_L3, // 涬 + 0x6DCF, KANJI_SJIS_L3, // 淏 + 0x6DF8, KANJI_SJIS_L3, // æ·ž + 0x6DF2, KANJI_SJIS_L3, // æ·² + 0x6DFC, KANJI_SJIS_L3, // æ·Œ + 0x6E39, KANJI_SJIS_L3, // æž¹ + 0x6E5C, KANJI_SJIS_L3, // 湜 + 0x6E27, KANJI_SJIS_L3, // æž§ + 0x6E3C, KANJI_SJIS_L3, // 枌 + 0x6EBF, KANJI_SJIS_L3, // 溿 + 0x6F88, KANJI_SJIS_L3, // 柈 + 0x6FB5, KANJI_SJIS_L3, // 柵 + 0x6FF5, KANJI_SJIS_L3, // 濵 + 0x7005, KANJI_SJIS_L3, // 瀅 + 0x7007, KANJI_SJIS_L3, // 瀇 + 0x7028, KANJI_SJIS_L3, // 瀹 + 0x7085, KANJI_SJIS_L3, // 炅 + 0x70AB, KANJI_SJIS_L3, // 炫 + 0x710F, KANJI_SJIS_L3, // 焏 + 0x7104, KANJI_SJIS_L3, // 焄 + 0x715C, KANJI_SJIS_L3, // 煜 + 0x7146, KANJI_SJIS_L3, // 煆 + 0x7147, KANJI_SJIS_L3, // 煇 + 0xFA15, KANJI_SJIS_L3, // ïš• + 0x71C1, KANJI_SJIS_L3, // 燁 + 0x71FE, KANJI_SJIS_L3, // 營 + 0x72B1, KANJI_SJIS_L3, // 犱 + 0x72BE, KANJI_SJIS_L3, // 犟 + 0x7324, KANJI_SJIS_L3, // 猀 + 0xFA16, KANJI_SJIS_L3, // ïš– + 0x7377, KANJI_SJIS_L3, // 獷 + 0x73BD, KANJI_SJIS_L3, // 玜 + 0x73C9, KANJI_SJIS_L3, // 珉 + 0x73D6, KANJI_SJIS_L3, // 珖 + 0x73E3, KANJI_SJIS_L3, // 珣 + 0x73D2, KANJI_SJIS_L3, // 珒 + 0x7407, KANJI_SJIS_L3, // 琇 + 0x73F5, KANJI_SJIS_L3, // 珵 + 0x7426, KANJI_SJIS_L3, // 琊 + 0x742A, KANJI_SJIS_L3, // 琪 + 0x7429, KANJI_SJIS_L3, // 琩 + 0x742E, KANJI_SJIS_L3, // 琮 + 0x7462, KANJI_SJIS_L3, // 瑢 + 0x7489, KANJI_SJIS_L3, // 璉 + 0x749F, KANJI_SJIS_L3, // 璟 + 0x7501, KANJI_SJIS_L3, // 甁 + 0x756F, KANJI_SJIS_L3, // 畯 + 0x7682, KANJI_SJIS_L3, // 皂 + 0x769C, KANJI_SJIS_L3, // 皜 + 0x769E, KANJI_SJIS_L3, // 皞 + 0x769B, KANJI_SJIS_L3, // 皛 + 0x76A6, KANJI_SJIS_L3, // 皩 + 0xFA17, KANJI_SJIS_L3, // ïš— + 0x7746, KANJI_SJIS_L3, // 睆 + 0x52AF, KANJI_SJIS_L3, // 劯 + 0x7821, KANJI_SJIS_L3, // ç ¡ + 0x784E, KANJI_SJIS_L3, // 硎 + 0x7864, KANJI_SJIS_L3, // ç¡€ + 0x787A, KANJI_SJIS_L3, // 硺 + 0x7930, KANJI_SJIS_L3, // 瀰 + 0xFA18, KANJI_SJIS_L3, //  + 0xFA19, KANJI_SJIS_L3, // ïš™ + 0xFA1A, KANJI_SJIS_L3, // ïšš + 0x7994, KANJI_SJIS_L3, // 穔 + 0xFA1B, KANJI_SJIS_L3, // ïš› + 0x799B, KANJI_SJIS_L3, // 穛 + 0x7AD1, KANJI_SJIS_L3, // 竑 + 0x7AE7, KANJI_SJIS_L3, // ç«§ + 0xFA1C, KANJI_SJIS_L3, // ïšœ + 0x7AEB, KANJI_SJIS_L3, // ç«« + 0x7B9E, KANJI_SJIS_L3, // 箞 + 0xFA1D, KANJI_SJIS_L3, //  + 0x7D48, KANJI_SJIS_L3, // 絈 + 0x7D5C, KANJI_SJIS_L3, // 絜 + 0x7DB7, KANJI_SJIS_L3, // ç¶· + 0x7DA0, KANJI_SJIS_L3, // ç¶  + 0x7DD6, KANJI_SJIS_L3, // 緖 + 0x7E52, KANJI_SJIS_L3, // 繒 + 0x7F47, KANJI_SJIS_L3, // 眇 + 0x7FA1, KANJI_SJIS_L3, // 矡 + 0xFA1E, KANJI_SJIS_L3, //  + 0x8301, KANJI_SJIS_L3, // 茁 + 0x8362, KANJI_SJIS_L3, // 荢 + 0x837F, KANJI_SJIS_L3, // 荿 + 0x83C7, KANJI_SJIS_L3, // 菇 + 0x83F6, KANJI_SJIS_L3, // 菶 + 0x8448, KANJI_SJIS_L3, // 葈 + 0x84B4, KANJI_SJIS_L3, // è’Ž + 0x8553, KANJI_SJIS_L3, // 蕓 + 0x8559, KANJI_SJIS_L3, // 蕙 + 0x3000, KANJI_SJIS_L3, //   + 0x856B, KANJI_SJIS_L3, // 蕫 + 0xFA1F, KANJI_SJIS_L3, //  + 0x85B0, KANJI_SJIS_L3, // 薰 + 0xFA20, KANJI_SJIS_L3, // ïš  + 0xFA21, KANJI_SJIS_L3, // ïš¡ + 0x8807, KANJI_SJIS_L3, // 蠇 + 0x88F5, KANJI_SJIS_L3, // 裵 + 0x8A12, KANJI_SJIS_L3, // èš’ + 0x8A37, KANJI_SJIS_L3, // èš· + 0x8A79, KANJI_SJIS_L3, // 詹 + 0x8AA7, KANJI_SJIS_L3, // 誧 + 0x8ABE, KANJI_SJIS_L3, // 誟 + 0x8ADF, KANJI_SJIS_L3, // 諟 + 0xFA22, KANJI_SJIS_L3, //  + 0x8AF6, KANJI_SJIS_L3, // è«¶ + 0x8B53, KANJI_SJIS_L3, // 譓 + 0x8B7F, KANJI_SJIS_L3, // è­¿ + 0x8CF0, KANJI_SJIS_L3, // è³° + 0x8CF4, KANJI_SJIS_L3, // 賎 + 0x8D12, KANJI_SJIS_L3, // 莒 + 0x8D76, KANJI_SJIS_L3, // èµ¶ + 0xFA23, KANJI_SJIS_L3, //  + 0x8ECF, KANJI_SJIS_L3, // 軏 + 0xFA24, KANJI_SJIS_L3, //  + 0xFA25, KANJI_SJIS_L3, //  + 0x9067, KANJI_SJIS_L3, // 遧 + 0x90DE, KANJI_SJIS_L3, // 郞 + 0xFA26, KANJI_SJIS_L3, //  + 0x9115, KANJI_SJIS_L3, // 鄕 + 0x9127, KANJI_SJIS_L3, // 鄧 + 0x91DA, KANJI_SJIS_L3, // 釚 + 0x91D7, KANJI_SJIS_L3, // 釗 + 0x91DE, KANJI_SJIS_L3, // 釞 + 0x91ED, KANJI_SJIS_L3, // 釭 + 0x91EE, KANJI_SJIS_L3, // 釮 + 0x91E4, KANJI_SJIS_L3, // 釀 + 0x91E5, KANJI_SJIS_L3, // 釥 + 0x9206, KANJI_SJIS_L3, // 鈆 + 0x9210, KANJI_SJIS_L3, // 鈐 + 0x920A, KANJI_SJIS_L3, // 鈊 + 0x923A, KANJI_SJIS_L3, // 鈺 + 0x9240, KANJI_SJIS_L3, // 鉀 + 0x923C, KANJI_SJIS_L3, // 鈌 + 0x924E, KANJI_SJIS_L3, // 鉎 + 0x9259, KANJI_SJIS_L3, // 鉙 + 0x9251, KANJI_SJIS_L3, // 鉑 + 0x9239, KANJI_SJIS_L3, // 鈹 + 0x9267, KANJI_SJIS_L3, // 鉧 + 0x92A7, KANJI_SJIS_L3, // 銧 + 0x9277, KANJI_SJIS_L3, // 鉷 + 0x9278, KANJI_SJIS_L3, // 鉾 + 0x92E7, KANJI_SJIS_L3, // 鋧 + 0x92D7, KANJI_SJIS_L3, // 鋗 + 0x92D9, KANJI_SJIS_L3, // 鋙 + 0x92D0, KANJI_SJIS_L3, // 鋐 + 0xFA27, KANJI_SJIS_L3, // ïš§ + 0x92D5, KANJI_SJIS_L3, // 鋕 + 0x92E0, KANJI_SJIS_L3, // 鋠 + 0x92D3, KANJI_SJIS_L3, // 鋓 + 0x9325, KANJI_SJIS_L3, // 錥 + 0x9321, KANJI_SJIS_L3, // 錡 + 0x92FB, KANJI_SJIS_L3, // 鋻 + 0xFA28, KANJI_SJIS_L3, // ïšš + 0x931E, KANJI_SJIS_L3, // 錞 + 0x92FF, KANJI_SJIS_L3, // 鋿 + 0x931D, KANJI_SJIS_L3, // 錝 + 0x9302, KANJI_SJIS_L3, // 錂 + 0x9370, KANJI_SJIS_L3, // 鍰 + 0x9357, KANJI_SJIS_L3, // 鍗 + 0x93A4, KANJI_SJIS_L3, // 鎀 + 0x93C6, KANJI_SJIS_L3, // 鏆 + 0x93DE, KANJI_SJIS_L3, // 鏞 + 0x93F8, KANJI_SJIS_L3, // 鏞 + 0x9431, KANJI_SJIS_L3, // 鐱 + 0x9445, KANJI_SJIS_L3, // 鑅 + 0x9448, KANJI_SJIS_L3, // 鑈 + 0x9592, KANJI_SJIS_L3, // 閒 + 0xF9DC, KANJI_SJIS_L3, // 隆 + 0xFA29, KANJI_SJIS_L3, // ïš© + 0x969D, KANJI_SJIS_L3, // 隝 + 0x96AF, KANJI_SJIS_L3, // 隯 + 0x9733, KANJI_SJIS_L3, // 霳 + 0x973B, KANJI_SJIS_L3, // 霻 + 0x9743, KANJI_SJIS_L3, // 靃 + 0x974D, KANJI_SJIS_L3, // 靍 + 0x974F, KANJI_SJIS_L3, // 靏 + 0x9751, KANJI_SJIS_L3, // 靑 + 0x9755, KANJI_SJIS_L3, // 靕 + 0x9857, KANJI_SJIS_L3, // 顗 + 0x9865, KANJI_SJIS_L3, // é¡¥ + 0xFA2A, KANJI_SJIS_L3, //  + 0xFA2B, KANJI_SJIS_L3, // ïš« + 0x9927, KANJI_SJIS_L3, // 逧 + 0xFA2C, KANJI_SJIS_L3, //  + 0x999E, KANJI_SJIS_L3, // 銞 + 0x9A4E, KANJI_SJIS_L3, // 驎 + 0x9AD9, KANJI_SJIS_L3, // 髙 + 0x9ADC, KANJI_SJIS_L3, // 髜 + 0x9B75, KANJI_SJIS_L3, // é­µ + 0x9B72, KANJI_SJIS_L3, // é­² + 0x9B8F, KANJI_SJIS_L3, // 鮏 + 0x9BB1, KANJI_SJIS_L3, // é®± + 0x9BBB, KANJI_SJIS_L3, // é®» + 0x9C00, KANJI_SJIS_L3, // 鰀 + 0x9D70, KANJI_SJIS_L3, // éµ° + 0x9D6B, KANJI_SJIS_L3, // 鵫 + 0xFA2D, KANJI_SJIS_L3, // ïš­ + 0x9E19, KANJI_SJIS_L3, // 龙 + 0x9ED1, KANJI_SJIS_L3, // 黑 + 0x7E8A, KANJI_SJIS_L3, // 纊 + 0x891C, KANJI_SJIS_L3, // 耜 + 0x9348, KANJI_SJIS_L3, // 鍈 + 0x9288, KANJI_SJIS_L3, // 銈 + 0x84DC, KANJI_SJIS_L3, // 蓜 + 0x4FC9, KANJI_SJIS_L3, // 俉 + 0x70BB, KANJI_SJIS_L3, // 炻 + 0x6631, KANJI_SJIS_L3, // 昱 + 0x68C8, KANJI_SJIS_L3, // 棈 + 0x92F9, KANJI_SJIS_L3, // 鋹 + 0x66FB, KANJI_SJIS_L3, // 曻 + 0x5F45, KANJI_SJIS_L3, // 圅 + 0x4E28, KANJI_SJIS_L3, // äžš + 0x4EE1, KANJI_SJIS_L3, // 仡 + 0x4EFC, KANJI_SJIS_L3, // 仌 + 0x4F00, KANJI_SJIS_L3, // 䌀 + 0x4F03, KANJI_SJIS_L3, // 䌃 + 0x4F39, KANJI_SJIS_L3, // 䌹 + 0x4F56, KANJI_SJIS_L3, // 䜖 + 0x4F92, KANJI_SJIS_L3, // 䟒 + 0x4F8A, KANJI_SJIS_L3, // 䟊 + 0x4F9A, KANJI_SJIS_L3, // 䟚 + 0x4F94, KANJI_SJIS_L3, // 䟔 + 0x4FCD, KANJI_SJIS_L3, // 俍 + 0x5040, KANJI_SJIS_L3, // 偀 + 0x5022, KANJI_SJIS_L3, // 倢 + 0x4FFF, KANJI_SJIS_L3, // ä¿¿ + 0x501E, KANJI_SJIS_L3, // 倞 + 0x5046, KANJI_SJIS_L3, // 偆 + 0x5070, KANJI_SJIS_L3, // 偰 + 0x5042, KANJI_SJIS_L3, // 偂 + 0x5094, KANJI_SJIS_L3, // 傔 + 0x50F4, KANJI_SJIS_L3, // 僎 + 0x50D8, KANJI_SJIS_L3, // 僘 + 0x514A, KANJI_SJIS_L3, // 兊 + 0x3000, KANJI_SJIS_L3, //   + 0x5164, KANJI_SJIS_L3, // å…€ + 0x519D, KANJI_SJIS_L3, // 冝 + 0x51BE, KANJI_SJIS_L3, // 冟 + 0x51EC, KANJI_SJIS_L3, // 凬 + 0x5215, KANJI_SJIS_L3, // 刕 + 0x529C, KANJI_SJIS_L3, // 劜 + 0x52A6, KANJI_SJIS_L3, // 劊 + 0x52C0, KANJI_SJIS_L3, // 勀 + 0x52DB, KANJI_SJIS_L3, // 勛 + 0x5300, KANJI_SJIS_L3, // 匀 + 0x5307, KANJI_SJIS_L3, // 匇 + 0x5324, KANJI_SJIS_L3, // 匀 + 0x5372, KANJI_SJIS_L3, // 卲 + 0x5393, KANJI_SJIS_L3, // 厓 + 0x53B2, KANJI_SJIS_L3, // 厲 + 0x53DD, KANJI_SJIS_L3, // 叝 + 0xFA0E, KANJI_SJIS_L3, //  + 0x549C, KANJI_SJIS_L3, // 咜 + 0x548A, KANJI_SJIS_L3, // 咊 + 0x54A9, KANJI_SJIS_L3, // 咩 + 0x54FF, KANJI_SJIS_L3, // 哿 + 0x5586, KANJI_SJIS_L3, // 喆 + 0x5759, KANJI_SJIS_L3, // 坙 + 0x5765, KANJI_SJIS_L3, // 坥 + 0x57AC, KANJI_SJIS_L3, // 垬 + 0x57C8, KANJI_SJIS_L3, // 埈 + 0x57C7, KANJI_SJIS_L3, // 埇 + 0xFA0F, KANJI_SJIS_L3, //  + 0xFA10, KANJI_SJIS_L3, //  + 0x589E, KANJI_SJIS_L3, // 增 + 0x58B2, KANJI_SJIS_L3, // 墲 + 0x590B, KANJI_SJIS_L3, // 個 + 0x5953, KANJI_SJIS_L3, // 奓 + 0x595B, KANJI_SJIS_L3, // 奛 + 0x595D, KANJI_SJIS_L3, // 奝 + 0x5963, KANJI_SJIS_L3, // 奣 + 0x59A4, KANJI_SJIS_L3, // 劀 + 0x59BA, KANJI_SJIS_L3, // 劺 + 0x5B56, KANJI_SJIS_L3, // 孖 + 0x5BC0, KANJI_SJIS_L3, // 寀 + 0x752F, KANJI_SJIS_L3, // 甯 + 0x5BD8, KANJI_SJIS_L3, // 寘 + 0x5BEC, KANJI_SJIS_L3, // 寬 + 0x5C1E, KANJI_SJIS_L3, // 尞 + 0x5CA6, KANJI_SJIS_L3, // 岊 + 0x5CBA, KANJI_SJIS_L3, // 岺 + 0x5CF5, KANJI_SJIS_L3, // å³µ + 0x5D27, KANJI_SJIS_L3, // 厧 + 0x5D53, KANJI_SJIS_L3, // 嵓 + 0xFA11, KANJI_SJIS_L3, // ïš‘ + 0x5D42, KANJI_SJIS_L3, // 嵂 + 0x5D6D, KANJI_SJIS_L3, // åµ­ + 0x5DB8, KANJI_SJIS_L3, // å¶ž + 0x5DB9, KANJI_SJIS_L3, // å¶¹ + 0x5DD0, KANJI_SJIS_L3, // 巐 + 0x5F21, KANJI_SJIS_L3, // 匡 + 0x5F34, KANJI_SJIS_L3, // 匎 + 0x5F67, KANJI_SJIS_L3, // 圧 + 0x5FB7, KANJI_SJIS_L3, // 執 + 0x5FDE, KANJI_SJIS_L3, // 忞 + 0x605D, KANJI_SJIS_L3, // 恝 + 0x6085, KANJI_SJIS_L3, // 悅 + 0x608A, KANJI_SJIS_L3, // 悊 + 0x60DE, KANJI_SJIS_L3, // 惞 + 0x60D5, KANJI_SJIS_L3, // 惕 + 0x6120, KANJI_SJIS_L3, // 愠 + 0x60F2, KANJI_SJIS_L3, // 惲 + 0x6111, KANJI_SJIS_L3, // 愑 + 0x6137, KANJI_SJIS_L3, // 愷 + 0x6130, KANJI_SJIS_L3, // 愰 + 0x6198, KANJI_SJIS_L3, // 憘 + 0x6213, KANJI_SJIS_L3, // 戓 + 0x62A6, KANJI_SJIS_L3, // 把 + 0x63F5, KANJI_SJIS_L3, // 揵 + 0x6460, KANJI_SJIS_L3, // 摠 + 0x649D, KANJI_SJIS_L3, // 撝 + 0x64CE, KANJI_SJIS_L3, // 擎 + 0x654E, KANJI_SJIS_L3, // 敎 + 0x6600, KANJI_SJIS_L3, // 昀 + 0x6615, KANJI_SJIS_L3, // 昕 + 0x663B, KANJI_SJIS_L3, // 昻 + 0x6609, KANJI_SJIS_L3, // 昉 + 0x662E, KANJI_SJIS_L3, // 昮 + 0x661E, KANJI_SJIS_L3, // 昞 + 0x6624, KANJI_SJIS_L3, // 昀 + 0x6665, KANJI_SJIS_L3, // 晥 + 0x6657, KANJI_SJIS_L3, // 晗 + 0x6659, KANJI_SJIS_L3, // 晙 + 0xFA12, KANJI_SJIS_L3, // ïš’ + 0x6673, KANJI_SJIS_L3, // 晳 + 0x6699, KANJI_SJIS_L3, // 暙 + 0x66A0, KANJI_SJIS_L3, // 暠 + 0x66B2, KANJI_SJIS_L3, // 暲 + 0x66BF, KANJI_SJIS_L3, // 暿 + 0x66FA, KANJI_SJIS_L3, // 曺 + 0x670E, KANJI_SJIS_L3, // 朎 + 0xF929, KANJI_SJIS_L3, //  + 0x6766, KANJI_SJIS_L3, // 杊 + 0x67BB, KANJI_SJIS_L3, // 枻 + 0x6852, KANJI_SJIS_L3, // 桒 + 0x67C0, KANJI_SJIS_L3, // 柀 + 0x6801, KANJI_SJIS_L3, // 栁 + 0x6844, KANJI_SJIS_L3, // 桄 + 0x68CF, KANJI_SJIS_L3, // 棏 + 0xFA13, KANJI_SJIS_L3, // ïš“ + 0x6968, KANJI_SJIS_L3, // 楚 + 0xFA14, KANJI_SJIS_L3, // ïš” + 0x6998, KANJI_SJIS_L3, // 折 + 0x69E2, KANJI_SJIS_L3, // æ§¢ + 0x6A30, KANJI_SJIS_L3, // æš° + 0x6A6B, KANJI_SJIS_L3, // æ©« + 0x6A46, KANJI_SJIS_L3, // 橆 + 0x6A73, KANJI_SJIS_L3, // 橳 + 0x6A7E, KANJI_SJIS_L3, // 機 + 0x6AE2, KANJI_SJIS_L3, // æ«¢ + 0x6AE4, KANJI_SJIS_L3, // æ«€ + 0x6BD6, KANJI_SJIS_L3, // 毖 + 0x6C3F, KANJI_SJIS_L3, // æ°¿ + 0x6C5C, KANJI_SJIS_L3, // 汜 + 0x6C86, KANJI_SJIS_L3, // 沆 + 0x6C6F, KANJI_SJIS_L3, // 汯 + 0x6CDA, KANJI_SJIS_L3, // 泚 + 0x6D04, KANJI_SJIS_L3, // 掄 + 0x6D87, KANJI_SJIS_L3, // 涇 + 0x6D6F, KANJI_SJIS_L3, // 浯 + 0x6D96, KANJI_SJIS_L3, // 涖 + 0x6DAC, KANJI_SJIS_L3, // 涬 + 0x6DCF, KANJI_SJIS_L3, // 淏 + 0x6DF8, KANJI_SJIS_L3, // æ·ž + 0x6DF2, KANJI_SJIS_L3, // æ·² + 0x6DFC, KANJI_SJIS_L3, // æ·Œ + 0x6E39, KANJI_SJIS_L3, // æž¹ + 0x6E5C, KANJI_SJIS_L3, // 湜 + 0x6E27, KANJI_SJIS_L3, // æž§ + 0x6E3C, KANJI_SJIS_L3, // 枌 + 0x6EBF, KANJI_SJIS_L3, // 溿 + 0x6F88, KANJI_SJIS_L3, // 柈 + 0x6FB5, KANJI_SJIS_L3, // 柵 + 0x6FF5, KANJI_SJIS_L3, // 濵 + 0x7005, KANJI_SJIS_L3, // 瀅 + 0x7007, KANJI_SJIS_L3, // 瀇 + 0x7028, KANJI_SJIS_L3, // 瀹 + 0x7085, KANJI_SJIS_L3, // 炅 + 0x70AB, KANJI_SJIS_L3, // 炫 + 0x710F, KANJI_SJIS_L3, // 焏 + 0x7104, KANJI_SJIS_L3, // 焄 + 0x715C, KANJI_SJIS_L3, // 煜 + 0x7146, KANJI_SJIS_L3, // 煆 + 0x7147, KANJI_SJIS_L3, // 煇 + 0xFA15, KANJI_SJIS_L3, // ïš• + 0x71C1, KANJI_SJIS_L3, // 燁 + 0x71FE, KANJI_SJIS_L3, // 營 + 0x72B1, KANJI_SJIS_L3, // 犱 + 0x72BE, KANJI_SJIS_L3, // 犟 + 0x7324, KANJI_SJIS_L3, // 猀 + 0xFA16, KANJI_SJIS_L3, // ïš– + 0x7377, KANJI_SJIS_L3, // 獷 + 0x73BD, KANJI_SJIS_L3, // 玜 + 0x73C9, KANJI_SJIS_L3, // 珉 + 0x73D6, KANJI_SJIS_L3, // 珖 + 0x73E3, KANJI_SJIS_L3, // 珣 + 0x73D2, KANJI_SJIS_L3, // 珒 + 0x7407, KANJI_SJIS_L3, // 琇 + 0x73F5, KANJI_SJIS_L3, // 珵 + 0x7426, KANJI_SJIS_L3, // 琊 + 0x742A, KANJI_SJIS_L3, // 琪 + 0x7429, KANJI_SJIS_L3, // 琩 + 0x742E, KANJI_SJIS_L3, // 琮 + 0x7462, KANJI_SJIS_L3, // 瑢 + 0x7489, KANJI_SJIS_L3, // 璉 + 0x749F, KANJI_SJIS_L3, // 璟 + 0x7501, KANJI_SJIS_L3, // 甁 + 0x756F, KANJI_SJIS_L3, // 畯 + 0x7682, KANJI_SJIS_L3, // 皂 + 0x769C, KANJI_SJIS_L3, // 皜 + 0x769E, KANJI_SJIS_L3, // 皞 + 0x769B, KANJI_SJIS_L3, // 皛 + 0x76A6, KANJI_SJIS_L3, // 皩 + 0xFA17, KANJI_SJIS_L3, // ïš— + 0x7746, KANJI_SJIS_L3, // 睆 + 0x52AF, KANJI_SJIS_L3, // 劯 + 0x7821, KANJI_SJIS_L3, // ç ¡ + 0x784E, KANJI_SJIS_L3, // 硎 + 0x7864, KANJI_SJIS_L3, // ç¡€ + 0x787A, KANJI_SJIS_L3, // 硺 + 0x7930, KANJI_SJIS_L3, // 瀰 + 0xFA18, KANJI_SJIS_L3, //  + 0xFA19, KANJI_SJIS_L3, // ïš™ + 0x3000, KANJI_SJIS_L3, //   + 0xFA1A, KANJI_SJIS_L3, // ïšš + 0x7994, KANJI_SJIS_L3, // 穔 + 0xFA1B, KANJI_SJIS_L3, // ïš› + 0x799B, KANJI_SJIS_L3, // 穛 + 0x7AD1, KANJI_SJIS_L3, // 竑 + 0x7AE7, KANJI_SJIS_L3, // ç«§ + 0xFA1C, KANJI_SJIS_L3, // ïšœ + 0x7AEB, KANJI_SJIS_L3, // ç«« + 0x7B9E, KANJI_SJIS_L3, // 箞 + 0xFA1D, KANJI_SJIS_L3, //  + 0x7D48, KANJI_SJIS_L3, // 絈 + 0x7D5C, KANJI_SJIS_L3, // 絜 + 0x7DB7, KANJI_SJIS_L3, // ç¶· + 0x7DA0, KANJI_SJIS_L3, // ç¶  + 0x7DD6, KANJI_SJIS_L3, // 緖 + 0x7E52, KANJI_SJIS_L3, // 繒 + 0x7F47, KANJI_SJIS_L3, // 眇 + 0x7FA1, KANJI_SJIS_L3, // 矡 + 0xFA1E, KANJI_SJIS_L3, //  + 0x8301, KANJI_SJIS_L3, // 茁 + 0x8362, KANJI_SJIS_L3, // 荢 + 0x837F, KANJI_SJIS_L3, // 荿 + 0x83C7, KANJI_SJIS_L3, // 菇 + 0x83F6, KANJI_SJIS_L3, // 菶 + 0x8448, KANJI_SJIS_L3, // 葈 + 0x84B4, KANJI_SJIS_L3, // è’Ž + 0x8553, KANJI_SJIS_L3, // 蕓 + 0x8559, KANJI_SJIS_L3, // 蕙 + 0x856B, KANJI_SJIS_L3, // 蕫 + 0xFA1F, KANJI_SJIS_L3, //  + 0x85B0, KANJI_SJIS_L3, // 薰 + 0xFA20, KANJI_SJIS_L3, // ïš  + 0xFA21, KANJI_SJIS_L3, // ïš¡ + 0x8807, KANJI_SJIS_L3, // 蠇 + 0x88F5, KANJI_SJIS_L3, // 裵 + 0x8A12, KANJI_SJIS_L3, // èš’ + 0x8A37, KANJI_SJIS_L3, // èš· + 0x8A79, KANJI_SJIS_L3, // 詹 + 0x8AA7, KANJI_SJIS_L3, // 誧 + 0x8ABE, KANJI_SJIS_L3, // 誟 + 0x8ADF, KANJI_SJIS_L3, // 諟 + 0xFA22, KANJI_SJIS_L3, //  + 0x8AF6, KANJI_SJIS_L3, // è«¶ + 0x8B53, KANJI_SJIS_L3, // 譓 + 0x8B7F, KANJI_SJIS_L3, // è­¿ + 0x8CF0, KANJI_SJIS_L3, // è³° + 0x8CF4, KANJI_SJIS_L3, // 賎 + 0x8D12, KANJI_SJIS_L3, // 莒 + 0x8D76, KANJI_SJIS_L3, // èµ¶ + 0xFA23, KANJI_SJIS_L3, //  + 0x8ECF, KANJI_SJIS_L3, // 軏 + 0xFA24, KANJI_SJIS_L3, //  + 0xFA25, KANJI_SJIS_L3, //  + 0x9067, KANJI_SJIS_L3, // 遧 + 0x90DE, KANJI_SJIS_L3, // 郞 + 0xFA26, KANJI_SJIS_L3, //  + 0x9115, KANJI_SJIS_L3, // 鄕 + 0x9127, KANJI_SJIS_L3, // 鄧 + 0x91DA, KANJI_SJIS_L3, // 釚 + 0x91D7, KANJI_SJIS_L3, // 釗 + 0x91DE, KANJI_SJIS_L3, // 釞 + 0x91ED, KANJI_SJIS_L3, // 釭 + 0x91EE, KANJI_SJIS_L3, // 釮 + 0x91E4, KANJI_SJIS_L3, // 釀 + 0x91E5, KANJI_SJIS_L3, // 釥 + 0x9206, KANJI_SJIS_L3, // 鈆 + 0x9210, KANJI_SJIS_L3, // 鈐 + 0x920A, KANJI_SJIS_L3, // 鈊 + 0x923A, KANJI_SJIS_L3, // 鈺 + 0x9240, KANJI_SJIS_L3, // 鉀 + 0x923C, KANJI_SJIS_L3, // 鈌 + 0x924E, KANJI_SJIS_L3, // 鉎 + 0x9259, KANJI_SJIS_L3, // 鉙 + 0x9251, KANJI_SJIS_L3, // 鉑 + 0x9239, KANJI_SJIS_L3, // 鈹 + 0x9267, KANJI_SJIS_L3, // 鉧 + 0x92A7, KANJI_SJIS_L3, // 銧 + 0x9277, KANJI_SJIS_L3, // 鉷 + 0x9278, KANJI_SJIS_L3, // 鉾 + 0x92E7, KANJI_SJIS_L3, // 鋧 + 0x92D7, KANJI_SJIS_L3, // 鋗 + 0x92D9, KANJI_SJIS_L3, // 鋙 + 0x92D0, KANJI_SJIS_L3, // 鋐 + 0xFA27, KANJI_SJIS_L3, // ïš§ + 0x92D5, KANJI_SJIS_L3, // 鋕 + 0x92E0, KANJI_SJIS_L3, // 鋠 + 0x92D3, KANJI_SJIS_L3, // 鋓 + 0x9325, KANJI_SJIS_L3, // 錥 + 0x9321, KANJI_SJIS_L3, // 錡 + 0x92FB, KANJI_SJIS_L3, // 鋻 + 0xFA28, KANJI_SJIS_L3, // ïšš + 0x931E, KANJI_SJIS_L3, // 錞 + 0x9357, KANJI_SJIS_L3, // 鍗 + 0x93A4, KANJI_SJIS_L3, // 鎀 + 0x93C6, KANJI_SJIS_L3, // 鏆 + 0x93DE, KANJI_SJIS_L3, // 鏞 + 0x93F8, KANJI_SJIS_L3, // 鏞 + 0x9431, KANJI_SJIS_L3, // 鐱 + 0x9445, KANJI_SJIS_L3, // 鑅 + 0x9448, KANJI_SJIS_L3, // 鑈 + 0x9592, KANJI_SJIS_L3, // 閒 + 0xF9DC, KANJI_SJIS_L3, // 隆 + 0xFA29, KANJI_SJIS_L3, // ïš© + 0x969D, KANJI_SJIS_L3, // 隝 + 0x96AF, KANJI_SJIS_L3, // 隯 + 0x9733, KANJI_SJIS_L3, // 霳 + 0x973B, KANJI_SJIS_L3, // 霻 + 0x9743, KANJI_SJIS_L3, // 靃 + 0x974D, KANJI_SJIS_L3, // 靍 + 0x974F, KANJI_SJIS_L3, // 靏 + 0x9751, KANJI_SJIS_L3, // 靑 + 0x9755, KANJI_SJIS_L3, // 靕 + 0x9857, KANJI_SJIS_L3, // 顗 + 0x9865, KANJI_SJIS_L3, // é¡¥ + 0xFA2A, KANJI_SJIS_L3, //  + 0xFA2B, KANJI_SJIS_L3, // ïš« + 0x9927, KANJI_SJIS_L3, // 逧 + 0xFA2C, KANJI_SJIS_L3, //  + 0x999E, KANJI_SJIS_L3, // 銞 + 0x9A4E, KANJI_SJIS_L3, // 驎 + 0x9AD9, KANJI_SJIS_L3, // 髙 + 0x9ADC, KANJI_SJIS_L3, // 髜 + 0x9B75, KANJI_SJIS_L3, // é­µ + 0x9B72, KANJI_SJIS_L3, // é­² + 0x9B8F, KANJI_SJIS_L3, // 鮏 + 0x9BB1, KANJI_SJIS_L3, // é®± + 0x9BBB, KANJI_SJIS_L3, // é®» + 0x9C00, KANJI_SJIS_L3, // 鰀 + 0x9D70, KANJI_SJIS_L3, // éµ° + 0x9D6B, KANJI_SJIS_L3, // 鵫 + 0xFA2D, KANJI_SJIS_L3, // ïš­ + 0x9E19, KANJI_SJIS_L3, // 龙 + 0x9ED1, KANJI_SJIS_L3, // 黑 +}; \ No newline at end of file diff --git a/ext/native/tools/zimtool.cpp b/ext/native/tools/zimtool.cpp new file mode 100644 index 0000000000..69f84221b3 --- /dev/null +++ b/ext/native/tools/zimtool.cpp @@ -0,0 +1,100 @@ +#include +#include +#include + +#include "base/logging.h" +#include "image/png_load.h" +#include "image/zim_save.h" + +char magic[5] = "ZIMG"; + +bool FLAGS_flip = false; + +const char *format_strings[4] = {"8888", "4444", "565", "ETC1"}; +int formats[4] = {ZIM_RGBA8888, ZIM_RGBA4444, ZIM_RGB565, ZIM_ETC1}; + +void printusage() { + fprintf(stderr, "Usage: zimtool infile.png outfile.zim [-f=FORMAT] [-m] [-g]\n"); + fprintf(stderr, "Formats: 8888 4444 565 ETC1\n"); +} + +int filesize(const char *filename) { + FILE *f = fopen(filename, "rb"); + fseek(f, 0, SEEK_END); + int sz = ftell(f); + fclose(f); + return sz; +} + +int main(int argc, char **argv) { + // Parse command line arguments. + const char *FLAGS_infile; + const char *FLAGS_outfile; + if (argc >= 3) { + FLAGS_infile = argv[1]; + FLAGS_outfile = argv[2]; + } else { + fprintf(stderr, "ERROR: Not enough parameters.\n"); + printusage(); + return 1; + } + + int flags = 0; + bool format_set = false; + for (int i = 3; i < argc; i++) { + if (argv[i][0] != '-') { + fprintf(stderr, "Additional arguments must start with '-'\n"); + return 1; + } + switch (argv[i][1]) { + case 'm': + flags |= ZIM_HAS_MIPS; + // Generates mips directly here. We can generate gamma + // corrected mips, and mips for ETC1. + break; + case 'g': + flags |= ZIM_GEN_MIPS; + break; + case 'c': + flags |= ZIM_CLAMP; + break; + case 'f': + { + for (int j = 0; j < 4; j++) { + if (!strcmp(format_strings[j], argv[i] + 3)) { + flags |= j; + format_set = true; + } + } + } + break; + } + } + // TODO: make setting? + flags |= ZIM_ETC1_MEDIUM; + if ((flags & ZIM_FORMAT_MASK) == ZIM_ETC1) { + if (flags & ZIM_GEN_MIPS) { + fprintf(stderr, "WARNING: Cannot generate ETC1 mips at runtime\n"); + flags &= ~ZIM_GEN_MIPS; + } + } + if (!format_set) { + fprintf(stderr, "Must set format\n"); + printusage(); + return 1; + } + + uint8_t *image_data; + int width, height; + if (1 != pngLoad(FLAGS_infile, &width, &height, &image_data, FLAGS_flip)) { + fprintf(stderr, "Input not a PNG file\n"); + printusage(); + return 1; + } + + SaveZIM(FLAGS_outfile, width, height, width * 4, flags, image_data); + int in_file_size = filesize(FLAGS_infile); + int out_file_size = filesize(FLAGS_outfile); + fprintf(stdout, "Converted %s to %s. %i b to %i b. %ix%i, %s.\n", FLAGS_infile, FLAGS_outfile, in_file_size, out_file_size, width, height, format_strings[flags & ZIM_FORMAT_MASK]); + return 0; +} diff --git a/ext/native/tools/zimtool/zimtool.vcxproj b/ext/native/tools/zimtool/zimtool.vcxproj new file mode 100644 index 0000000000..bd3087f108 --- /dev/null +++ b/ext/native/tools/zimtool/zimtool.vcxproj @@ -0,0 +1,97 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7055E1C3-0B42-40E4-80B0-8146A647FC5B} + Win32Proj + zimtool + + + + Application + true + MultiByte + v120 + + + Application + false + false + MultiByte + v120 + + + + + + + + + + + + + true + + + false + $(ProjectDir)\..\build\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..;..\..\..\glew;..\..\SDL\include;%(AdditionalIncludeDirectories); + + + Console + true + kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..;..\..\..\glew;..\..\SDL\include;%(AdditionalIncludeDirectories); + + + Console + true + true + true + kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies) + + + + + + + + {f761046e-6c38-4428-a5f1-38391a37bb34} + + + {C4DF647E-80EA-4111-A0A8-218B1B711E18} + + + + + + \ No newline at end of file diff --git a/ext/native/tools/zimtool/zimtool.vcxproj.filters b/ext/native/tools/zimtool/zimtool.vcxproj.filters new file mode 100644 index 0000000000..1b836b2f43 --- /dev/null +++ b/ext/native/tools/zimtool/zimtool.vcxproj.filters @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ext/native/ui/CMakeLists.txt b/ext/native/ui/CMakeLists.txt new file mode 100644 index 0000000000..37c0ab1194 --- /dev/null +++ b/ext/native/ui/CMakeLists.txt @@ -0,0 +1,17 @@ +set(SRCS + ui.cpp + ui_context.cpp + view.cpp + viewgroup.cpp + screen.cpp + virtual_input.cpp +) + +set(SRCS ${SRCS}) + +add_library(ui STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) + diff --git a/ext/native/ui/screen.cpp b/ext/native/ui/screen.cpp new file mode 100644 index 0000000000..341d9a01ec --- /dev/null +++ b/ext/native/ui/screen.cpp @@ -0,0 +1,230 @@ +#include "base/logging.h" +#include "input/input_state.h" +#include "ui/screen.h" +#include "ui/ui.h" +#include "ui/view.h" + +ScreenManager::ScreenManager() { + nextScreen_ = 0; + uiContext_ = 0; + dialogFinished_ = 0; +} + +ScreenManager::~ScreenManager() { + shutdown(); +} + +void ScreenManager::switchScreen(Screen *screen) { + if (screen == nextScreen_) { + ELOG("Already switching to this screen"); + return; + } + // Note that if a dialog is found, this will be a silent background switch that + // will only become apparent if the dialog is closed. The previous screen will stick around + // until that switch. + // TODO: is this still true? + if (nextScreen_ != 0) { + FLOG("Already had a nextScreen_"); + } + if (screen == 0) { + WLOG("Swiching to a zero screen, this can't be good"); + } + if (stack_.empty() || screen != stack_.back().screen) { + nextScreen_ = screen; + nextScreen_->setScreenManager(this); + } +} + +void ScreenManager::update(InputState &input) { + if (nextScreen_) { + switchToNext(); + } + + if (stack_.size()) { + stack_.back().screen->update(input); + } +} + +void ScreenManager::switchToNext() { + if (!nextScreen_) { + ELOG("switchToNext: No nextScreen_!"); + } + + Layer temp = {0, 0}; + if (!stack_.empty()) { + temp = stack_.back(); + stack_.pop_back(); + } + Layer newLayer = {nextScreen_, 0}; + stack_.push_back(newLayer); + if (temp.screen) { + delete temp.screen; + } + nextScreen_ = 0; + UI::SetFocusedView(0); +} + +bool ScreenManager::touch(const TouchInput &touch) { + if (!stack_.empty()) { + return stack_.back().screen->touch(touch); + } else { + return false; + } +} + +bool ScreenManager::key(const KeyInput &key) { + if (!stack_.empty()) { + return stack_.back().screen->key(key); + } else { + return false; + } +} + +bool ScreenManager::axis(const AxisInput &axis) { + if (!stack_.empty()) { + return stack_.back().screen->axis(axis); + } else { + return false; + } +} + +void ScreenManager::resized() { + // Have to notify the whole stack, otherwise there will be problems when going back + // to non-top screens. + for (auto iter = stack_.begin(); iter != stack_.end(); ++iter) { + iter->screen->resized(); + } +} + +void ScreenManager::render() { + if (!stack_.empty()) { + switch (stack_.back().flags) { + case LAYER_SIDEMENU: + case LAYER_TRANSPARENT: + if (stack_.size() == 1) { + ELOG("Can't have sidemenu over nothing"); + break; + } else { + auto iter = stack_.end(); + iter--; + iter--; + Layer backback = *iter; + UIDisableBegin(); + // Also shift to the right somehow... + backback.screen->render(); + UIDisableEnd(); + stack_.back().screen->render(); + break; + } + default: + stack_.back().screen->render(); + break; + } + } else { + ELOG("No current screen!"); + } + + processFinishDialog(); +} + +void ScreenManager::sendMessage(const char *msg, const char *value) { + if (!strcmp(msg, "recreateviews")) + RecreateAllViews(); + if (!stack_.empty()) + stack_.back().screen->sendMessage(msg, value); +} + +void ScreenManager::deviceLost() { + for (size_t i = 0; i < stack_.size(); i++) { + stack_[i].screen->deviceLost(); + } + // Dialogs too? Nah, they should only use the standard UI texture anyway. + // TODO: Change this when it becomes necessary. +} + +Screen *ScreenManager::topScreen() const { + if (!stack_.empty()) + return stack_.back().screen; + else + return 0; +} + +void ScreenManager::shutdown() { + for (auto x = stack_.begin(); x != stack_.end(); x++) + delete x->screen; + stack_.clear(); + delete nextScreen_; + nextScreen_ = 0; +} + +void ScreenManager::push(Screen *screen, int layerFlags) { + if (nextScreen_ && stack_.empty()) { + // we're during init, this is OK + switchToNext(); + } + screen->setScreenManager(this); + if (screen->isTransparent()) { + layerFlags |= LAYER_TRANSPARENT; + } + UI::SetFocusedView(0); + Layer layer = {screen, layerFlags}; + stack_.push_back(layer); +} + +void ScreenManager::pop() { + if (stack_.size()) { + delete stack_.back().screen; + stack_.pop_back(); + } else { + ELOG("Can't pop when stack empty"); + } +} + +void ScreenManager::RecreateAllViews() { + for (auto it = stack_.begin(); it != stack_.end(); ++it) { + it->screen->RecreateViews(); + } +} + +void ScreenManager::finishDialog(Screen *dialog, DialogResult result) { + if (stack_.empty()) { + ELOG("Must be in a dialog to finishDialog"); + return; + } + if (dialog != stack_.back().screen) { + ELOG("Wrong dialog being finished!"); + return; + } + dialog->onFinish(result); + dialogFinished_ = dialog; + dialogResult_ = result; +} + +void ScreenManager::processFinishDialog() { + if (dialogFinished_) { + // Another dialog may have been pushed before the render, so search for it. + Screen *caller = 0; + for (size_t i = 0; i < stack_.size(); ++i) { + if (stack_[i].screen != dialogFinished_) { + continue; + } + + stack_.erase(stack_.begin() + i); + // The previous screen was the caller (not necessarily the topmost.) + if (i > 0) { + caller = stack_[i - 1].screen; + } + } + + if (!caller) { + ELOG("ERROR: no top screen when finishing dialog"); + } else if (caller != topScreen()) { + // The caller may get confused if we call dialogFinished() now. + WLOG("Skipping non-top dialog when finishing dialog."); + } else { + caller->dialogFinished(dialogFinished_, dialogResult_); + } + delete dialogFinished_; + dialogFinished_ = 0; + } +} diff --git a/ext/native/ui/screen.h b/ext/native/ui/screen.h new file mode 100644 index 0000000000..1c8aa7da00 --- /dev/null +++ b/ext/native/ui/screen.h @@ -0,0 +1,146 @@ +// Super basic screen manager. Let's you, well, switch between screens. Can also be used +// to pop one screen in front for a bit while keeping another one running, it's basically +// a native "activity stack". Well actually that part is still a TODO. +// +// Semantics +// +// switchScreen: When you call this, on a newed screen, the ScreenManager takes ownership. +// On the next update, it switches to the new screen and deletes the previous screen. +// +// TODO: A way to do smooth transitions between screens. Will probably involve screenshotting +// the previous screen and then animating it on top of the current screen with transparency +// and/or other similar effects. + +#pragma once + +#include + +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/NativeApp.h" + +namespace UI { + class View; +} + +struct InputState; + +enum DialogResult { + DR_OK, + DR_CANCEL, + DR_YES, + DR_NO, + DR_BACK, +}; + +class ScreenManager; +class UIContext; +class Thin3DContext; + +class Screen { +public: + Screen() : screenManager_(0) { } + virtual ~Screen() { + screenManager_ = 0; + } + + virtual void onFinish(DialogResult reason) {} + virtual void update(InputState &input) {} + virtual void render() {} + virtual void deviceLost() {} + virtual void resized() {} + virtual void dialogFinished(const Screen *dialog, DialogResult result) {} + virtual bool touch(const TouchInput &touch) { return false; } + virtual bool key(const KeyInput &key) { return false; } + virtual bool axis(const AxisInput &touch) { return false; } + virtual void sendMessage(const char *msg, const char *value) {} + + virtual void RecreateViews() {} + + ScreenManager *screenManager() { return screenManager_; } + void setScreenManager(ScreenManager *sm) { screenManager_ = sm; } + + // This one is icky to use because you can't know what's in it until you know + // what screen it is. + virtual void *dialogData() { return 0; } + + virtual std::string tag() const { return std::string(""); } + + virtual bool isTransparent() const { return false; } + virtual bool isTopLevel() const { return false; } + +private: + ScreenManager *screenManager_; + DISALLOW_COPY_AND_ASSIGN(Screen); +}; + +class Transition { +public: + Transition() {} +}; + +enum { + LAYER_SIDEMENU = 1, + LAYER_TRANSPARENT = 2, +}; + +class ScreenManager { +public: + ScreenManager(); + virtual ~ScreenManager(); + + void switchScreen(Screen *screen); + void update(InputState &input); + + void setUIContext(UIContext *context) { uiContext_ = context; } + UIContext *getUIContext() { return uiContext_; } + + void setThin3DContext(Thin3DContext *context) { thin3DContext_ = context; } + Thin3DContext *getThin3DContext() { return thin3DContext_; } + + void render(); + void resized(); + void deviceLost(); + void shutdown(); + + // Push a dialog box in front. Currently 1-level only. + void push(Screen *screen, int layerFlags = 0); + + // Recreate all views + void RecreateAllViews(); + + // Pops the dialog away. + void finishDialog(Screen *dialog, DialogResult result = DR_OK); + + // Instant touch, separate from the update() mechanism. + bool touch(const TouchInput &touch); + bool key(const KeyInput &key); + bool axis(const AxisInput &touch); + + // Generic facility for gross hacks :P + void sendMessage(const char *msg, const char *value); + + Screen *topScreen() const; + +private: + void pop(); + void switchToNext(); + void processFinishDialog(); + + Screen *nextScreen_; + UIContext *uiContext_; + Thin3DContext *thin3DContext_; + + const Screen *dialogFinished_; + DialogResult dialogResult_; + + struct Layer { + Screen *screen; + int flags; // From LAYER_ enum above + UI::View *focusedView; // TODO: save focus here. Going for quick solution now to reset focus. + }; + + // Dialog stack. These are shown "on top" of base screens and the Android back button works as expected. + // Used for options, in-game menus and other things you expect to be able to back out from onto something. + std::vector stack_; +}; diff --git a/ext/native/ui/ui.cpp b/ext/native/ui/ui.cpp new file mode 100644 index 0000000000..e8c4a568c4 --- /dev/null +++ b/ext/native/ui/ui.cpp @@ -0,0 +1,609 @@ +// See header for documentation. + +#include +#include +#include +#include + +#include "base/colorutil.h" +#include "ui/ui.h" +#include "ui/ui_context.h" +#include "gfx/texture.h" +#include "gfx/texture_atlas.h" +#include "gfx_es2/draw_buffer.h" + +// TODO: UI should probably not own these. +DrawBuffer ui_draw2d; +DrawBuffer ui_draw2d_front; + +// This one, though, is OK. +UIState uistate; +UIState savedUistate; + +// Theme. +static const Atlas *themeAtlas; +static UITheme theme; + +void UIInit(const Atlas *atlas, const UITheme &ui_theme) { + ui_draw2d.SetAtlas(atlas); + ui_draw2d_front.SetAtlas(atlas); + themeAtlas = atlas; + theme = ui_theme; + memset(&uistate, 0, sizeof(uistate)); +} + +void UIDisableBegin() +{ + savedUistate = uistate; + memset(&uistate, 0, sizeof(uistate)); +} + +void UIDisableEnd() +{ + uistate = savedUistate; +} + +void UIUpdateMouse(int i, float x, float y, bool down) { + if (down && !uistate.mousedown[i]) { + uistate.mousepressed[i] = 1; + uistate.mouseStartX[i] = x; + uistate.mouseStartY[i] = y; + } else { + uistate.mousepressed[i] = 0; + } + uistate.mousex[i] = x; + uistate.mousey[i] = y; + uistate.mousedown[i] = down; + + if (uistate.mousedown[i]) + uistate.mouseframesdown[i]++; + else + uistate.mouseframesdown[i] = 0; +} + +void UIReset() { + memset(&uistate, 0, sizeof(uistate)); +} + +bool UIRegionHit(int i, int x, int y, int w, int h, int margin) { + // Input handling + if (uistate.mousex[i] < x - margin || + uistate.mousey[i] < y - margin || + uistate.mousex[i] >= x + w + margin || + uistate.mousey[i] >= y + h + margin) { + return false; + } else { + return true; + } +} + +void UIBegin(Thin3DShaderSet *shaderSet) { + for (int i = 0; i < MAX_POINTERS; i++) + uistate.hotitem[i] = 0; + ui_draw2d.Begin(shaderSet); + ui_draw2d_front.Begin(shaderSet); +} + +void UIFlush() { + ui_draw2d.Flush(); + ui_draw2d_front.Flush(); +} + +void UIEnd() { + for (int i = 0; i < MAX_POINTERS; i++) { + if (uistate.mousedown[i] == 0) { + uistate.activeitem[i] = 0; + } else { + if (uistate.activeitem[i] == 0) { + uistate.activeitem[i] = -1; + } + } + } + ui_draw2d.End(); + ui_draw2d_front.End(); + + if (uistate.ui_tick > 0) + uistate.ui_tick--; + ui_draw2d.Flush(); + ui_draw2d_front.Flush(); +} + +void UIText(int x, int y, const char *text, uint32_t color, float scale, int align) { + UIText(theme.uiFont, x, y, text, color, scale, align); +} + +void UIText(int font, int x, int y, const char *text, uint32_t color, float scale, int align) { + ui_draw2d.SetFontScale(scale, scale); + ui_draw2d.DrawTextShadow(font, text, x, y, color, align); + ui_draw2d.SetFontScale(1.0f, 1.0f); +} + +void UIText(int font, const LayoutManager &layout, const char *text, uint32_t color, float scale, int align) +{ + ui_draw2d.SetFontScale(scale, scale); + float w, h; + ui_draw2d.MeasureText(font, text, &w, &h); + float x, y; + layout.GetPos(&w, &h, &x, &y); + UIText(font, x, y, text, color, scale, 0); + ui_draw2d.SetFontScale(1.0f, 1.0f); +} + +int UIButton(int id, const LayoutManager &layout, float w, float h, const char *text, int button_align) { + if (h == 0.0f) + h = themeAtlas->images[theme.buttonImage].h; + + float x, y; + layout.GetPos(&w, &h, &x, &y); + + if (button_align & ALIGN_HCENTER) x -= w / 2; + if (button_align & ALIGN_VCENTER) y -= h / 2; + if (button_align & ALIGN_RIGHT) x -= w; + if (button_align & ALIGN_BOTTOM) y -= h; + + int txOffset = 0; + + int clicked = 0; + for (int i = 0; i < MAX_POINTERS; i++) { + // Check whether the button should be hot, use a generous margin for touch ease + if (UIRegionHit(i, x, y, w, h, 8)) { + uistate.hotitem[i] = id; + if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) { + uistate.activeitem[i] = id; + } + } + + if (uistate.hotitem[i] == id) { + if (uistate.activeitem[i] == id) { + // Button is both 'hot' and 'active' + txOffset = 2; + } else { + // Button is merely 'hot' + } + } else { + // button is not hot, but it may be active + } + + // If button is hot and active, but mouse button is not + // down, the user must have clicked the button. + if (uistate.mousedown[i] == 0 && + uistate.hotitem[i] == id && + uistate.activeitem[i] == id) { + clicked = 1; + } + } + + // Render button + + if (h == themeAtlas->images[theme.buttonImage].h) + ui_draw2d.DrawImage2GridH((txOffset && theme.buttonSelected) ? theme.buttonSelected : theme.buttonImage, x, y, x + w); + else + ui_draw2d.DrawImage4Grid((txOffset && theme.buttonSelected) ? theme.buttonSelected : theme.buttonImage, x, y, x + w, y + h); + ui_draw2d.DrawTextShadow(theme.uiFont, text, x + w/2, y + h/2 + txOffset, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_VCENTER); + + uistate.lastwidget = id; + return clicked; +} + +int UIImageButton(int id, const LayoutManager &layout, float w, int image, int button_align) { + float h = 64; + float x, y; + layout.GetPos(&w, &h, &x, &y); + + if (button_align & ALIGN_HCENTER) x -= w / 2; + if (button_align & ALIGN_VCENTER) y -= h / 2; + if (button_align & ALIGN_RIGHT) x -= w; + if (button_align & ALIGN_BOTTOMRIGHT) y -= h; + + int txOffset = 0; + int clicked = 0; + for (int i = 0; i < MAX_POINTERS; i++) { + // Check whether the button should be hot, use a generous margin for touch ease + if (UIRegionHit(i, x, y, w, h, 8)) { + uistate.hotitem[i] = id; + if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) + uistate.activeitem[i] = id; + } + + if (uistate.hotitem[i] == id) { + if (uistate.activeitem[i] == id) { + // Button is both 'hot' and 'active' + txOffset = 2; + } else { + // Button is merely 'hot' + } + } else { + // button is not hot, but it may be active + } + + // If button is hot and active, but mouse button is not + // down, the user must have clicked the button. + if (uistate.mousedown[i] == 0 && + uistate.hotitem[i] == id && + uistate.activeitem[i] == id) { + clicked = 1; + } + } + + // Render button + + ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w); + ui_draw2d.DrawImage(image, x + w/2, y + h/2 + txOffset, 1.0f, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_VCENTER); + + uistate.lastwidget = id; + return clicked; +} + +int UITextureButton(UIContext *ctx, int id, const LayoutManager &layout, float w, float h, Texture *texture, int button_align, uint32_t color, int drop_shadow) // uses current UI atlas for fetching images. +{ + float x, y; + layout.GetPos(&w, &h, &x, &y); + + if (button_align & ALIGN_HCENTER) x -= w / 2; + if (button_align & ALIGN_VCENTER) y -= h / 2; + if (button_align & ALIGN_RIGHT) x -= w; + if (button_align & ALIGN_BOTTOMRIGHT) y -= h; + + int txOffset = 0; + int clicked = 0; + for (int i = 0; i < MAX_POINTERS; i++) { + // Check whether the button should be hot, use a generous margin for touch ease + if (UIRegionHit(i, x, y, w, h, 8)) { + uistate.hotitem[i] = id; + if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) + uistate.activeitem[i] = id; + } + + if (uistate.hotitem[i] == id) { + if (uistate.activeitem[i] == id) { + // Button is both 'hot' and 'active' + txOffset = 2; + } else { + // Button is merely 'hot' + } + } else { + // button is not hot, but it may be active + } + + // If button is hot and active, but mouse button is not + // down, the user must have clicked the button. + if (uistate.mousedown[i] == 0 && + uistate.hotitem[i] == id && + uistate.activeitem[i] == id) { + clicked = 1; + } + } + if (texture) { + float tw = texture->Width(); + float th = texture->Height(); + + // Adjust position so we don't stretch the image vertically or horizontally. + // TODO: Add a param to specify fit? The below assumes it's never too wide. + float nw = h * tw / th; + x += (w - nw) / 2.0f; + w = nw; + } + + // Render button + int dropsize = 10; + if (drop_shadow && texture) + { + if (txOffset) { + dropsize = 3; + y += txOffset * 2; + } + ui_draw2d.DrawImage4Grid(drop_shadow, x - dropsize, y, x+w + dropsize, y+h+dropsize*1.5, + blackAlpha(0.5f), 1.0f); + ui_draw2d.Flush(true); + } + + if (texture) { + texture->Bind(0); + } else { + ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w, color); + ui_draw2d.Flush(); + + Texture::Unbind(); + } + ui_draw2d.DrawTexRect(x, y, x+w, y+h, 0, 0, 1, 1, color); + + ui_draw2d.Flush(); + ctx->RebindTexture(); + + uistate.lastwidget = id; + return clicked; +} + +int UICheckBox(int id, int x, int y, const char *text, int align, bool *value) { +#ifdef _WIN32 + const int h = 32; +#else + const int h = 48; +#endif + float tw, th; + ui_draw2d.MeasureText(theme.uiFont, text, &tw, &th); + int w = themeAtlas->images[theme.checkOn].w + UI_SPACE + tw; + if (align & ALIGN_HCENTER) x -= w / 2; + if (align & ALIGN_VCENTER) y -= h / 2; + if (align & ALIGN_RIGHT) x -= w; + if (align & ALIGN_BOTTOMRIGHT) y -= h; + + int txOffset = 0; + int clicked = 0; + for (int i = 0; i < MAX_POINTERS; i++) { + + // Check whether the button should be hot + if (UIRegionHit(i, x, y, w, h, 8)) { + uistate.hotitem[i] = id; + if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) + uistate.activeitem[i] = id; + } + + // Render button + + if (uistate.hotitem[i] == id) { + if (uistate.activeitem[i] == id) { + // Button is both 'hot' and 'active' + txOffset = 2; + } else { + // Button is merely 'hot' + } + } else { + // button is not hot, but it may be active + } + // If button is hot and active, but mouse button is not + // down, the user must have clicked the button. + if (uistate.mousedown[i] == 0 && + uistate.hotitem[i] == id && + uistate.activeitem[i] == id) { + *value = !(*value); + clicked = 1; + } + } + + ui_draw2d.DrawImage((*value) ? theme.checkOn : theme.checkOff, x, y+h/2, 1.0f, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER); + ui_draw2d.DrawTextShadow(theme.uiFont, text, x + themeAtlas->images[theme.checkOn].w + UI_SPACE, y + txOffset + h/2, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER); + + + uistate.lastwidget = id; + return clicked; +} + +void StringVectorListAdapter::drawItem(int item, int x, int y, int w, int h, bool selected) const +{ + ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w); + ui_draw2d.DrawTextShadow(theme.uiFont, (*items_)[item].c_str(), x + UI_SPACE , y, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER); +} + +UIList::UIList() + : scrollY(0.0f), startDragY(0.0f), dragFinger(-1), selected(-1) { + movedDistanceX = 0.0f; + movedDistanceY = 0.0f; + scrolling = false; + inertiaY = 0.0f; +} + +void UIList::pointerDown(int pointer, float x, float y) { + // Instantly halt on pointerDown if inertia-scrolling + scrolling = false; + inertiaY = 0.0f; + + startScrollY = scrollY; + startDragY = y; + movedDistanceX = 0.0f; + movedDistanceY = 0.0f; +} + +const int holdFramesClick = 3; +const int holdFramesScroll = 10; + +void UIList::pointerMove(int pointer, float x, float y, bool inside) { + float deltaX = x - lastX; + float deltaY = y - lastY; + movedDistanceY += fabsf(deltaY); + movedDistanceX += fabsf(deltaX); + + if (inertiaY <= 0.0f && deltaY > 0.0f) { + inertiaY = -deltaY; + } else if (inertiaY >= 0.0f && deltaY < 0.0f) { + inertiaY = -deltaY; + } else { + inertiaY = 0.8 * inertiaY + 0.2 * -deltaY; + } + + const int deadzone = 30 * holdFramesScroll; + if (inside && movedDistanceY * uistate.mouseframesdown[0] > deadzone && !scrolling) { + scrolling = true; + } +} + +void UIList::pointerUp(int pointer, float x, float y, bool inside) { + // printf("PointerUp %f %f\n", x, y); +} + +int UIList::Do(int id, int x, int y, int w, int h, UIListAdapter *adapter) { + int clicked = 0; + + // Pointer and focus handling + + // UIList only cares about the first pointer for simplicity. + // Probably not much need to scroll one of these while dragging something + // else. + + // TODO: Abstract this stuff out into EmulatePointerEvents + for (int i = 0; i < 1; i++) { + // Check for hover + bool isInside = false; + if (UIRegionHit(i, x, y, w, h, 0)) { + isInside = true; + uistate.hotitem[i] = id; + if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) { + // Mousedown + uistate.activeitem[i] = id; + pointerDown(i, uistate.mousex[i], uistate.mousey[i]); + } + } + + if (uistate.activeitem[i] == id) { + // NOTE: won't work with multiple pointers + if (uistate.mousex[i] != lastX || uistate.mousey[i] != lastY) { + pointerMove(i, uistate.mousex[i], uistate.mousey[i], isInside); + } + } + + // If button is hot and active, but mouse button is not + // down, the user must have clicked a list item (unless after the last item). + if (uistate.mousedown[i] == 0 && + uistate.activeitem[i] == id && + selected != -1) { + if (uistate.hotitem[i] == id) { + clicked = 1; + } + pointerUp(i, uistate.mousex[i], uistate.mousey[i], isInside); + } + } + + int itemHeight = adapter->itemHeight(0); + int numItems = (int)adapter->getCount(); + + // Cap total inertia + if (inertiaY > 20) inertiaY = 20; + if (inertiaY < -20) inertiaY = -20; + + if (!uistate.mousedown[0]) { + // Let it slide if the pointer is not down + scrollY += inertiaY; + } else if (scrolling /* && mouseY > y && mouseY < y + h*/ ) { + // Pointer is down so stick to it + scrollY = startScrollY - (uistate.mousey[0] - startDragY); + } + + // Inertia gradually trails off + inertiaY *= 0.92f; + if (scrolling && fabsf(inertiaY) < 0.001f) + scrolling = false; + + // Cap top and bottom softly. + float maxScrollY = numItems * itemHeight - h; + if (maxScrollY < 0.0f) maxScrollY = 0.0f; + if (scrollY > maxScrollY) { + scrollY -= 0.4f * (scrollY - maxScrollY); + } else if (scrollY < 0.0f) { + scrollY += 0.4f * -scrollY; + } + + lastX = uistate.mousex[0]; + lastY = uistate.mousey[0]; + uistate.lastwidget = id; + + // Drawing and item hittesting + + // render items + for (int i = 0; i < numItems; i++) { + int item_y = y + i * itemHeight - scrollY; + + if (item_y >= y - itemHeight && item_y <= y + h) { + for (int k = 0; k < 1; k++) { // MAX_POINTERS if we add back multitouch + if (uistate.mousedown[k] && + uistate.mouseframesdown[k] >= holdFramesClick && + adapter->itemEnabled(i) && + !scrolling && + selected == -1 && + UIRegionHit(k, x, item_y, w, itemHeight, 0)) { + selected = i; + } else if (scrolling) { + selected = -1; + } + } + adapter->drawItem(i, x, item_y, w, itemHeight, i == selected); + } + } + + // Prevent scroll-clicks from registering + if (selected == -1) clicked = 0; + // Otherwise, no clicky. + return clicked; +} + +/* +struct SlideItem { +const char *text; +int image; +uint32_t bgColor; +}; + +struct SlideState +{ +float scroll; + +}; + +void UISlideChoice(int id, int y, const SlideItem *items, int numItems, SlideState *state) + +}*/ + +// TODO +int UIHSlider(int id, int x, int y, int w, int max, int *value) { + // Calculate mouse cursor's relative y offset + int xpos = ((256 - 16) * *value) / max; + + for (int i = 0; i < MAX_POINTERS; i++) { + // Check for hotness + if (UIRegionHit(i, x+8, y+8, 16, 255, 0)) { + uistate.hotitem[i] = id; + if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) + uistate.activeitem[i] = id; + } + + // Update widget value + if (uistate.activeitem[i] == id) { + int mousepos = uistate.mousey[i] - (y + 8); + if (mousepos < 0) mousepos = 0; + if (mousepos > 255) mousepos = 255; + int v = (mousepos * max) / 255; + if (v != *value) { + *value = v; + return 1; + } + } + } + // Render the scrollbar + ui_draw2d.Rect(x, y, 32, 256+16, 0x777777); + + ui_draw2d.Rect(x+8+xpos, y+8, 16, 16, 0xffffff); + + return 0; +} + +/* +// TODO +int UIVSlider(int id, int x, int y, int h, int max, int *value) { + // Calculate mouse cursor's relative y offset + int ypos = ((256 - 16) * *value) / max; + + // Check for hotness + if (UIRegionHit(x+8, y+8, 16, 255, 0)) { + uistate.hotitem = id; + if (uistate.activeitem == 0 && uistate.mousedown) + uistate.activeitem = id; + } + // Update widget value + if (uistate.activeitem == id) { + int mousepos = uistate.mousey - (y + 8); + if (mousepos < 0) mousepos = 0; + if (mousepos > 255) mousepos = 255; + int v = (mousepos * max) / 255; + if (v != *value) { + *value = v; + return 1; + } + } + // Render the scrollbar + ui_draw2d.Rect(x, y, 32, 256+16, 0x777777); + + ui_draw2d.Rect(x+8, y+8 + ypos, 16, 16, 0xffffff); + + + return 0; +} +*/ diff --git a/ext/native/ui/ui.h b/ext/native/ui/ui.h new file mode 100644 index 0000000000..b9f1d72e2f --- /dev/null +++ b/ext/native/ui/ui.h @@ -0,0 +1,300 @@ +// Simple immediate mode UI implementation. +// +// Heavily inspired by Sol's tutorial at http://sol.gfxile.net/imgui/. +// +// A common pattern is Adapter classes for changing how things are drawn +// in lists, for example. +// +// Immediate UI works great for overlay UI for games, for example, but is actually +// not really a good idea for full app UIs. Also, animations are difficult because +// there's not really any good place to store state. +// +// hrydgard@gmail.com + +#pragma once + +// Simple ID generators. Absolutely no guarantee of collision avoidance if you implement +// multiple parts of a single screen of UI over multiple files unless you use IMGUI_SRC_ID. +#ifdef IMGUI_SRC_ID +#define GEN_ID (int)((IMGUI_SRC_ID) + (__LINE__)) +#define GEN_ID_LOOP(i) (int)((IMGUI_SRC_ID) + (__LINE__) + (i) * 13612) +#else +#define GEN_ID (__LINE__) +#define GEN_ID_LOOP(i) ((__LINE__) + ((int)i) * 13612) +#endif + +#include +#include + +#include "gfx_es2/draw_buffer.h" +#include "input/input_state.h" + +class Texture; +class UIContext; + +class LayoutManager { +public: + virtual void GetPos(float *w, float *h, float *x, float *y) const = 0; +}; + +class Pos : public LayoutManager { +public: + Pos(float x, float y) : x_(x), y_(y) {} + virtual void GetPos(float *w, float *h, float *x, float *y) const { + *x = x_; + *y = y_; + } +private: + float x_; + float y_; +}; + +class HLinear : public LayoutManager { +public: + HLinear(float x, float y, float spacing = 2.0f) : x_(x), y_(y), spacing_(spacing) {} + virtual void GetPos(float *w, float *h, float *x, float *y) const { + *x = x_; + *y = y_; + x_ += *w + spacing_; + } + void Space(float x) { + x_ += x; + } + +private: + mutable float x_; + float y_; + float spacing_; +}; + +class VLinear : public LayoutManager { +public: + VLinear(float x, float y, float spacing = 2.0f) : x_(x), y_(y), spacing_(spacing) {} + virtual void GetPos(float *w, float *h, float *x, float *y) const { + *x = x_; + *y = y_; + y_ += *h + spacing_; + } + +private: + float x_; + mutable float y_; + float spacing_; +}; + +class HGrid : public LayoutManager { +public: + HGrid(float x, float y, float xMax, float xSpacing = 2.0f, float ySpacing = 2.0f) + : x_(x), y_(y), xInit_(x), xMax_(xMax), xSpacing_(xSpacing), ySpacing_(ySpacing) {} + virtual void GetPos(float *w, float *h, float *x, float *y) const { + *x = x_; + *y = y_; + x_ += *w + xSpacing_; + if (x_ >= xMax_) { + x_ = xInit_; + y_ += *h + ySpacing_; + } + } + +private: + mutable float x_; + mutable float y_; + float xInit_; + float xMax_; + float xSpacing_; + float ySpacing_; +}; + +class VGrid : public LayoutManager { +public: + VGrid(float x, float y, float yMax, float xSpacing = 2.0f, float ySpacing = 2.0f) + : x_(x), y_(y), yInit_(y), yMax_(yMax), xSpacing_(xSpacing), ySpacing_(ySpacing) {} + virtual void GetPos(float *w, float *h, float *x, float *y) const { + *x = x_; + *y = y_; + y_ += *h + ySpacing_; + if (y_ + *h >= yMax_) { + x_ += *w + xSpacing_; + y_ = yInit_; + } + } + +private: + mutable float x_; + mutable float y_; + float yInit_; + float yMax_; + float xSpacing_; + float ySpacing_; +}; + +// "Mouse" out of habit, applies just as well to touch events. +// TODO: Change to "pointer" +// This struct is zeroed on init, so should be valid at that state. +// Never inherit from this. +struct UIState { + int mousex[MAX_POINTERS]; + int mousey[MAX_POINTERS]; + bool mousedown[MAX_POINTERS]; + bool mousepressed[MAX_POINTERS]; + short mouseframesdown[MAX_POINTERS]; + + int mouseStartX[MAX_POINTERS]; + int mouseStartY[MAX_POINTERS]; + + int hotitem[MAX_POINTERS]; + int activeitem[MAX_POINTERS]; + + // keyboard focus, not currently used + int kbdwidget; + int lastwidget; + + int ui_tick; + + // deprecated: tempfloat + float tempfloat; +}; + +// This needs to be extern so that additional UI controls can be developed outside this file. +extern UIState uistate; + +struct Atlas; + +// This is the drawbuffer used for UI. Remember to flush it at the end of the frame. +// TODO: One should probably pass it in through UIInit. +extern DrawBuffer ui_draw2d; +extern DrawBuffer ui_draw2d_front; // for things that need to be on top of the rest + +struct UITheme { + int uiFont; + int uiFontSmall; + int uiFontSmaller; + int buttonImage; + int buttonSelected; + int checkOn; + int checkOff; +}; + +// The atlas needs to stick around, the theme is copied. +void UIInit(const Atlas *atlas, const UITheme &theme); + +// Between these, UI components won't see pointer events. +void UIDisableBegin(); +void UIDisableEnd(); + +// Just lets you retrieve the theme that was passed into UIInit, for your own controls for example. +UITheme &UIGetTheme(); + +// TODO: These don't really belong here. +const int UI_SPACE = 32; +const int SMALL_BUTTON_WIDTH = 128; +const int LARGE_BUTTON_WIDTH = 192; +const int BUTTON_HEIGHT = 72; + +struct SlideItem { + const char *text; + int image; + uint32_t bgColor; +}; + +struct UISlideState { + float scroll; +}; + +// Implement this interface to style your lists +class UIListAdapter { +public: + virtual size_t getCount() const = 0; + virtual void drawItem(int item, int x, int y, int w, int h, bool active) const = 0; + virtual float itemHeight(int itemIndex) const { return 64; } + virtual bool itemEnabled(int itemIndex) const { return true; } +}; + +class StringVectorListAdapter : public UIListAdapter { +public: + StringVectorListAdapter(const std::vector *items) : items_(items) {} + virtual size_t getCount() const { return items_->size(); } + virtual void drawItem(int item, int x, int y, int w, int h, bool active) const; + +private: + const std::vector *items_; +}; + + +// Utility functions, useful when implementing your own controls +bool UIRegionHit(int pointerId, int x, int y, int w, int h, int margin); + +// Call at start of frame +void UIBegin(Thin3DShaderSet *shaderSet); + +// Call at end of frame. + +void UIEnd(); +void UIFlush(); + +void UIUpdateMouse(int i, float x, float y, bool down); + +// Call when you switch screens +void UIReset(); + +// Returns 1 if clicked +int UIButton(int id, const LayoutManager &layout, float w, float h, const char *text, int button_align); +int UIImageButton(int id, const LayoutManager &layout, float w, int image_id, int button_align); // uses current UI atlas for fetching images. +int UITextureButton(UIContext *ctx, int id, const LayoutManager &layout, float w, float h, Texture *texture, int button_align, uint32_t color, int drop_shadow=0); // uses current UI atlas for fetching images. +// Returns 1 if clicked, puts the value in *value (where it also gets the current state). +int UICheckBox(int id, int x, int y, const char *text, int align, bool *value); + +// Vertical slider. Not yet working. +// int UIVSlider(int id, int x, int y, int h, int max, int *value); + +// Horizontal slider. Not yet working. +int UIHSlider(int id, int x, int y, int w, int max, int *value); + +// Draws static text, that does not participate in any focusing scheme etc, it just is. +void UIText(int font, int x, int y, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT); +void UIText(int x, int y, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT); +void UIText(int font, const LayoutManager &layout, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT); + +// Slide choice, like the Angry Birds level selector. Not yet working. +void UISlideChoice(int id, int y, const SlideItem *items, int numItems, UISlideState *state); + + +class UIList { +public: + UIList(); + + bool scrolling; + int activePointer; + float startScrollY; + float scrollY; + float lastX; + float lastY; + float startDragY; + float movedDistanceX; + float movedDistanceY; + float inertiaY; + + int dragFinger; + int selected; + // List view. + // return -1 = no selection + int Do(int id, int x, int y, int w, int h, UIListAdapter *adapter); + + // Call this when the content has changed, to reset scroll position etc. + void contentChanged() { + scrollY = 0.0f; + inertiaY = 0.0f; + } + + void scrollRelative(float delta) { + scrollY += delta; + } +private: + // TODO: Migrate to using these directly. + void pointerDown(int pointer, float x, float y); + void pointerUp(int pointer, float x, float y, bool inside); + void pointerMove(int pointer, float x, float y, bool inside); + + DISALLOW_COPY_AND_ASSIGN(UIList); +}; + diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp new file mode 100644 index 0000000000..56039e1809 --- /dev/null +++ b/ext/native/ui/ui_context.cpp @@ -0,0 +1,189 @@ +#include "base/display.h" +#include "ui/ui.h" +#include "ui/view.h" +#include "ui/ui_context.h" +#include "gfx_es2/draw_buffer.h" +#include "gfx_es2/draw_text.h" + +UIContext::UIContext() + : uishader_(0), uitexture_(0), uidrawbuffer_(0), uidrawbufferTop_(0) { + fontScaleX_ = 1.0f; + fontScaleY_ = 1.0f; + fontStyle_ = new UI::FontStyle(); + bounds_ = Bounds(0, 0, dp_xres, dp_yres); +} + +UIContext::~UIContext() { + delete fontStyle_; + delete textDrawer_; +} + +void UIContext::Init(Thin3DContext *thin3d, Thin3DShaderSet *uishader, Thin3DShaderSet *uishadernotex, Thin3DTexture *uitexture, DrawBuffer *uidrawbuffer, DrawBuffer *uidrawbufferTop) { + thin3d_ = thin3d; + blend_ = thin3d_->GetBlendStatePreset(T3DBlendStatePreset::BS_STANDARD_ALPHA); + depth_ = thin3d_->CreateDepthStencilState(false, false, T3DComparison::LESS); + + uishader_ = uishader; + uishadernotex_ = uishadernotex; + uitexture_ = uitexture; + uidrawbuffer_ = uidrawbuffer; + uidrawbufferTop_ = uidrawbufferTop; +#if defined(_WIN32) || defined(USING_QT_UI) + textDrawer_ = new TextDrawer(thin3d); +#else + textDrawer_ = 0; +#endif +} + +void UIContext::Begin() { + thin3d_->SetBlendState(blend_); + thin3d_->SetDepthStencilState(depth_); + thin3d_->SetRenderState(T3DRenderState::CULL_MODE, T3DCullMode::NO_CULL); + thin3d_->SetTexture(0, uitexture_); + thin3d_->SetScissorEnabled(false); + UIBegin(uishader_); +} + +void UIContext::BeginNoTex() { + thin3d_->SetBlendState(blend_); + thin3d_->SetRenderState(T3DRenderState::CULL_MODE, T3DCullMode::NO_CULL); + + UIBegin(uishadernotex_); +} + +void UIContext::RebindTexture() const { + thin3d_->SetTexture(0, uitexture_); +} + +void UIContext::Flush() { + if (uidrawbuffer_) { + uidrawbuffer_->End(); + uidrawbuffer_->Flush(); + } + if (uidrawbufferTop_) { + uidrawbufferTop_->End(); + uidrawbufferTop_->Flush(); + } +} + +void UIContext::End() { + UIEnd(); + Flush(); +} + +// TODO: Support transformed bounds using stencil +void UIContext::PushScissor(const Bounds &bounds) { + Flush(); + Bounds clipped = bounds; + if (scissorStack_.size()) + clipped.Clip(scissorStack_.back()); + scissorStack_.push_back(clipped); + ActivateTopScissor(); +} + +void UIContext::PopScissor() { + Flush(); + scissorStack_.pop_back(); + ActivateTopScissor(); +} + +Bounds UIContext::GetScissorBounds() { + if (!scissorStack_.empty()) + return scissorStack_.back(); + else + return bounds_; +} + +void UIContext::ActivateTopScissor() { + if (scissorStack_.size()) { + const Bounds &bounds = scissorStack_.back(); + float scale = 1.0f / g_dpi_scale; + int x = scale * bounds.x; + int y = scale * bounds.y; + int w = scale * bounds.w; + int h = scale * bounds.h; + thin3d_->SetScissorRect(x, y, w, h); + thin3d_->SetScissorEnabled(true); + } else { + thin3d_->SetScissorEnabled(false); + } +} + +void UIContext::SetFontScale(float scaleX, float scaleY) { + fontScaleX_ = scaleX; + fontScaleY_ = scaleY; +} + +void UIContext::SetFontStyle(const UI::FontStyle &fontStyle) { + *fontStyle_ = fontStyle; + if (textDrawer_) { + textDrawer_->SetFontScale(fontScaleX_, fontScaleY_); + Text()->SetFont(fontStyle.fontName.c_str(), fontStyle.sizePts, fontStyle.flags); + } +} + +void UIContext::MeasureText(const UI::FontStyle &style, const char *str, float *x, float *y, int align) const { + MeasureTextCount(style, str, (int)strlen(str), x, y, align); +} + +void UIContext::MeasureTextCount(const UI::FontStyle &style, const char *str, int count, float *x, float *y, int align) const { + if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) { + float sizeFactor = (float)style.sizePts / 24.0f; + Draw()->SetFontScale(fontScaleX_ * sizeFactor, fontScaleY_ * sizeFactor); + Draw()->MeasureTextCount(style.atlasFont, str, count, x, y); + } else { + textDrawer_->SetFontScale(fontScaleX_, fontScaleY_); + std::string subset(str, count); + textDrawer_->MeasureString(subset.c_str(), x, y); + } +} + +void UIContext::DrawText(const char *str, float x, float y, uint32_t color, int align) { + if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) { + float sizeFactor = (float)fontStyle_->sizePts / 24.0f; + Draw()->SetFontScale(fontScaleX_ * sizeFactor, fontScaleY_ * sizeFactor); + Draw()->DrawText(fontStyle_->atlasFont, str, x, y, color, align); + } else { + textDrawer_->SetFontScale(fontScaleX_, fontScaleY_); + textDrawer_->DrawString(*Draw(), str, x, y, color, align); + RebindTexture(); + } +} + +void UIContext::DrawTextShadow(const char *str, float x, float y, uint32_t color, int align) { + uint32_t alpha = (color >> 1) & 0xFF000000; + DrawText(str, x + 2, y + 2, alpha, align); + DrawText(str, x, y, color, align); +} + +void UIContext::DrawTextRect(const char *str, const Bounds &bounds, uint32_t color, int align) { + if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) { + float sizeFactor = (float)fontStyle_->sizePts / 24.0f; + Draw()->SetFontScale(fontScaleX_ * sizeFactor, fontScaleY_ * sizeFactor); + Draw()->DrawTextRect(fontStyle_->atlasFont, str, bounds.x, bounds.y, bounds.w, bounds.h, color, align); + } else { + textDrawer_->SetFontScale(fontScaleX_, fontScaleY_); + textDrawer_->DrawStringRect(*Draw(), str, bounds, color, align); + RebindTexture(); + } +} + +void UIContext::FillRect(const UI::Drawable &drawable, const Bounds &bounds) { + // Only draw if alpha is non-zero. + if ((drawable.color & 0xFF000000) == 0) + return; + + switch (drawable.type) { + case UI::DRAW_SOLID_COLOR: + uidrawbuffer_->DrawImageStretch(theme->whiteImage, bounds.x, bounds.y, bounds.x2(), bounds.y2(), drawable.color); + break; + case UI::DRAW_4GRID: + uidrawbuffer_->DrawImage4Grid(drawable.image, bounds.x, bounds.y, bounds.x2(), bounds.y2(), drawable.color); + break; + case UI::DRAW_STRETCH_IMAGE: + uidrawbuffer_->DrawImageStretch(drawable.image, bounds.x, bounds.y, bounds.x2(), bounds.y2(), drawable.color); + break; + case UI::DRAW_NOTHING: + break; + } +} diff --git a/ext/native/ui/ui_context.h b/ext/native/ui/ui_context.h new file mode 100644 index 0000000000..628a96cba1 --- /dev/null +++ b/ext/native/ui/ui_context.h @@ -0,0 +1,93 @@ +#pragma once + +#include + +#include "base/basictypes.h" +#include "math/geom2d.h" +#include "gfx/texture_atlas.h" + +// Everything you need to draw a UI collected into a single unit that can be passed around. +// Everything forward declared so this header is safe everywhere. + +class Thin3DContext; +class Thin3DShaderSet; +class Thin3DDepthStencilState; +class Thin3DTexture; +class Thin3DBlendState; +class Texture; +class DrawBuffer; +class TextDrawer; + +namespace UI { + struct Drawable; + struct Theme; + struct FontStyle; +} + +class DrawBuffer; + +class UIContext { +public: + UIContext(); + ~UIContext(); + + void Init(Thin3DContext *thin3d, Thin3DShaderSet *uiShaderTex, Thin3DShaderSet *uiShaderNoTex, Thin3DTexture *uitexture, DrawBuffer *uidrawbuffer, DrawBuffer *uidrawbufferTop); + + void Begin(); + void BeginNoTex(); + void Flush(); + void End(); + + void RebindTexture() const; + + // TODO: Support transformed bounds using stencil + void PushScissor(const Bounds &bounds); + void PopScissor(); + Bounds GetScissorBounds(); + + void ActivateTopScissor(); + + DrawBuffer *Draw() const { return uidrawbuffer_; } + DrawBuffer *DrawTop() const { return uidrawbufferTop_; } + const UI::Theme *theme; + + // Utility methods + + TextDrawer *Text() const { return textDrawer_; } + + void SetFontStyle(const UI::FontStyle &style); + const UI::FontStyle &GetFontStyle() { return *fontStyle_; } + void SetFontScale(float scaleX, float scaleY); + void MeasureTextCount(const UI::FontStyle &style, const char *str, int count, float *x, float *y, int align = 0) const; + void MeasureText(const UI::FontStyle &style, const char *str, float *x, float *y, int align = 0) const; + void DrawText(const char *str, float x, float y, uint32_t color, int align = 0); + void DrawTextShadow(const char *str, float x, float y, uint32_t color, int align = 0); + void DrawTextRect(const char *str, const Bounds &bounds, uint32_t color, int align = 0); + void FillRect(const UI::Drawable &drawable, const Bounds &bounds); + + // in dps, like dp_xres and dp_yres + void SetBounds(const Bounds &b) { bounds_ = b; } + const Bounds &GetBounds() const { return bounds_; } + Thin3DContext *GetThin3DContext() { return thin3d_; } + +private: + Thin3DContext *thin3d_; + Bounds bounds_; + + float fontScaleX_; + float fontScaleY_; + UI::FontStyle *fontStyle_; + TextDrawer *textDrawer_; + + Thin3DContext *thin3D_; + Thin3DDepthStencilState *depth_; + Thin3DBlendState *blend_; + Thin3DShaderSet *uishader_; + Thin3DShaderSet *uishadernotex_; + Thin3DTexture *uitexture_; + + DrawBuffer *uidrawbuffer_; + DrawBuffer *uidrawbufferTop_; + + std::vector scissorStack_; +}; diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp new file mode 100644 index 0000000000..0a85893905 --- /dev/null +++ b/ext/native/ui/ui_screen.cpp @@ -0,0 +1,535 @@ +#include "input/input_state.h" +#include "input/keycodes.h" +#include "ui/ui_screen.h" +#include "ui/ui_context.h" +#include "ui/screen.h" +#include "i18n/i18n.h" +#include "gfx_es2/draw_buffer.h" + +UIScreen::UIScreen() + : Screen(), root_(0), recreateViews_(true), hatDown_(0) { +} + +UIScreen::~UIScreen() { + delete root_; +} + +void UIScreen::DoRecreateViews() { + if (recreateViews_) { + delete root_; + root_ = 0; + CreateViews(); + if (root_ && root_->GetDefaultFocusView()) { + root_->GetDefaultFocusView()->SetFocus(); + } + recreateViews_ = false; + } +} + +void UIScreen::update(InputState &input) { + DoRecreateViews(); + + if (root_) { + UpdateViewHierarchy(input, root_); + } +} + +void UIScreen::render() { + DoRecreateViews(); + + if (root_) { + UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_); + + screenManager()->getUIContext()->Begin(); + DrawBackground(*screenManager()->getUIContext()); + root_->Draw(*screenManager()->getUIContext()); + screenManager()->getUIContext()->End(); + screenManager()->getUIContext()->Flush(); + } +} + +bool UIScreen::touch(const TouchInput &touch) { + if (root_) { + UI::TouchEvent(touch, root_); + return true; + } + return false; +} + +bool UIScreen::key(const KeyInput &key) { + if (root_) { + return UI::KeyEvent(key, root_); + } + return false; +} + +bool UIDialogScreen::key(const KeyInput &key) { + bool retval = UIScreen::key(key); + if (!retval && (key.flags & KEY_DOWN) && UI::IsEscapeKey(key)) { + if (finished_) { + ELOG("Screen already finished"); + } else { + finished_ = true; + screenManager()->finishDialog(this, DR_BACK); + } + return true; + } + return retval; +} + +bool UIScreen::axis(const AxisInput &axis) { + // Simple translation of hat to keys for Shield and other modern pads. + // TODO: Use some variant of keymap? + int flags = 0; + if (axis.axisId == JOYSTICK_AXIS_HAT_X) { + if (axis.value < -0.7f) + flags |= PAD_BUTTON_LEFT; + if (axis.value > 0.7f) + flags |= PAD_BUTTON_RIGHT; + } + if (axis.axisId == JOYSTICK_AXIS_HAT_Y) { + if (axis.value < -0.7f) + flags |= PAD_BUTTON_UP; + if (axis.value > 0.7f) + flags |= PAD_BUTTON_DOWN; + } + + // Yeah yeah, this should be table driven.. + int pressed = flags & ~hatDown_; + int released = ~flags & hatDown_; + if (pressed & PAD_BUTTON_LEFT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT, KEY_DOWN)); + if (pressed & PAD_BUTTON_RIGHT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT, KEY_DOWN)); + if (pressed & PAD_BUTTON_UP) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP, KEY_DOWN)); + if (pressed & PAD_BUTTON_DOWN) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN, KEY_DOWN)); + if (released & PAD_BUTTON_LEFT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT, KEY_UP)); + if (released & PAD_BUTTON_RIGHT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT, KEY_UP)); + if (released & PAD_BUTTON_UP) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP, KEY_UP)); + if (released & PAD_BUTTON_DOWN) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN, KEY_UP)); + hatDown_ = flags; + if (root_) { + UI::AxisEvent(axis, root_); + return true; + } + return (pressed & (PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_UP | PAD_BUTTON_DOWN)) != 0; +} + +UI::EventReturn UIScreen::OnBack(UI::EventParams &e) { + screenManager()->finishDialog(this, DR_BACK); + return UI::EVENT_DONE; +} + +UI::EventReturn UIScreen::OnOK(UI::EventParams &e) { + screenManager()->finishDialog(this, DR_OK); + return UI::EVENT_DONE; +} + +UI::EventReturn UIScreen::OnCancel(UI::EventParams &e) { + screenManager()->finishDialog(this, DR_CANCEL); + return UI::EVENT_DONE; +} + +PopupScreen::PopupScreen(std::string title, std::string button1, std::string button2) + : box_(0), title_(title), defaultButton_(NULL) { + I18NCategory *di = GetI18NCategory("Dialog"); + if (!button1.empty()) + button1_ = di->T(button1.c_str()); + if (!button2.empty()) + button2_ = di->T(button2.c_str()); +} + +bool PopupScreen::touch(const TouchInput &touch) { + if (!box_ || (touch.flags & TOUCH_DOWN) == 0 || touch.id != 0) { + return UIDialogScreen::touch(touch); + } + + if (!box_->GetBounds().Contains(touch.x, touch.y)) + screenManager()->finishDialog(this, DR_BACK); + + return UIDialogScreen::touch(touch); +} + +bool PopupScreen::key(const KeyInput &key) { + if (key.flags & KEY_DOWN) { + if (key.keyCode == NKCODE_ENTER && defaultButton_) { + UI::EventParams e; + defaultButton_->OnClick.Trigger(e); + return true; + } + } + + return UIDialogScreen::key(key); +} + +void PopupScreen::CreateViews() { + using namespace UI; + + UIContext &dc = *screenManager()->getUIContext(); + + root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); + + float yres = screenManager()->getUIContext()->GetBounds().h; + + box_ = new LinearLayout(ORIENT_VERTICAL, + new AnchorLayoutParams(550, FillVertical() ? yres - 30 : WRAP_CONTENT, dc.GetBounds().centerX(), dc.GetBounds().centerY(), NONE, NONE, true)); + + root_->Add(box_); + box_->SetBG(UI::Drawable(0xFF303030)); + box_->SetHasDropShadow(true); + + View *title = new PopupHeader(title_); + box_->Add(title); + + CreatePopupContents(box_); + root_->SetDefaultFocusView(box_); + + if (ShowButtons() && !button1_.empty()) { + // And the two buttons at the bottom. + LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(200, WRAP_CONTENT)); + buttonRow->SetSpacing(0); + Margins buttonMargins(5, 5); + + // Adjust button order to the platform default. +#if defined(_WIN32) + defaultButton_ = buttonRow->Add(new Button(button1_, new LinearLayoutParams(1.0f, buttonMargins))); + defaultButton_->OnClick.Handle(this, &PopupScreen::OnOK); + if (!button2_.empty()) + buttonRow->Add(new Button(button2_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &PopupScreen::OnCancel); +#else + if (!button2_.empty()) + buttonRow->Add(new Button(button2_, new LinearLayoutParams(1.0f)))->OnClick.Handle(this, &PopupScreen::OnCancel); + defaultButton_ = buttonRow->Add(new Button(button1_, new LinearLayoutParams(1.0f))); + defaultButton_->OnClick.Handle(this, &PopupScreen::OnOK); +#endif + + box_->Add(buttonRow); + } +} + +void MessagePopupScreen::CreatePopupContents(UI::ViewGroup *parent) { + std::vector messageLines; + SplitString(message_, '\n', messageLines); + for (const auto& lineOfText : messageLines) + parent->Add(new UI::TextView(lineOfText, ALIGN_LEFT | ALIGN_VCENTER, false)); +} + +void MessagePopupScreen::OnCompleted(DialogResult result) { + if (result == DR_OK) { + if (callback_) + callback_(true); + } else { + if (callback_) + callback_(false); + } +} + +UI::EventReturn PopupScreen::OnOK(UI::EventParams &e) { + OnCompleted(DR_OK); + screenManager()->finishDialog(this, DR_OK); + return UI::EVENT_DONE; +} + +UI::EventReturn PopupScreen::OnCancel(UI::EventParams &e) { + OnCompleted(DR_CANCEL); + screenManager()->finishDialog(this, DR_CANCEL); + return UI::EVENT_DONE; +} + +void ListPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { + using namespace UI; + + listView_ = parent->Add(new ListView(&adaptor_)); //, new LinearLayoutParams(1.0))); + listView_->SetMaxHeight(screenManager()->getUIContext()->GetBounds().h - 140); + listView_->OnChoice.Handle(this, &ListPopupScreen::OnListChoice); +} + +UI::EventReturn ListPopupScreen::OnListChoice(UI::EventParams &e) { + adaptor_.SetSelected(e.a); + if (callback_) + callback_(adaptor_.GetSelected()); + screenManager()->finishDialog(this, DR_OK); + OnCompleted(DR_OK); + OnChoice.Dispatch(e); + return UI::EVENT_DONE; +} + +namespace UI { + +UI::EventReturn PopupMultiChoice::HandleClick(UI::EventParams &e) { + restoreFocus_ = HasFocus(); + + std::vector choices; + for (int i = 0; i < numChoices_; i++) { + choices.push_back(category_ ? category_->T(choices_[i]) : choices_[i]); + } + + Screen *popupScreen = new ListPopupScreen(text_, choices, *value_ - minVal_, + std::bind(&PopupMultiChoice::ChoiceCallback, this, placeholder::_1)); + screenManager_->push(popupScreen); + return UI::EVENT_DONE; +} + +void PopupMultiChoice::Update(const InputState &input_state) { + UpdateText(); +} + +void PopupMultiChoice::UpdateText() { + // Clamp the value to be safe. + if (*value_ < minVal_ || *value_ > minVal_ + numChoices_ - 1) { + valueText_ = "(invalid choice)"; // Shouldn't happen. Should be no need to translate this. + } else { + valueText_ = category_ ? category_->T(choices_[*value_ - minVal_]) : choices_[*value_ - minVal_]; + } +} + +void PopupMultiChoice::ChoiceCallback(int num) { + if (num != -1) { + *value_ = num + minVal_; + UpdateText(); + + UI::EventParams e; + e.v = this; + e.a = num; + OnChoice.Trigger(e); + + if (restoreFocus_) { + SetFocusedView(this); + } + } +} + +void PopupMultiChoice::Draw(UIContext &dc) { + Style style = dc.theme->itemStyle; + if (!IsEnabled()) { + style = dc.theme->itemDisabledStyle; + } + Choice::Draw(dc); + int paddingX = 12; + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawText(valueText_.c_str(), bounds_.x2() - paddingX, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); +} + +PopupSliderChoice::PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, ScreenManager *screenManager, LayoutParams *layoutParams) + : Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(1), screenManager_(screenManager) { + OnClick.Handle(this, &PopupSliderChoice::HandleClick); +} + +PopupSliderChoice::PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, int step, ScreenManager *screenManager, LayoutParams *layoutParams) +: Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), screenManager_(screenManager) { + OnClick.Handle(this, &PopupSliderChoice::HandleClick); +} + +PopupSliderChoiceFloat::PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, ScreenManager *screenManager, LayoutParams *layoutParams) + : Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(1.0f), screenManager_(screenManager) { + OnClick.Handle(this, &PopupSliderChoiceFloat::HandleClick); +} + +PopupSliderChoiceFloat::PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, float step, ScreenManager *screenManager, LayoutParams *layoutParams) + : Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), screenManager_(screenManager) { + OnClick.Handle(this, &PopupSliderChoiceFloat::HandleClick); +} + +EventReturn PopupSliderChoice::HandleClick(EventParams &e) { + restoreFocus_ = HasFocus(); + + SliderPopupScreen *popupScreen = new SliderPopupScreen(value_, minValue_, maxValue_, text_, step_); + popupScreen->OnChange.Handle(this, &PopupSliderChoice::HandleChange); + screenManager_->push(popupScreen); + return EVENT_DONE; +} + +EventReturn PopupSliderChoice::HandleChange(EventParams &e) { + e.v = this; + OnChange.Trigger(e); + + if (restoreFocus_) { + SetFocusedView(this); + } + return EVENT_DONE; +} + +void PopupSliderChoice::Draw(UIContext &dc) { + Style style = dc.theme->itemStyle; + if (!IsEnabled()) { + style = dc.theme->itemDisabledStyle; + } + Choice::Draw(dc); + char temp[32]; + sprintf(temp, "%i", *value_); + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawText(temp, bounds_.x2() - 12, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); +} + +EventReturn PopupSliderChoiceFloat::HandleClick(EventParams &e) { + restoreFocus_ = HasFocus(); + + SliderFloatPopupScreen *popupScreen = new SliderFloatPopupScreen(value_, minValue_, maxValue_, text_, step_); + popupScreen->OnChange.Handle(this, &PopupSliderChoiceFloat::HandleChange); + screenManager_->push(popupScreen); + return EVENT_DONE; +} + +EventReturn PopupSliderChoiceFloat::HandleChange(EventParams &e) { + e.v = this; + OnChange.Trigger(e); + + if (restoreFocus_) { + SetFocusedView(this); + } + return EVENT_DONE; +} + +void PopupSliderChoiceFloat::Draw(UIContext &dc) { + Style style = dc.theme->itemStyle; + if (!IsEnabled()) { + style = dc.theme->itemDisabledStyle; + } + Choice::Draw(dc); + char temp[32]; + sprintf(temp, "%2.2f", *value_); + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawText(temp, bounds_.x2() - 12, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); +} + +EventReturn SliderPopupScreen::OnDecrease(EventParams ¶ms) { + sliderValue_ -= step_; + slider_->Clamp(); + return EVENT_DONE; +} + +EventReturn SliderPopupScreen::OnIncrease(EventParams ¶ms) { + sliderValue_ += step_; + slider_->Clamp(); + return EVENT_DONE; +} + +void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { + using namespace UI; + sliderValue_ = *value_; + LinearLayout *lin = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(UI::Margins(10, 5)))); + slider_ = new Slider(&sliderValue_, minValue_, maxValue_, step_, new LinearLayoutParams(1.0f)); + lin->Add(slider_); + lin->Add(new Button(" - "))->OnClick.Handle(this, &SliderPopupScreen::OnDecrease); + lin->Add(new Button(" + "))->OnClick.Handle(this, &SliderPopupScreen::OnIncrease); + + UI::SetFocusedView(slider_); +} + +void SliderFloatPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { + using namespace UI; + sliderValue_ = *value_; + LinearLayout *lin = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(UI::Margins(10, 5)))); + slider_ = new SliderFloat(&sliderValue_, minValue_, maxValue_, new LinearLayoutParams(1.0f)); + lin->Add(slider_); + lin->Add(new Button(" - "))->OnClick.Handle(this, &SliderFloatPopupScreen::OnDecrease); + lin->Add(new Button(" + "))->OnClick.Handle(this, &SliderFloatPopupScreen::OnIncrease); + // slider_ = parent->Add(new SliderFloat(&sliderValue_, minValue_, maxValue_, new LinearLayoutParams(UI::Margins(10, 5)))); + UI::SetFocusedView(slider_); +} + +EventReturn SliderFloatPopupScreen::OnDecrease(EventParams ¶ms) { + sliderValue_ -= step_; + slider_->Clamp(); + return EVENT_DONE; +} + +EventReturn SliderFloatPopupScreen::OnIncrease(EventParams ¶ms) { + sliderValue_ += step_; + slider_->Clamp(); + return EVENT_DONE; +} + +void SliderPopupScreen::OnCompleted(DialogResult result) { + if (result == DR_OK) { + *value_ = sliderValue_; + EventParams e; + e.v = 0; + e.a = *value_; + OnChange.Trigger(e); + } +} + +void SliderFloatPopupScreen::OnCompleted(DialogResult result) { + if (result == DR_OK) { + *value_ = sliderValue_; + EventParams e; + e.v = 0; + e.a = (int)*value_; + e.f = *value_; + OnChange.Trigger(e); + } +} + +PopupTextInputChoice::PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, int maxLen, ScreenManager *screenManager, LayoutParams *layoutParams) +: Choice(title, "", false, layoutParams), value_(value), placeHolder_(placeholder), screenManager_(screenManager), maxLen_(maxLen) { + OnClick.Handle(this, &PopupTextInputChoice::HandleClick); +} + +EventReturn PopupTextInputChoice::HandleClick(EventParams &e) { + restoreFocus_ = HasFocus(); + + TextEditPopupScreen *popupScreen = new TextEditPopupScreen(value_, placeHolder_, text_, maxLen_); + popupScreen->OnChange.Handle(this, &PopupTextInputChoice::HandleChange); + screenManager_->push(popupScreen); + return EVENT_DONE; +} + +void PopupTextInputChoice::Draw(UIContext &dc) { + Style style = dc.theme->itemStyle; + if (!IsEnabled()) { + style = dc.theme->itemDisabledStyle; + } + Choice::Draw(dc); + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawText(value_->c_str(), bounds_.x2() - 12, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); +} + +EventReturn PopupTextInputChoice::HandleChange(EventParams &e) { + e.v = this; + OnChange.Trigger(e); + + if (restoreFocus_) { + SetFocusedView(this); + } + return EVENT_DONE; +} + +void TextEditPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { + using namespace UI; + + textEditValue_ = *value_; + LinearLayout *lin = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams((UI::Size)300, WRAP_CONTENT))); + edit_ = new TextEdit(textEditValue_, placeholder_, new LinearLayoutParams(1.0f)); + edit_->SetMaxLen(maxLen_); + lin->Add(edit_); + + UI::SetFocusedView(edit_); +} + +void TextEditPopupScreen::OnCompleted(DialogResult result) { + if (result == DR_OK) { + *value_ = edit_->GetText(); + EventParams e; + e.v = edit_; + OnChange.Trigger(e); + } +} + +void ChoiceWithValueDisplay::Draw(UIContext &dc) { + Style style = dc.theme->itemStyle; + std::ostringstream valueText; + Choice::Draw(dc); + dc.SetFontStyle(dc.theme->uiFont); + + if (sValue_ != nullptr) { + if (category_) + valueText << category_->T(*sValue_); + else + valueText << *sValue_; + } else if (iValue_ != nullptr) { + valueText << *iValue_; + } + + dc.DrawText(valueText.str().c_str(), bounds_.x2() - 12, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); +} + +} // namespace UI diff --git a/ext/native/ui/ui_screen.h b/ext/native/ui/ui_screen.h new file mode 100644 index 0000000000..1ffb28c289 --- /dev/null +++ b/ext/native/ui/ui_screen.h @@ -0,0 +1,301 @@ +#pragma once + +#include "ui/screen.h" +#include "ui/viewgroup.h" + +class I18NCategory; +class Thin3DContext; + +class UIScreen : public Screen { +public: + UIScreen(); + ~UIScreen(); + + virtual void update(InputState &input) override; + virtual void render() override; + + virtual bool touch(const TouchInput &touch) override; + virtual bool key(const KeyInput &touch) override; + virtual bool axis(const AxisInput &touch) override; + + // Some useful default event handlers + UI::EventReturn OnOK(UI::EventParams &e); + UI::EventReturn OnCancel(UI::EventParams &e); + UI::EventReturn OnBack(UI::EventParams &e); + +protected: + virtual void CreateViews() = 0; + virtual void DrawBackground(UIContext &dc) {} + + virtual void RecreateViews() { recreateViews_ = true; } + + UI::ViewGroup *root_; + +private: + void DoRecreateViews(); + + bool recreateViews_; + + int hatDown_; +}; + +class UIDialogScreen : public UIScreen { +public: + UIDialogScreen() : UIScreen(), finished_(false) {} + virtual bool key(const KeyInput &key) override; + +private: + bool finished_; +}; + + +class PopupScreen : public UIDialogScreen { +public: + PopupScreen(std::string title, std::string button1 = "", std::string button2 = ""); + + virtual void CreatePopupContents(UI::ViewGroup *parent) = 0; + virtual void CreateViews() override; + virtual bool isTransparent() const override { return true; } + virtual bool touch(const TouchInput &touch) override; + virtual bool key(const KeyInput &key) override; + +protected: + virtual bool FillVertical() const { return false; } + virtual bool ShowButtons() const { return true; } + virtual void OnCompleted(DialogResult result) {} + +private: + UI::EventReturn OnOK(UI::EventParams &e); + UI::EventReturn OnCancel(UI::EventParams &e); + + UI::ViewGroup *box_; + UI::Button *defaultButton_; + std::string title_; + std::string button1_; + std::string button2_; +}; + +class ListPopupScreen : public PopupScreen { +public: + ListPopupScreen(std::string title) : PopupScreen(title), showButtons_(false) {} + ListPopupScreen(std::string title, const std::vector &items, int selected, std::function callback, bool showButtons = false) + : PopupScreen(title, "OK", "Cancel"), adaptor_(items, selected), callback_(callback), showButtons_(showButtons) { + } + ListPopupScreen(std::string title, const std::vector &items, int selected, bool showButtons = false) + : PopupScreen(title, "OK", "Cancel"), adaptor_(items, selected), showButtons_(showButtons) { + } + + int GetChoice() const { + return listView_->GetSelected(); + } + std::string GetChoiceString() const { + return adaptor_.GetTitle(listView_->GetSelected()); + } + UI::Event OnChoice; + virtual std::string tag() const override { return std::string("listpopup"); } + +protected: + virtual bool FillVertical() const override { return false; } + virtual bool ShowButtons() const override { return showButtons_; } + virtual void CreatePopupContents(UI::ViewGroup *parent) override; + UI::StringVectorListAdaptor adaptor_; + UI::ListView *listView_; + +private: + UI::EventReturn OnListChoice(UI::EventParams &e); + + std::function callback_; + bool showButtons_; +}; + +class MessagePopupScreen : public PopupScreen { +public: + MessagePopupScreen(std::string title, std::string message, std::string button1, std::string button2, std::function callback) + : PopupScreen(title, button1, button2), message_(message), callback_(callback) {} + UI::Event OnChoice; + +protected: + virtual bool FillVertical() const override { return false; } + virtual bool ShowButtons() const override { return true; } + virtual void CreatePopupContents(UI::ViewGroup *parent) override; + +private: + void OnCompleted(DialogResult result) override; + std::string message_; + std::function callback_; +}; + +// TODO: Need a way to translate OK and Cancel + +namespace UI { + +class SliderPopupScreen : public PopupScreen { +public: + SliderPopupScreen(int *value, int minValue, int maxValue, const std::string &title, int step = 1) + : PopupScreen(title, "OK", "Cancel"), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step) {} + virtual void CreatePopupContents(ViewGroup *parent) override; + + Event OnChange; + +private: + EventReturn OnDecrease(EventParams ¶ms); + EventReturn OnIncrease(EventParams ¶ms); + virtual void OnCompleted(DialogResult result) override; + Slider *slider_; + int *value_; + int sliderValue_; + int minValue_; + int maxValue_; + int step_; +}; + +class SliderFloatPopupScreen : public PopupScreen { +public: + SliderFloatPopupScreen(float *value, float minValue, float maxValue, const std::string &title, float step = 1.0f) + : PopupScreen(title, "OK", "Cancel"), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step) {} + void CreatePopupContents(UI::ViewGroup *parent) override; + + Event OnChange; + +private: + EventReturn OnIncrease(EventParams ¶ms); + EventReturn OnDecrease(EventParams ¶ms); + virtual void OnCompleted(DialogResult result) override; + UI::SliderFloat *slider_; + float sliderValue_; + float *value_; + float minValue_; + float maxValue_; + float step_; +}; + +class TextEditPopupScreen : public PopupScreen { +public: + TextEditPopupScreen(std::string *value, std::string &placeholder, const std::string &title, int maxLen) + : PopupScreen(title, "OK", "Cancel"), value_(value), placeholder_(placeholder), maxLen_(maxLen) {} + virtual void CreatePopupContents(ViewGroup *parent) override; + + Event OnChange; + +private: + virtual void OnCompleted(DialogResult result) override; + TextEdit *edit_; + std::string *value_; + std::string textEditValue_; + std::string placeholder_; + int step_; + int maxLen_; +}; + +// Reads and writes value to determine the current selection. +class PopupMultiChoice : public UI::Choice { +public: + PopupMultiChoice(int *value, const std::string &text, const char **choices, int minVal, int numChoices, + I18NCategory *category, ScreenManager *screenManager, UI::LayoutParams *layoutParams = 0) + : UI::Choice(text, "", false, layoutParams), value_(value), choices_(choices), minVal_(minVal), numChoices_(numChoices), + category_(category), screenManager_(screenManager) { + if (*value >= numChoices+minVal) *value = numChoices+minVal-1; + if (*value < minVal) *value = minVal; + OnClick.Handle(this, &PopupMultiChoice::HandleClick); + UpdateText(); + } + + virtual void Draw(UIContext &dc) override; + virtual void Update(const InputState &input_state) override; + + UI::Event OnChoice; + +private: + void UpdateText(); + UI::EventReturn HandleClick(UI::EventParams &e); + + void ChoiceCallback(int num); + + int *value_; + const char **choices_; + int minVal_; + int numChoices_; + I18NCategory *category_; + ScreenManager *screenManager_; + std::string valueText_; + bool restoreFocus_; +}; + + +class PopupSliderChoice : public Choice { +public: + PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, ScreenManager *screenManager, LayoutParams *layoutParams = 0); + PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, int step, ScreenManager *screenManager, LayoutParams *layoutParams = 0); + + virtual void Draw(UIContext &dc) override; + + Event OnChange; + +private: + EventReturn HandleClick(EventParams &e); + EventReturn HandleChange(EventParams &e); + + int *value_; + int minValue_; + int maxValue_; + int step_; + ScreenManager *screenManager_; + bool restoreFocus_; +}; + +class PopupSliderChoiceFloat : public Choice { +public: + PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, ScreenManager *screenManager, LayoutParams *layoutParams = 0); + PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, float step, ScreenManager *screenManager, LayoutParams *layoutParams = 0); + + virtual void Draw(UIContext &dc) override; + + Event OnChange; + +private: + EventReturn HandleClick(EventParams &e); + EventReturn HandleChange(EventParams &e); + float *value_; + float minValue_; + float maxValue_; + float step_; + ScreenManager *screenManager_; + bool restoreFocus_; +}; + +class PopupTextInputChoice: public Choice { +public: + PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, int maxLen, ScreenManager *screenManager, LayoutParams *layoutParams = 0); + + virtual void Draw(UIContext &dc) override; + + Event OnChange; + +private: + EventReturn HandleClick(EventParams &e); + EventReturn HandleChange(EventParams &e); + ScreenManager *screenManager_; + std::string *value_; + std::string placeHolder_; + std::string defaultText_; + int maxLen_; + bool restoreFocus_; +}; + +class ChoiceWithValueDisplay : public UI::Choice { +public: + ChoiceWithValueDisplay(int *value, const std::string &text, LayoutParams *layoutParams = 0) + : Choice(text, layoutParams), iValue_(value), category_(nullptr) { sValue_ = nullptr; } + + ChoiceWithValueDisplay(std::string *value, const std::string &text, I18NCategory *category, LayoutParams *layoutParams = 0) + : Choice(text, layoutParams), sValue_(value), category_(category) { iValue_ = nullptr; } + + virtual void Draw(UIContext &dc) override; + +private: + int *iValue_; + std::string *sValue_; + I18NCategory *category_; +}; + +} // namespace UI diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp new file mode 100644 index 0000000000..1992953007 --- /dev/null +++ b/ext/native/ui/view.cpp @@ -0,0 +1,1064 @@ +#include +#include + +#include "base/mutex.h" +#include "base/stringutil.h" +#include "base/timeutil.h" +#include "input/input_state.h" +#include "input/keycodes.h" +#include "gfx_es2/draw_buffer.h" +#include "gfx/texture.h" +#include "gfx/texture_atlas.h" +#include "util/text/utf8.h" +#include "ui/ui.h" +#include "ui/view.h" +#include "ui/ui_context.h" +#include "thin3d/thin3d.h" +#include "base/NativeApp.h" + +namespace UI { + +static View *focusedView; +static bool focusMovementEnabled; +bool focusForced; +static recursive_mutex mutex_; + +const float ITEM_HEIGHT = 64.f; + + +struct DispatchQueueItem { + Event *e; + EventParams params; +}; + +std::deque g_dispatchQueue; + + +void EventTriggered(Event *e, EventParams params) { + lock_guard guard(mutex_); + + DispatchQueueItem item; + item.e = e; + item.params = params; + g_dispatchQueue.push_front(item); +} + +void DispatchEvents() { + lock_guard guard(mutex_); + + while (!g_dispatchQueue.empty()) { + DispatchQueueItem item = g_dispatchQueue.back(); + g_dispatchQueue.pop_back(); + if (item.e) { + item.e->Dispatch(item.params); + } + } +} + +void RemoveQueuedEvents(View *v) { + for (size_t i = 0; i < g_dispatchQueue.size(); i++) { + if (g_dispatchQueue[i].params.v == v) + g_dispatchQueue.erase(g_dispatchQueue.begin() + i); + } +} + +View *GetFocusedView() { + return focusedView; +} + +void SetFocusedView(View *view, bool force) { + if (focusedView) { + focusedView->FocusChanged(FF_LOSTFOCUS); + } + focusedView = view; + if (focusedView) { + focusedView->FocusChanged(FF_GOTFOCUS); + if (force) { + focusForced = true; + } + } +} + +void EnableFocusMovement(bool enable) { + focusMovementEnabled = enable; + if (!enable) { + if (focusedView) { + focusedView->FocusChanged(FF_LOSTFOCUS); + } + focusedView = 0; + } +} + +bool IsFocusMovementEnabled() { + return focusMovementEnabled; +} + +void MeasureBySpec(Size sz, float contentWidth, MeasureSpec spec, float *measured) { + *measured = sz; + if (sz == WRAP_CONTENT) { + if (spec.type == UNSPECIFIED || spec.type == AT_MOST) + *measured = contentWidth; + else if (spec.type == EXACTLY) + *measured = spec.size; + } else if (sz == FILL_PARENT) { + if (spec.type == UNSPECIFIED) + *measured = contentWidth; // We have no value to set + else + *measured = spec.size; + } else if (spec.type == EXACTLY || (spec.type == AT_MOST && *measured > spec.size)) { + *measured = spec.size; + } +} + +void Event::Add(std::function func) { + HandlerRegistration reg; + reg.func = func; + handlers_.push_back(reg); +} + +// Call this from input thread or whatever, it doesn't matter +void Event::Trigger(EventParams &e) { + EventTriggered(this, e); +} + +// Call this from UI thread +EventReturn Event::Dispatch(EventParams &e) { + for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter) { + if ((iter->func)(e) == UI::EVENT_DONE) { + // Event is handled, stop looping immediately. This event might even have gotten deleted. + return UI::EVENT_DONE; + } + } + return UI::EVENT_SKIPPED; +} + +View::~View() { + if (HasFocus()) + SetFocusedView(0); + RemoveQueuedEvents(this); +} + +void View::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { + float contentW = 0.0f, contentH = 0.0f; + GetContentDimensions(dc, contentW, contentH); + MeasureBySpec(layoutParams_->width, contentW, horiz, &measuredWidth_); + MeasureBySpec(layoutParams_->height, contentH, vert, &measuredHeight_); +} + +// Default values + +void View::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + w = 10.0f; + h = 10.0f; +} + +Point View::GetFocusPosition(FocusDirection dir) { + // The +2/-2 is some extra fudge factor to cover for views sitting right next to each other. + // Distance zero yields strange results otherwise. + switch (dir) { + case FOCUS_LEFT: return Point(bounds_.x + 2, bounds_.centerY()); + case FOCUS_RIGHT: return Point(bounds_.x2() - 2, bounds_.centerY()); + case FOCUS_UP: return Point(bounds_.centerX(), bounds_.y + 2); + case FOCUS_DOWN: return Point(bounds_.centerX(), bounds_.y2() - 2); + + default: + return bounds_.Center(); + } +} + +bool View::SetFocus() { + if (IsFocusMovementEnabled()) { + if (CanBeFocused()) { + SetFocusedView(this); + return true; + } + } + return false; +} + +void Clickable::Click() { + UI::EventParams e; + e.v = this; + OnClick.Trigger(e); +}; + +void Clickable::FocusChanged(int focusFlags) { + if (focusFlags & FF_LOSTFOCUS) { + down_ = false; + dragging_ = false; + } +} + +void Clickable::Touch(const TouchInput &input) { + if (!IsEnabled()) { + dragging_ = false; + down_ = false; + return; + } + + if (input.flags & TOUCH_DOWN) { + if (bounds_.Contains(input.x, input.y)) { + if (IsFocusMovementEnabled()) + SetFocusedView(this); + dragging_ = true; + down_ = true; + } else { + down_ = false; + dragging_ = false; + } + } else if (input.flags & TOUCH_MOVE) { + if (dragging_) + down_ = bounds_.Contains(input.x, input.y); + } + if (input.flags & TOUCH_UP) { + if ((input.flags & TOUCH_CANCEL) == 0 && dragging_ && bounds_.Contains(input.x, input.y)) { + Click(); + } + down_ = false; + downCountDown_ = 0; + dragging_ = false; + } +} + +// TODO: O/X confirm preference for xperia play? + +bool IsDPadKey(const KeyInput &key) { + if (dpadKeys.empty()) { + return key.keyCode >= NKCODE_DPAD_UP && key.keyCode <= NKCODE_DPAD_RIGHT; + } else { + return std::find(dpadKeys.begin(), dpadKeys.end(), KeyDef(key.deviceId, key.keyCode)) != dpadKeys.end(); + } +} + +bool IsAcceptKey(const KeyInput &key) { + if (confirmKeys.empty()) { + if (key.deviceId == DEVICE_ID_KEYBOARD) { + return key.keyCode == NKCODE_SPACE || key.keyCode == NKCODE_ENTER || key.keyCode == NKCODE_Z; + } else { + return key.keyCode == NKCODE_BUTTON_A || key.keyCode == NKCODE_BUTTON_CROSS || key.keyCode == NKCODE_BUTTON_1; + } + } else { + return std::find(confirmKeys.begin(), confirmKeys.end(), KeyDef(key.deviceId, key.keyCode)) != confirmKeys.end(); + } +} + +bool IsEscapeKey(const KeyInput &key) { + if (cancelKeys.empty()) { + if (key.deviceId == DEVICE_ID_KEYBOARD) { + return key.keyCode == NKCODE_ESCAPE || key.keyCode == NKCODE_BACK; + } else { + return key.keyCode == NKCODE_BUTTON_CIRCLE || key.keyCode == NKCODE_BUTTON_B || key.keyCode == NKCODE_BUTTON_2; + } + } else { + return std::find(cancelKeys.begin(), cancelKeys.end(), KeyDef(key.deviceId, key.keyCode)) != cancelKeys.end(); + } +} + +bool IsTabLeftKey(const KeyInput &key) { + if (tabLeftKeys.empty()) { + return key.keyCode == NKCODE_BUTTON_L1; + } else { + return std::find(tabLeftKeys.begin(), tabLeftKeys.end(), KeyDef(key.deviceId, key.keyCode)) != tabLeftKeys.end(); + } +} + +bool IsTabRightKey(const KeyInput &key) { + if (tabRightKeys.empty()) { + return key.keyCode == NKCODE_BUTTON_R1; + } else { + return std::find(tabRightKeys.begin(), tabRightKeys.end(), KeyDef(key.deviceId, key.keyCode)) != tabRightKeys.end(); + } +} + +bool Clickable::Key(const KeyInput &key) { + if (!HasFocus() && key.deviceId != DEVICE_ID_MOUSE) { + down_ = false; + return false; + } + // TODO: Replace most of Update with this. + bool ret = false; + if (key.flags & KEY_DOWN) { + if (IsAcceptKey(key)) { + down_ = true; + ret = true; + } + } + if (key.flags & KEY_UP) { + if (IsAcceptKey(key)) { + if (down_) { + Click(); + down_ = false; + ret = true; + } + } else if (IsEscapeKey(key)) { + down_ = false; + } + } + return ret; +} + +void StickyChoice::Touch(const TouchInput &input) { + dragging_ = false; + if (!IsEnabled()) { + down_ = false; + return; + } + + if (input.flags & TOUCH_DOWN) { + if (bounds_.Contains(input.x, input.y)) { + if (IsFocusMovementEnabled()) + SetFocusedView(this); + down_ = true; + Click(); + } + } +} + +bool StickyChoice::Key(const KeyInput &key) { + if (!HasFocus()) { + return false; + } + + // TODO: Replace most of Update with this. + if (key.flags & KEY_DOWN) { + if (IsAcceptKey(key)) { + down_ = true; + Click(); + return true; + } + } + return false; +} + +void StickyChoice::FocusChanged(int focusFlags) { + // Override Clickable's FocusChanged to do nothing. +} + +Item::Item(LayoutParams *layoutParams) : InertView(layoutParams) { + if (!layoutParams) { + layoutParams_->width = FILL_PARENT; + layoutParams_->height = ITEM_HEIGHT; + } +} + +void Item::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + w = 0.0f; + h = 0.0f; +} + +void ClickableItem::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + w = 0.0f; + h = 0.0f; +} + +ClickableItem::ClickableItem(LayoutParams *layoutParams) : Clickable(layoutParams) { + if (!layoutParams) { + if (layoutParams_->width == WRAP_CONTENT) + layoutParams_->width = FILL_PARENT; + layoutParams_->height = ITEM_HEIGHT; + } +} + +void ClickableItem::Draw(UIContext &dc) { + Style style = dc.theme->itemStyle; + + if (HasFocus()) { + style = dc.theme->itemFocusedStyle; + } + if (down_) { + style = dc.theme->itemDownStyle; + } + + dc.FillRect(style.background, bounds_); +} + +void Choice::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + if (atlasImage_ != -1) { + const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_]; + w = img.w; + h = img.h; + } else { + dc.MeasureText(dc.theme->uiFont, text_.c_str(), &w, &h); + } + w += 24; + h += 16; +} + +void Choice::HighlightChanged(bool highlighted){ + highlighted_ = highlighted; +} + +void Choice::Draw(UIContext &dc) { + if (!IsSticky()) { + ClickableItem::Draw(dc); + } else { + Style style = dc.theme->itemStyle; + if (highlighted_) { + style = dc.theme->itemHighlightedStyle; + } + if (down_) { + style = dc.theme->itemDownStyle; + } + if (HasFocus()) { + style = dc.theme->itemFocusedStyle; + } + dc.FillRect(style.background, bounds_); + } + + Style style = dc.theme->itemStyle; + if (!IsEnabled()) { + style = dc.theme->itemDisabledStyle; + } + + if (atlasImage_ != -1) { + dc.Draw()->DrawImage(atlasImage_, bounds_.centerX(), bounds_.centerY(), 1.0f, style.fgColor, ALIGN_CENTER); + } else { + int paddingX = 12; + dc.SetFontStyle(dc.theme->uiFont); + if (centered_) { + dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER); + } else { + if (iconImage_ != -1) { + dc.Draw()->DrawImage(iconImage_, bounds_.x2() - 32 - paddingX, bounds_.centerY(), 0.5f, style.fgColor, ALIGN_CENTER); + } + dc.DrawText(text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), style.fgColor, ALIGN_VCENTER); + } + } + + if (selected_) { + dc.Draw()->DrawImage(dc.theme->checkOn, bounds_.x2() - 40, bounds_.centerY(), 1.0f, style.fgColor, ALIGN_CENTER); + } +} + +void InfoItem::Draw(UIContext &dc) { + Item::Draw(dc); + if (HasFocus()) { + UI::Style style = dc.theme->itemFocusedStyle; + style.background.color &= 0x7fffffff; + dc.FillRect(style.background, bounds_); + } + int paddingX = 12; + + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawText(text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER); + dc.DrawText(rightText_.c_str(), bounds_.x2() - paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER | ALIGN_RIGHT); +// dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y + 2, dc.theme->itemDownStyle.bgColor); +} + +ItemHeader::ItemHeader(const std::string &text, LayoutParams *layoutParams) + : Item(layoutParams), text_(text) { + layoutParams_->width = FILL_PARENT; + layoutParams_->height = 40; +} + +void ItemHeader::Draw(UIContext &dc) { + dc.SetFontStyle(dc.theme->uiFontSmall); + dc.DrawText(text_.c_str(), bounds_.x + 4, bounds_.centerY(), 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER); + dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), 0xFFFFFFFF); +} + +void PopupHeader::Draw(UIContext &dc) { + const float paddingHorizontal = 12; + const float availableWidth = bounds_.w - paddingHorizontal * 2; + + float tw, th; + dc.SetFontStyle(dc.theme->uiFont); + dc.MeasureText(dc.GetFontStyle(), text_.c_str(), &tw, &th, 0); + + float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f; + + float tx = paddingHorizontal; + if (availableWidth < tw) { + float overageRatio = 1.5f * availableWidth * 1.0f / tw; + tx -= (1.0f + sin(time_now_d() * overageRatio)) * sineWidth; + Bounds tb = bounds_; + tb.x = bounds_.x + paddingHorizontal; + tb.w = bounds_.w - paddingHorizontal * 2; + dc.PushScissor(tb); + } + + dc.DrawText(text_.c_str(), bounds_.x + tx, bounds_.centerY(), dc.theme->popupTitle.fgColor, ALIGN_LEFT | ALIGN_VCENTER); + dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.theme->popupTitle.fgColor); + + if (availableWidth < tw) { + dc.PopScissor(); + } +} + +void CheckBox::Toggle(){ + if (toggle_) + *toggle_ = !(*toggle_); +}; + +EventReturn CheckBox::OnClicked(EventParams &e) { + Toggle(); + return EVENT_CONTINUE; // It's safe to keep processing events. +} + +void CheckBox::Draw(UIContext &dc) { + ClickableItem::Draw(dc); + int paddingX = 12; + + int image = *toggle_ ? dc.theme->checkOn : dc.theme->checkOff; + + Style style = dc.theme->itemStyle; + if (!IsEnabled()) + style = dc.theme->itemDisabledStyle; + + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawText(text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), style.fgColor, ALIGN_VCENTER); + dc.Draw()->DrawImage(image, bounds_.x2() - paddingX, bounds_.centerY(), 1.0f, style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); +} + +void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + if (imageID_ != -1) { + const AtlasImage *img = &dc.Draw()->GetAtlas()->images[imageID_]; + w = img->w; + h = img->h; + } else { + dc.MeasureText(dc.theme->uiFont, text_.c_str(), &w, &h); + } + // Add some internal padding to not look totally ugly + w += 16; + h += 8; +} + +void Button::Draw(UIContext &dc) { + Style style = dc.theme->buttonStyle; + + if (HasFocus()) style = dc.theme->buttonFocusedStyle; + if (down_) style = dc.theme->buttonDownStyle; + if (!IsEnabled()) style = dc.theme->buttonDisabledStyle; + + // dc.Draw()->DrawImage4Grid(style.image, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y2(), style.bgColor); + dc.FillRect(style.background, bounds_); + float tw, th; + dc.MeasureText(dc.theme->uiFont, text_.c_str(), &tw, &th); + if (tw > bounds_.w || imageID_ != -1) { + dc.PushScissor(bounds_); + } + dc.SetFontStyle(dc.theme->uiFont); + if (imageID_ != -1 && text_.empty()) { + dc.Draw()->DrawImage(imageID_, bounds_.centerX(), bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); + } else if (!text_.empty()) { + dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER); + if (imageID_ != -1) { + const AtlasImage &img = dc.Draw()->GetAtlas()->images[imageID_]; + dc.Draw()->DrawImage(imageID_, bounds_.centerX() - tw / 2 - 5 - img.w/2, bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); + } + } + if (tw > bounds_.w || imageID_ != -1) { + dc.PopScissor(); + } +} + +void ImageView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_]; + // TODO: involve sizemode + w = img.w; + h = img.h; +} + +void ImageView::Draw(UIContext &dc) { + const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_]; + // TODO: involve sizemode + float scale = bounds_.w / img.w; + dc.Draw()->DrawImage(atlasImage_, bounds_.x, bounds_.y, scale, 0xFFFFFFFF, ALIGN_TOPLEFT); +} + +void TextureView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + // TODO: involve sizemode + if (texture_) { + w = (float)texture_->Width(); + h = (float)texture_->Height(); + } else { + w = 16; + h = 16; + } +} + +void TextureView::Draw(UIContext &dc) { + // TODO: involve sizemode + if (texture_) { + dc.Flush(); + texture_->Bind(0); + dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_); + dc.Flush(); + dc.RebindTexture(); + } +} + +void Thin3DTextureView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + // TODO: involve sizemode + if (texture_) { + w = (float)texture_->Width(); + h = (float)texture_->Height(); + } else { + w = 16; + h = 16; + } +} + +void Thin3DTextureView::Draw(UIContext &dc) { + // TODO: involve sizemode + if (texture_) { + dc.Flush(); + dc.GetThin3DContext()->SetTexture(0, texture_); + dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_); + dc.Flush(); + dc.RebindTexture(); + } +} + +void TextView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + // MeasureText doesn't seem to work with line breaks, so do something more sophisticated. + std::vector lines; + SplitString(text_, '\n', lines); + float total_w = 0.f; + float total_h = 0.f; + for (size_t i = 0; i < lines.size(); i++) { + float temp_w, temp_h; + dc.MeasureText(small_ ? dc.theme->uiFontSmall : dc.theme->uiFont, lines[i].c_str(), &temp_w, &temp_h); + if (temp_w > total_w) + total_w = temp_w; + total_h += temp_h; + } + w = total_w; + h = total_h; +} + +void TextView::Draw(UIContext &dc) { + float w, h; + GetContentDimensions(dc, w, h); + bool clip = false; + if (w > bounds_.w || h > bounds_.h) + clip = true; + if (bounds_.w < 0 || bounds_.h < 0) { + // We have a layout but, but try not to screw up rendering. + // TODO: Fix properly. + clip = false; + } + if (clip) { + Bounds clipRect = bounds_.Expand(10); // TODO: Remove this hackery + dc.Flush(); + dc.PushScissor(clipRect); + } + // In case it's been made focusable. + if (HasFocus()) { + UI::Style style = dc.theme->itemFocusedStyle; + style.background.color &= 0x7fffffff; + dc.FillRect(style.background, bounds_); + } + dc.SetFontStyle(small_ ? dc.theme->uiFontSmall : dc.theme->uiFont); + if (shadow_) { + uint32_t shadowColor = 0x80000000; + dc.DrawTextRect(text_.c_str(), bounds_, shadowColor, textAlign_); + } + dc.DrawTextRect(text_.c_str(), bounds_, textColor_, textAlign_); + if (clip) { + dc.PopScissor(); + } +} + +TextEdit::TextEdit(const std::string &text, const std::string &placeholderText, LayoutParams *layoutParams) + : View(layoutParams), text_(text), undo_(text), placeholderText_(placeholderText), maxLen_(255), ctrlDown_(false) { + caret_ = (int)text_.size(); +} + +void TextEdit::Draw(UIContext &dc) { + dc.PushScissor(bounds_); + dc.SetFontStyle(dc.theme->uiFont); + dc.FillRect(HasFocus() ? UI::Drawable(0x80000000) : UI::Drawable(0x30000000), bounds_); + + float textX = bounds_.x; + float w, h; + + Bounds textBounds = bounds_; + textBounds.x = textX; + + if (text_.empty()) { + if (placeholderText_.size()) { + dc.DrawTextRect(placeholderText_.c_str(), bounds_, 0x50FFFFFF, ALIGN_CENTER); + } + } else { + dc.DrawTextRect(text_.c_str(), textBounds, 0xFFFFFFFF, ALIGN_VCENTER | ALIGN_LEFT); + } + + if (HasFocus()) { + // Hack to find the caret position. Might want to find a better way... + dc.MeasureTextCount(dc.theme->uiFont, text_.c_str(), caret_, &w, &h, ALIGN_VCENTER | ALIGN_LEFT); + float caretX = w; + caretX += textX; + + if (caretX > bounds_.w) { + // Scroll text to the left if the caret won't fit. Not ideal but looks better than not scrolling it. + textX -= caretX - bounds_.w; + } + dc.FillRect(UI::Drawable(0xFFFFFFFF), Bounds(caretX - 1, bounds_.y + 2, 3, bounds_.h - 4)); + } + dc.PopScissor(); +} + +void TextEdit::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + dc.MeasureText(dc.theme->uiFont, text_.size() ? text_.c_str() : "Wj", &w, &h); + w += 2; + h += 2; +} + +// Handles both windows and unix line endings. +static std::string FirstLine(const std::string &text) { + size_t pos = text.find("\r\n"); + if (pos != std::string::npos) { + return text.substr(0, pos); + } + pos = text.find('\n'); + if (pos != std::string::npos) { + return text.substr(0, pos); + } + return text; +} + +void TextEdit::Touch(const TouchInput &touch) { + if (touch.flags & TOUCH_DOWN) { + if (bounds_.Contains(touch.x, touch.y)) { + SetFocusedView(this, true); + } + } +} + +bool TextEdit::Key(const KeyInput &input) { + if (!HasFocus()) + return false; + bool textChanged = false; + // Process navigation keys. These aren't chars. + if (input.flags & KEY_DOWN) { + switch (input.keyCode) { + case NKCODE_CTRL_LEFT: + case NKCODE_CTRL_RIGHT: + ctrlDown_ = true; + break; + case NKCODE_DPAD_LEFT: // ASCII left arrow + u8_dec(text_.c_str(), &caret_); + break; + case NKCODE_DPAD_RIGHT: // ASCII right arrow + u8_inc(text_.c_str(), &caret_); + break; + case NKCODE_MOVE_HOME: + case NKCODE_PAGE_UP: + caret_ = 0; + break; + case NKCODE_MOVE_END: + case NKCODE_PAGE_DOWN: + caret_ = (int)text_.size(); + break; + case NKCODE_FORWARD_DEL: + if (caret_ < (int)text_.size()) { + int endCaret = caret_; + u8_inc(text_.c_str(), &endCaret); + undo_ = text_; + text_.erase(text_.begin() + caret_, text_.begin() + endCaret); + textChanged = true; + } + break; + case NKCODE_DEL: + if (caret_ > 0) { + int begCaret = caret_; + u8_dec(text_.c_str(), &begCaret); + undo_ = text_; + text_.erase(text_.begin() + begCaret, text_.begin() + caret_); + caret_--; + textChanged = true; + } + break; + case NKCODE_ENTER: + { + EventParams e; + e.s = text_; + OnEnter.Trigger(e); + break; + } + case NKCODE_BACK: + case NKCODE_ESCAPE: + return false; + } + + if (ctrlDown_) { + switch (input.keyCode) { + case NKCODE_C: + // Just copy the entire text contents, until we get selection support. + System_SendMessage("setclipboardtext", text_.c_str()); + break; + case NKCODE_V: + { + std::string clipText = System_GetProperty(SYSPROP_CLIPBOARD_TEXT); + clipText = FirstLine(clipText); + if (clipText.size()) { + // Until we get selection, replace the whole text + undo_ = text_; + text_.clear(); + caret_ = 0; + + size_t maxPaste = maxLen_ - text_.size(); + if (clipText.size() > maxPaste) { + int end = 0; + while ((size_t)end < maxPaste) { + u8_inc(clipText.c_str(), &end); + } + if (end > 0) { + u8_dec(clipText.c_str(), &end); + } + clipText = clipText.substr(0, end); + } + InsertAtCaret(clipText.c_str()); + textChanged = true; + } + } + break; + case NKCODE_Z: + text_ = undo_; + break; + } + } + + if (caret_ < 0) { + caret_ = 0; + } + if (caret_ > (int)text_.size()) { + caret_ = (int)text_.size(); + } + } + + if (input.flags & KEY_UP) { + switch (input.keyCode) { + case NKCODE_CTRL_LEFT: + case NKCODE_CTRL_RIGHT: + ctrlDown_ = false; + break; + } + } + + // Process chars. + if (input.flags & KEY_CHAR) { + int unichar = input.keyCode; + if (unichar >= 0x20 && !ctrlDown_) { // Ignore control characters. + // Insert it! (todo: do it with a string insert) + char buf[8]; + buf[u8_wc_toutf8(buf, unichar)] = '\0'; + if (strlen(buf) + text_.size() < maxLen_) { + undo_ = text_; + InsertAtCaret(buf); + textChanged = true; + } + } + } + + if (textChanged) { + UI::EventParams e; + e.v = this; + OnTextChange.Trigger(e); + } + return true; +} + +void TextEdit::InsertAtCaret(const char *text) { + size_t len = strlen(text); + for (size_t i = 0; i < len; i++) { + text_.insert(text_.begin() + caret_, text[i]); + caret_++; + } +} + +void ProgressBar::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + dc.MeasureText(dc.theme->uiFont, " 100% ", &w, &h); +} + +void ProgressBar::Draw(UIContext &dc) { + char temp[32]; + sprintf(temp, "%i%%", (int)(progress_ * 100.0f)); + dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x + bounds_.w * progress_, bounds_.y2(), 0xc0c0c0c0); + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawTextRect(temp, bounds_, 0xFFFFFFFF, ALIGN_CENTER); +} + +void TriggerButton::Touch(const TouchInput &input) { + if (input.flags & TOUCH_DOWN) { + if (bounds_.Contains(input.x, input.y)) { + down_ |= 1 << input.id; + } + } + if (input.flags & TOUCH_MOVE) { + if (bounds_.Contains(input.x, input.y)) + down_ |= 1 << input.id; + else + down_ &= ~(1 << input.id); + } + + if (input.flags & TOUCH_UP) { + down_ &= ~(1 << input.id); + } + + if (down_ != 0) { + *bitField_ |= bit_; + } else { + *bitField_ &= ~bit_; + } +} + +void TriggerButton::Draw(UIContext &dc) { + dc.Draw()->DrawImage(imageBackground_, bounds_.centerX(), bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); + dc.Draw()->DrawImage(imageForeground_, bounds_.centerX(), bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); +} + +void TriggerButton::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + const AtlasImage &image = dc.Draw()->GetAtlas()->images[imageBackground_]; + w = image.w; + h = image.h; +} + +bool Slider::Key(const KeyInput &input) { + if (HasFocus() && (input.flags & KEY_DOWN)) { + switch (input.keyCode) { + case NKCODE_DPAD_LEFT: + case NKCODE_MINUS: + case NKCODE_NUMPAD_SUBTRACT: + *value_ -= step_; + break; + case NKCODE_DPAD_RIGHT: + case NKCODE_PLUS: + case NKCODE_NUMPAD_ADD: + *value_ += step_; + break; + case NKCODE_PAGE_UP: + *value_ -= step_ * 10; + break; + case NKCODE_PAGE_DOWN: + *value_ += step_ * 10; + break; + case NKCODE_MOVE_HOME: + *value_ = minValue_; + break; + case NKCODE_MOVE_END: + *value_ = maxValue_; + break; + default: + return false; + } + Clamp(); + return true; + } else { + return false; + } +} + +void Slider::Touch(const TouchInput &input) { + Clickable::Touch(input); + if (dragging_ || bounds_.Contains(input.x, input.y)) { + float relativeX = (input.x - (bounds_.x + paddingLeft_)) / (bounds_.w - paddingLeft_ - paddingRight_); + *value_ = floorf(relativeX * (maxValue_ - minValue_) + minValue_ + 0.5f); + Clamp(); + } +} + +void Slider::Clamp() { + if (*value_ < minValue_) *value_ = minValue_; + else if (*value_ > maxValue_) *value_ = maxValue_; + + // Clamp the value to be a multiple of the nearest step (e.g. if step == 5, value == 293, it'll round down to 290). + *value_ = *value_ - fmodf(*value_, step_); +} + +void Slider::Draw(UIContext &dc) { + bool focus = HasFocus(); + uint32_t linecolor = dc.theme->popupTitle.fgColor; + uint32_t knobcolor = (down_ || focus) ? dc.theme->popupTitle.fgColor : 0xFFFFFFFF; + float knobX = ((float)(*value_) - minValue_) / (maxValue_ - minValue_) * (bounds_.w - paddingLeft_ - paddingRight_) + (bounds_.x + paddingLeft_); + dc.FillRect(Drawable(linecolor), Bounds(bounds_.x + paddingLeft_, bounds_.centerY() - 2, knobX - (bounds_.x + paddingLeft_), 4)); + dc.FillRect(Drawable(0xFF808080), Bounds(knobX, bounds_.centerY() - 2, (bounds_.x + bounds_.w - paddingRight_ - knobX), 4)); + dc.Draw()->DrawImage(dc.theme->sliderKnob, knobX, bounds_.centerY(), 1.0f, knobcolor, ALIGN_CENTER); + char temp[64]; + if (showPercent_) + sprintf(temp, "%i%%", *value_); + else + sprintf(temp, "%i", *value_); + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER); +} + +void Slider::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + // TODO + w = 100; + h = 50; +} + +bool SliderFloat::Key(const KeyInput &input) { + if (HasFocus() && (input.flags & KEY_DOWN)) { + switch (input.keyCode) { + case NKCODE_DPAD_LEFT: + case NKCODE_MINUS: + case NKCODE_NUMPAD_SUBTRACT: + *value_ -= (maxValue_ - minValue_) / 20.0f; + break; + case NKCODE_DPAD_RIGHT: + case NKCODE_PLUS: + case NKCODE_NUMPAD_ADD: + *value_ += (maxValue_ - minValue_) / 30.0f; + break; + case NKCODE_PAGE_UP: + *value_ -= (maxValue_ - minValue_) / 5.0f; + break; + case NKCODE_PAGE_DOWN: + *value_ += (maxValue_ - minValue_) / 5.0f; + break; + case NKCODE_MOVE_HOME: + *value_ = minValue_; + break; + case NKCODE_MOVE_END: + *value_ = maxValue_; + break; + default: + return true; + } + Clamp(); + return true; + } else { + return false; + } +} + +void SliderFloat::Touch(const TouchInput &input) { + if (dragging_ || bounds_.Contains(input.x, input.y)) { + float relativeX = (input.x - (bounds_.x + paddingLeft_)) / (bounds_.w - paddingLeft_ - paddingRight_); + *value_ = (relativeX * (maxValue_ - minValue_) + minValue_); + Clamp(); + } +} + +void SliderFloat::Clamp() { + if (*value_ < minValue_) + *value_ = minValue_; + else if (*value_ > maxValue_) + *value_ = maxValue_; +} + +void SliderFloat::Draw(UIContext &dc) { + bool focus = HasFocus(); + uint32_t linecolor = dc.theme->popupTitle.fgColor; + uint32_t knobcolor = (down_ || focus) ? dc.theme->popupTitle.fgColor : 0xFFFFFFFF; + + float knobX = (*value_ - minValue_) / (maxValue_ - minValue_) * (bounds_.w - paddingLeft_ - paddingRight_) + (bounds_.x + paddingLeft_); + dc.FillRect(Drawable(linecolor), Bounds(bounds_.x + paddingLeft_, bounds_.centerY() - 2, knobX - (bounds_.x + paddingLeft_), 4)); + dc.FillRect(Drawable(0xFF808080), Bounds(knobX, bounds_.centerY() - 2, (bounds_.x + bounds_.w - paddingRight_ - knobX), 4)); + dc.Draw()->DrawImage(dc.theme->sliderKnob, knobX, bounds_.centerY(), 1.0f, knobcolor, ALIGN_CENTER); + char temp[64]; + sprintf(temp, "%0.2f", *value_); + dc.SetFontStyle(dc.theme->uiFont); + dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER); +} + +void SliderFloat::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + // TODO + w = 100; + h = 50; +} + +} // namespace diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h new file mode 100644 index 0000000000..bd7f25e2e4 --- /dev/null +++ b/ext/native/ui/view.h @@ -0,0 +1,810 @@ +#pragma once + +// More traditional UI framework than ui/ui.h. + +// Still very simple to use. + +// Works very similarly to Android, there's a Measure pass and a Layout pass which you don't +// really need to care about if you just use the standard containers and widgets. + +#include +#include +#include +#include + +#include "base/logging.h" +#include "base/functional.h" +#include "base/mutex.h" +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "gfx/texture_atlas.h" +#include "math/lin/matrix4x4.h" +#include "math/math_util.h" +#include "math/geom2d.h" + +#undef small + +struct KeyInput; +struct TouchInput; +struct AxisInput; +struct InputState; + +class DrawBuffer; +class Texture; +class UIContext; + +class Thin3DTexture; + + +// I don't generally like namespaces but I think we do need one for UI, so many potentially-clashing names. +namespace UI { + +class View; + +// The ONLY global is the currently focused item. +// Can be and often is null. +void EnableFocusMovement(bool enable); +bool IsFocusMovementEnabled(); +View *GetFocusedView(); +void SetFocusedView(View *view, bool force = false); + +enum DrawableType { + DRAW_NOTHING, + DRAW_SOLID_COLOR, + DRAW_4GRID, + DRAW_STRETCH_IMAGE, +}; + +enum Visibility { + V_VISIBLE, + V_INVISIBLE, // Keeps position, not drawn or interacted with + V_GONE, // Does not participate in layout +}; + +struct Drawable { + Drawable() : type(DRAW_NOTHING), image(-1), color(0xFFFFFFFF) {} + explicit Drawable(uint32_t col) : type(DRAW_SOLID_COLOR), image(-1), color(col) {} + Drawable(DrawableType t, int img, uint32_t col = 0xFFFFFFFF) : type(t), image(img), color(col) {} + + DrawableType type; + uint32_t image; + uint32_t color; +}; + +struct Style { + Style() : fgColor(0xFFFFFFFF), background(0xFF303030), image(-1) {} + + uint32_t fgColor; + Drawable background; + int image; // where applicable. +}; + +struct FontStyle { + FontStyle() : atlasFont(0), sizePts(0), flags(0) {} + FontStyle(const char *name, int size) : atlasFont(0), fontName(name), sizePts(size), flags(0) {} + FontStyle(int atlasFnt, const char *name, int size) : atlasFont(atlasFnt), fontName(name), sizePts(size), flags(0) {} + + int atlasFont; + // For native fonts: + std::string fontName; + int sizePts; + int flags; +}; + + +// To use with an UI atlas. +struct Theme { + FontStyle uiFont; + FontStyle uiFontSmall; + FontStyle uiFontSmaller; + int checkOn; + int checkOff; + int sliderKnob; + int whiteImage; + int dropShadow4Grid; + + Style buttonStyle; + Style buttonFocusedStyle; + Style buttonDownStyle; + Style buttonDisabledStyle; + Style buttonHighlightedStyle; + + Style itemStyle; + Style itemDownStyle; + Style itemFocusedStyle; + Style itemDisabledStyle; + Style itemHighlightedStyle; + + Style headerStyle; + + Style popupTitle; +}; + +// The four cardinal directions should be enough, plus Prev/Next in "element order". +enum FocusDirection { + FOCUS_UP, + FOCUS_DOWN, + FOCUS_LEFT, + FOCUS_RIGHT, + FOCUS_NEXT, + FOCUS_PREV, +}; + +enum { + WRAP_CONTENT = -1, + FILL_PARENT = -2, +}; + +// Gravity +enum Gravity { + G_LEFT = 0, + G_RIGHT = 1, + G_HCENTER = 2, + + G_HORIZMASK = 3, + + G_TOP = 0, + G_BOTTOM = 4, + G_VCENTER = 8, + + G_TOPLEFT = G_TOP | G_LEFT, + G_TOPRIGHT = G_TOP | G_RIGHT, + + G_BOTTOMLEFT = G_BOTTOM | G_LEFT, + G_BOTTOMRIGHT = G_BOTTOM | G_RIGHT, + + G_CENTER = G_HCENTER | G_VCENTER, + + G_VERTMASK = 3 << 2, +}; + +typedef float Size; // can also be WRAP_CONTENT or FILL_PARENT. + +enum Orientation { + ORIENT_HORIZONTAL, + ORIENT_VERTICAL, +}; + +inline Orientation Opposite(Orientation o) { + if (o == ORIENT_HORIZONTAL) return ORIENT_VERTICAL; else return ORIENT_HORIZONTAL; +} + +inline FocusDirection Opposite(FocusDirection d) { + switch (d) { + case FOCUS_UP: return FOCUS_DOWN; + case FOCUS_DOWN: return FOCUS_UP; + case FOCUS_LEFT: return FOCUS_RIGHT; + case FOCUS_RIGHT: return FOCUS_LEFT; + case FOCUS_PREV: return FOCUS_NEXT; + case FOCUS_NEXT: return FOCUS_PREV; + } + return d; +} + +enum MeasureSpecType { + UNSPECIFIED, + EXACTLY, + AT_MOST, +}; + +// I hope I can find a way to simplify this one day. +enum EventReturn { + EVENT_DONE, // Return this when no other view may process this event, for example if you changed the view hierarchy + EVENT_SKIPPED, // Return this if you ignored an event + EVENT_CONTINUE, // Return this if it's safe to send this event to further listeners. This should normally be the default choice but often EVENT_DONE is necessary. +}; + +enum FocusFlags { + FF_LOSTFOCUS = 1, + FF_GOTFOCUS = 2 +}; + +class ViewGroup; + +void Fill(UIContext &dc, const Bounds &bounds, const Drawable &drawable); + +struct MeasureSpec { + MeasureSpec(MeasureSpecType t, float s = 0.0f) : type(t), size(s) {} + MeasureSpec() : type(UNSPECIFIED), size(0) {} + + MeasureSpec operator -(float amount) { + // TODO: Check type + return MeasureSpec(type, size - amount); + } + MeasureSpecType type; + float size; +}; + +class View; + + +// Should cover all bases. +struct EventParams { + View *v; + uint32_t a, b, x, y; + float f; + std::string s; +}; + +struct HandlerRegistration { + std::function func; +}; + +class Event { +public: + Event() {} + ~Event() { + handlers_.clear(); + } + // Call this from input thread or whatever, it doesn't matter + void Trigger(EventParams &e); + // Call this from UI thread + EventReturn Dispatch(EventParams &e); + + // This is suggested for use in most cases. Autobinds, allowing for neat syntax. + template + T *Handle(T *thiz, EventReturn (T::* theCallback)(EventParams &e)) { + Add(std::bind(theCallback, thiz, placeholder::_1)); + return thiz; + } + + // Sometimes you have an already-bound function<>, just use this then. + void Add(std::function func); + +private: + std::vector handlers_; + DISALLOW_COPY_AND_ASSIGN(Event); +}; + +struct Margins { + Margins() : top(0), bottom(0), left(0), right(0) {} + explicit Margins(int8_t all) : top(all), bottom(all), left(all), right(all) {} + Margins(int8_t horiz, int8_t vert) : top(vert), bottom(vert), left(horiz), right(horiz) {} + Margins(int8_t l, int8_t t, int8_t r, int8_t b) : top(t), bottom(b), left(l), right(r) {} + + int8_t top; + int8_t bottom; + int8_t left; + int8_t right; +}; + +enum LayoutParamsType { + LP_PLAIN = 0, + LP_LINEAR = 1, + LP_ANCHOR = 2, +}; + +// Need a virtual destructor so vtables are created, otherwise RTTI can't work +class LayoutParams { +public: + LayoutParams(LayoutParamsType type = LP_PLAIN) + : width(WRAP_CONTENT), height(WRAP_CONTENT), type_(type) {} + LayoutParams(Size w, Size h, LayoutParamsType type = LP_PLAIN) + : width(w), height(h), type_(type) {} + virtual ~LayoutParams() {} + Size width; + Size height; + + // Fake RTTI + bool Is(LayoutParamsType type) const { return type_ == type; } + +private: + LayoutParamsType type_; +}; + +View *GetFocusedView(); + +class View { +public: + View(LayoutParams *layoutParams = 0) : layoutParams_(layoutParams), visibility_(V_VISIBLE), measuredWidth_(0), measuredHeight_(0), enabledPtr_(0), enabled_(true), enabledMeansDisabled_(false) { + if (!layoutParams) + layoutParams_.reset(new LayoutParams()); + } + virtual ~View(); + + // Please note that Touch is called ENTIRELY asynchronously from drawing! + // Can even be called on a different thread! This is to really minimize latency, and decouple + // touch response from the frame rate. Same with Key and Axis. + virtual bool Key(const KeyInput &input) { return false; } + virtual void Touch(const TouchInput &input) {} + virtual void Axis(const AxisInput &input) {} + virtual void Update(const InputState &input_state) {} + + virtual void FocusChanged(int focusFlags) {} + + void Move(Bounds bounds) { + bounds_ = bounds; + } + + // Views don't do anything here in Layout, only containers implement this. + virtual void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert); + virtual void Layout() {} + virtual void Draw(UIContext &dc) {} + + virtual float GetMeasuredWidth() const { return measuredWidth_; } + virtual float GetMeasuredHeight() const { return measuredHeight_; } + + // Override this for easy standard behaviour. No need to override Measure. + virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const; + + // Called when the layout is done. + void SetBounds(Bounds bounds) { bounds_ = bounds; } + virtual const LayoutParams *GetLayoutParams() const { return layoutParams_.get(); } + virtual void ReplaceLayoutParams(LayoutParams *newLayoutParams) { layoutParams_.reset(newLayoutParams); } + const Bounds &GetBounds() const { return bounds_; } + + virtual bool SetFocus(); + + virtual bool CanBeFocused() const { return true; } + virtual bool SubviewFocused(View *view) { return false; } + bool HasFocus() const { + return GetFocusedView() == this; + } + + void SetEnabled(bool enabled) { enabled_ = enabled; enabledMeansDisabled_ = false; } + bool IsEnabled() const { + if (enabledPtr_) + return *enabledPtr_ != enabledMeansDisabled_; + else + return enabled_ != enabledMeansDisabled_; + } + void SetEnabledPtr(bool *enabled) { enabledPtr_ = enabled; enabledMeansDisabled_ = false; } + void SetDisabledPtr(bool *disabled) { enabledPtr_ = disabled; enabledMeansDisabled_ = true; } + + void SetVisibility(Visibility visibility) { visibility_ = visibility; } + Visibility GetVisibility() const { return visibility_; } + + const std::string &Tag() const { return tag_; } + void SetTag(const std::string &str) { tag_ = str; } + + // Fake RTTI + virtual bool IsViewGroup() const { return false; } + + Point GetFocusPosition(FocusDirection dir); + +protected: + // Inputs to layout + scoped_ptr layoutParams_; + + std::string tag_; + Visibility visibility_; + + // Results of measure pass. Set these in Measure. + float measuredWidth_; + float measuredHeight_; + + // Outputs of layout. X/Y are absolute screen coordinates, hierarchy is "gone" here. + Bounds bounds_; + + scoped_ptr transform_; + +private: + bool *enabledPtr_; + bool enabled_; + bool enabledMeansDisabled_; + + DISALLOW_COPY_AND_ASSIGN(View); +}; + +// These don't do anything when touched. +class InertView : public View { +public: + InertView(LayoutParams *layoutParams) + : View(layoutParams) {} + + bool Key(const KeyInput &input) override { return false; } + void Touch(const TouchInput &input) override {} + bool CanBeFocused() const override { return false; } + void Update(const InputState &input_state) override {} +}; + + +// All these light up their background when touched, or have focus. +class Clickable : public View { +public: + Clickable(LayoutParams *layoutParams) + : View(layoutParams), downCountDown_(0), dragging_(false), down_(false){} + + bool Key(const KeyInput &input) override; + void Touch(const TouchInput &input) override; + + void FocusChanged(int focusFlags) override; + + Event OnClick; + +protected: + // Internal method that fires on a click. Default behaviour is to trigger + // the event. + // Use it for checking/unchecking checkboxes, etc. + virtual void Click(); + + int downCountDown_; + bool dragging_; + bool down_; +}; + +class Button : public Clickable { +public: + Button(const std::string &text, LayoutParams *layoutParams = 0) + : Clickable(layoutParams), text_(text), imageID_(-1) {} + Button(ImageID imageID, LayoutParams *layoutParams = 0) + : Clickable(layoutParams), imageID_(imageID) {} + Button(const std::string &text, ImageID imageID, LayoutParams *layoutParams = 0) + : Clickable(layoutParams), text_(text), imageID_(imageID) {} + + void Draw(UIContext &dc) override; + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + const std::string &GetText() const { return text_; } + +private: + Style style_; + std::string text_; + ImageID imageID_; +}; + +class Slider : public Clickable { +public: + Slider(int *value, int minValue, int maxValue, LayoutParams *layoutParams = 0) + : Clickable(layoutParams), value_(value), showPercent_(false), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70), step_(1) {} + + Slider(int *value, int minValue, int maxValue, int step = 1, LayoutParams *layoutParams = 0) + : Clickable(layoutParams), value_(value), showPercent_(false), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70) { + step_ = step <= 0 ? 1 : step; + } + void Draw(UIContext &dc) override; + bool Key(const KeyInput &input) override; + void Touch(const TouchInput &input) override; + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void SetShowPercent(bool s) { showPercent_ = s; } + + // OK to call this from the outside after having modified *value_ + void Clamp(); + +private: + int *value_; + bool showPercent_; + int minValue_; + int maxValue_; + float paddingLeft_; + float paddingRight_; + int step_; +}; + +class SliderFloat : public Clickable { +public: + SliderFloat(float *value, float minValue, float maxValue, LayoutParams *layoutParams = 0) + : Clickable(layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70) {} + void Draw(UIContext &dc) override; + bool Key(const KeyInput &input) override; + void Touch(const TouchInput &input) override; + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + + // OK to call this from the outside after having modified *value_ + void Clamp(); +private: + float *value_; + float minValue_; + float maxValue_; + float paddingLeft_; + float paddingRight_; +}; + +// Basic button that modifies a bitfield based on the pressed status. Supports multitouch. +// Suitable for controller simulation (ABXY etc). +class TriggerButton : public View { +public: + TriggerButton(uint32_t *bitField, uint32_t bit, int imageBackground, int imageForeground, LayoutParams *layoutParams) + : View(layoutParams), down_(0.0), bitField_(bitField), bit_(bit), imageBackground_(imageBackground), imageForeground_(imageForeground) {} + + void Touch(const TouchInput &input) override; + void Draw(UIContext &dc) override; + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + +private: + int down_; // bitfield of pressed fingers, translates into bitField + + uint32_t *bitField_; + uint32_t bit_; + + int imageBackground_; + int imageForeground_; +}; + + +// The following classes are mostly suitable as items in ListView which +// really is just a LinearLayout in a ScrollView, possibly with some special optimizations. + +class Item : public InertView { +public: + Item(LayoutParams *layoutParams); + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; +}; + +class ClickableItem : public Clickable { +public: + ClickableItem(LayoutParams *layoutParams); + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + + // Draws the item background. + void Draw(UIContext &dc) override; +}; + +// Use to trigger something or open a submenu screen. +class Choice : public ClickableItem { +public: + Choice(const std::string &text, LayoutParams *layoutParams = 0) + : ClickableItem(layoutParams), text_(text), smallText_(), atlasImage_(-1), iconImage_(-1), centered_(false), highlighted_(false), selected_(false) {} + Choice(const std::string &text, const std::string &smallText, bool selected = false, LayoutParams *layoutParams = 0) + : ClickableItem(layoutParams), text_(text), smallText_(smallText), atlasImage_(-1), iconImage_(-1), centered_(false), highlighted_(false), selected_(selected) {} + Choice(ImageID image, LayoutParams *layoutParams = 0) + : ClickableItem(layoutParams), atlasImage_(image), iconImage_(-1), centered_(false), highlighted_(false), selected_(false) {} + + virtual void HighlightChanged(bool highlighted); + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void Draw(UIContext &dc) override; + virtual void SetCentered(bool c) { + centered_ = c; + } + virtual void SetIcon(ImageID iconImage) { + iconImage_ = iconImage; + } + +protected: + // hackery + virtual bool IsSticky() const { return false; } + + int height_; + std::string text_; + std::string smallText_; + ImageID atlasImage_; + ImageID iconImage_; // Only applies for text, non-centered + bool centered_; + bool highlighted_; + +private: + bool selected_; +}; + +// Different key handling. +class StickyChoice : public Choice { +public: + StickyChoice(const std::string &text, const std::string &smallText = "", LayoutParams *layoutParams = 0) + : Choice(text, smallText, false, layoutParams) {} + StickyChoice(ImageID buttonImage, LayoutParams *layoutParams = 0) + : Choice(buttonImage, layoutParams) {} + + bool Key(const KeyInput &key) override; + void Touch(const TouchInput &touch) override; + void FocusChanged(int focusFlags) override; + + void Press() { down_ = true; dragging_ = false; } + void Release() { down_ = false; dragging_ = false; } + bool IsDown() { return down_; } + +protected: + // hackery + virtual bool IsSticky() const { return true; } +}; + +class InfoItem : public Item { +public: + InfoItem(const std::string &text, const std::string &rightText, LayoutParams *layoutParams = 0) + : Item(layoutParams), text_(text), rightText_(rightText) {} + + void Draw(UIContext &dc) override; + + // These are focusable so that long lists of them can be keyboard scrolled. + bool CanBeFocused() const override { return true; } + + void SetText(const std::string &text) { + text_ = text; + } + void SetRightText(const std::string &text) { + rightText_ = text; + } + +private: + std::string text_; + std::string rightText_; +}; + +class ItemHeader : public Item { +public: + ItemHeader(const std::string &text, LayoutParams *layoutParams = 0); + void Draw(UIContext &dc) override; + +private: + std::string text_; +}; + +class PopupHeader : public Item { +public: + PopupHeader(const std::string &text, LayoutParams *layoutParams = 0) + : Item(layoutParams), text_(text) { + layoutParams_->width = FILL_PARENT; + layoutParams_->height = 64; + } + void Draw(UIContext &dc) override; +private: + std::string text_; +}; + +class CheckBox : public ClickableItem { +public: + CheckBox(bool *toggle, const std::string &text, const std::string &smallText = "", LayoutParams *layoutParams = 0) + : ClickableItem(layoutParams), toggle_(toggle), text_(text), smallText_(smallText) { + OnClick.Handle(this, &CheckBox::OnClicked); + } + + void Draw(UIContext &dc) override; + + EventReturn OnClicked(EventParams &e); + //allow external agents to toggle the checkbox + void Toggle(); +private: + bool *toggle_; + std::string text_; + std::string smallText_; +}; + +// These are for generic use. + +class Spacer : public InertView { +public: + Spacer(LayoutParams *layoutParams = 0) + : InertView(layoutParams), size_(0.0f) {} + Spacer(float size, LayoutParams *layoutParams = 0) + : InertView(layoutParams), size_(size) {} + virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const { + w = size_; h = size_; + } + void Draw(UIContext &dc) override {} +private: + float size_; +}; + +class TextView : public InertView { +public: + TextView(const std::string &text, LayoutParams *layoutParams = 0) + : InertView(layoutParams), text_(text), textAlign_(0), textColor_(0xFFFFFFFF), small_(false), shadow_(false), focusable_(false) {} + + TextView(const std::string &text, int textAlign, bool small, LayoutParams *layoutParams = 0) + : InertView(layoutParams), text_(text), textAlign_(textAlign), textColor_(0xFFFFFFFF), small_(small), shadow_(false), focusable_(false) {} + + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void Draw(UIContext &dc) override; + + void SetText(const std::string &text) { text_ = text; } + void SetSmall(bool small) { small_ = small; } + void SetTextColor(uint32_t color) { textColor_ = color; } + void SetShadow(bool shadow) { shadow_ = shadow; } + void SetFocusable(bool focusable) { focusable_ = focusable; } + + bool CanBeFocused() const override { return focusable_; } + +private: + std::string text_; + int textAlign_; + uint32_t textColor_; + bool small_; + bool shadow_; + bool focusable_; +}; + +class TextEdit : public View { +public: + TextEdit(const std::string &text, const std::string &placeholderText, LayoutParams *layoutParams = 0); + void SetText(const std::string &text) { text_ = text; caret_ = (int)text_.size(); } + const std::string &GetText() const { return text_; } + void SetMaxLen(size_t maxLen) { maxLen_ = maxLen; } + + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void Draw(UIContext &dc) override; + bool Key(const KeyInput &key) override; + void Touch(const TouchInput &touch) override; + + Event OnTextChange; + Event OnEnter; + +private: + void InsertAtCaret(const char *text); + + std::string text_; + std::string undo_; + std::string placeholderText_; + int caret_; + size_t maxLen_; + bool ctrlDown_; // TODO: Make some global mechanism for this. + // TODO: Selections +}; + +enum ImageSizeMode { + IS_DEFAULT, + IS_FIXED, +}; + +class ImageView : public InertView { +public: + ImageView(int atlasImage, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0) + : InertView(layoutParams), atlasImage_(atlasImage), sizeMode_(sizeMode) {} + + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void Draw(UIContext &dc) override; + +private: + int atlasImage_; + ImageSizeMode sizeMode_; +}; + +// TextureView takes a texture that is assumed to be alive during the lifetime +// of the view. +class TextureView : public InertView { +public: + TextureView(Texture *texture, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0) + : InertView(layoutParams), texture_(texture), sizeMode_(sizeMode) {} + + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void Draw(UIContext &dc) override; + + void SetTexture(Texture *texture) { texture_ = texture; } + void SetColor(uint32_t color) { color_ = color; } + +private: + Texture *texture_; + uint32_t color_; + ImageSizeMode sizeMode_; +}; + +// TextureView takes a texture that is assumed to be alive during the lifetime +// of the view. +class Thin3DTextureView : public InertView { +public: + Thin3DTextureView(Thin3DTexture *texture, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0) + : InertView(layoutParams), texture_(texture), color_(0xFFFFFFFF), sizeMode_(sizeMode) {} + + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void Draw(UIContext &dc) override; + + void SetTexture(Thin3DTexture *texture) { texture_ = texture; } + void SetColor(uint32_t color) { color_ = color; } + +private: + Thin3DTexture *texture_; + uint32_t color_; + ImageSizeMode sizeMode_; +}; + +class ProgressBar : public InertView { +public: + ProgressBar(LayoutParams *layoutParams = 0) + : InertView(layoutParams), progress_(0.0) {} + + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void Draw(UIContext &dc) override; + + void SetProgress(float progress) { + if (progress > 1.0f) { + progress_ = 1.0f; + } else if (progress < 0.0f) { + progress_ = 0.0f; + } else { + progress_ = progress; + } + } + float GetProgress() const { return progress_; } + +private: + float progress_; +}; + +void MeasureBySpec(Size sz, float contentWidth, MeasureSpec spec, float *measured); + +void EventTriggered(Event *e, EventParams params); +void DispatchEvents(); +bool IsDPadKey(const KeyInput &key); +bool IsAcceptKey(const KeyInput &key); +bool IsEscapeKey(const KeyInput &key); +bool IsTabLeftKey(const KeyInput &key); +bool IsTabRightKey(const KeyInput &key); + +} // namespace diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp new file mode 100644 index 0000000000..60b75dc968 --- /dev/null +++ b/ext/native/ui/viewgroup.cpp @@ -0,0 +1,1318 @@ +#include + +#include "base/functional.h" +#include "base/logging.h" +#include "base/mutex.h" +#include "base/timeutil.h" +#include "input/keycodes.h" +#include "ui/ui_context.h" +#include "ui/view.h" +#include "ui/viewgroup.h" +#include "gfx_es2/draw_buffer.h" + +#include + +namespace UI { + +const float ITEM_HEIGHT = 64.f; + +static recursive_mutex focusLock; +static std::vector focusMoves; +extern bool focusForced; +bool dragCaptured[MAX_POINTERS]; + +void CaptureDrag(int id) { + dragCaptured[id] = true; +} + +void ReleaseDrag(int id) { + dragCaptured[id] = false; +} + +bool IsDragCaptured(int id) { + return dragCaptured[id]; +} + +void ApplyGravity(const Bounds outer, const Margins &margins, float w, float h, int gravity, Bounds &inner) { + inner.w = w - (margins.left + margins.right); + inner.h = h - (margins.right + margins.left); + + switch (gravity & G_HORIZMASK) { + case G_LEFT: inner.x = outer.x + margins.left; break; + case G_RIGHT: inner.x = outer.x + outer.w - w - margins.right; break; + case G_HCENTER: inner.x = outer.x + (outer.w - w) / 2; break; + } + + switch (gravity & G_VERTMASK) { + case G_TOP: inner.y = outer.y + margins.top; break; + case G_BOTTOM: inner.y = outer.y + outer.h - h - margins.bottom; break; + case G_VCENTER: inner.y = outer.y + (outer.h - h) / 2; break; + } +} + +ViewGroup::~ViewGroup() { + // Tear down the contents recursively. + Clear(); +} + +void ViewGroup::RemoveSubview(View *view) { + lock_guard guard(modifyLock_); + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i] == view) { + views_.erase(views_.begin() + i); + delete view; + return; + } + } +} + +void ViewGroup::Clear() { + lock_guard guard(modifyLock_); + for (size_t i = 0; i < views_.size(); i++) { + delete views_[i]; + views_[i] = 0; + } + views_.clear(); +} + +void ViewGroup::Touch(const TouchInput &input) { + lock_guard guard(modifyLock_); + for (auto iter = views_.begin(); iter != views_.end(); ++iter) { + // TODO: If there is a transformation active, transform input coordinates accordingly. + if ((*iter)->GetVisibility() == V_VISIBLE) + (*iter)->Touch(input); + } +} + +bool ViewGroup::Key(const KeyInput &input) { + lock_guard guard(modifyLock_); + bool ret = false; + for (auto iter = views_.begin(); iter != views_.end(); ++iter) { + // TODO: If there is a transformation active, transform input coordinates accordingly. + if ((*iter)->GetVisibility() == V_VISIBLE) + ret = ret || (*iter)->Key(input); + } + return ret; +} + +void ViewGroup::Axis(const AxisInput &input) { + lock_guard guard(modifyLock_); + for (auto iter = views_.begin(); iter != views_.end(); ++iter) { + // TODO: If there is a transformation active, transform input coordinates accordingly. + if ((*iter)->GetVisibility() == V_VISIBLE) + (*iter)->Axis(input); + } +} + +void ViewGroup::Draw(UIContext &dc) { + if (hasDropShadow_) { + // Darken things behind. + dc.FillRect(UI::Drawable(0x60000000), dc.GetBounds()); + float dropsize = 30; + dc.Draw()->DrawImage4Grid(dc.theme->dropShadow4Grid, + bounds_.x - dropsize, bounds_.y, + bounds_.x2() + dropsize, bounds_.y2()+dropsize*1.5, 0xDF000000, 3.0f); + } + + if (clip_) { + dc.PushScissor(bounds_); + } + + dc.FillRect(bg_, bounds_); + for (auto iter = views_.begin(); iter != views_.end(); ++iter) { + // TODO: If there is a transformation active, transform input coordinates accordingly. + if ((*iter)->GetVisibility() == V_VISIBLE) { + // Check if bounds are in current scissor rectangle. + if (dc.GetScissorBounds().Intersects((*iter)->GetBounds())) + (*iter)->Draw(dc); + } + } + if (clip_) { + dc.PopScissor(); + } +} + +void ViewGroup::Update(const InputState &input_state) { + for (auto iter = views_.begin(); iter != views_.end(); ++iter) { + // TODO: If there is a transformation active, transform input coordinates accordingly. + if ((*iter)->GetVisibility() != V_GONE) + (*iter)->Update(input_state); + } +} + +bool ViewGroup::SetFocus() { + lock_guard guard(modifyLock_); + if (!CanBeFocused() && !views_.empty()) { + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i]->SetFocus()) + return true; + } + } + return false; +} + +bool ViewGroup::SubviewFocused(View *view) { + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i] == view) + return true; + if (views_[i]->SubviewFocused(view)) + return true; + } + return false; +} + +static float HorizontalOverlap(const Bounds &a, const Bounds &b) { + if (a.x2() < b.x || b.x2() < a.x) + return 0.0f; + // okay they do overlap. Let's clip. + float maxMin = std::max(a.x, b.x); + float minMax = std::min(a.x2(), b.x2()); + float overlap = minMax - maxMin; + if (overlap < 0.0f) + return 0.0f; + else + return std::min(1.0f, overlap / std::min(a.w, b.w)); +} + +// Returns the percentage the smaller one overlaps the bigger one. +static float VerticalOverlap(const Bounds &a, const Bounds &b) { + if (a.y2() < b.y || b.y2() < a.y) + return 0.0f; + // okay they do overlap. Let's clip. + float maxMin = std::max(a.y, b.y); + float minMax = std::min(a.y2(), b.y2()); + float overlap = minMax - maxMin; + if (overlap < 0.0f) + return 0.0f; + else + return std::min(1.0f, overlap / std::min(a.h, b.h)); +} + +float GetDirectionScore(View *origin, View *destination, FocusDirection direction) { + // Skip labels and things like that. + if (!destination->CanBeFocused()) + return 0.0f; + if (destination->IsEnabled() == false) + return 0.0f; + if (destination->GetVisibility() != V_VISIBLE) + return 0.0f; + + Point originPos = origin->GetFocusPosition(direction); + Point destPos = destination->GetFocusPosition(Opposite(direction)); + + float dx = destPos.x - originPos.x; + float dy = destPos.y - originPos.y; + + float distance = sqrtf(dx*dx + dy*dy); + float overlap = 0.0f; + float dirX = dx / distance; + float dirY = dy / distance; + + bool wrongDirection = false; + bool vertical = false; + float horizOverlap = HorizontalOverlap(origin->GetBounds(), destination->GetBounds()); + float vertOverlap = VerticalOverlap(origin->GetBounds(), destination->GetBounds()); + if (horizOverlap == 1.0f && vertOverlap == 1.0f) { + ILOG("Contain overlap"); + return 0.0; + } + float originSize = 0.0f; + switch (direction) { + case FOCUS_LEFT: + overlap = vertOverlap; + originSize = origin->GetBounds().w; + if (dirX > 0.0f) { + wrongDirection = true; + } + break; + case FOCUS_UP: + overlap = horizOverlap; + originSize = origin->GetBounds().h; + if (dirY > 0.0f) { + wrongDirection = true; + } + vertical = true; + break; + case FOCUS_RIGHT: + overlap = vertOverlap; + originSize = origin->GetBounds().w; + if (dirX < 0.0f) { + wrongDirection = true; + } + break; + case FOCUS_DOWN: + overlap = horizOverlap; + originSize = origin->GetBounds().h; + if (dirY < 0.0f) { + wrongDirection = true; + } + vertical = true; + break; + case FOCUS_PREV: + case FOCUS_NEXT: + ELOG("Invalid focus direction"); + break; + } + + // Add a small bonus if the views are the same size. This prioritizes moving to the next item + // upwards in a scroll view instead of moving up to the top bar. + float distanceBonus = 0.0f; + if (vertical) { + float widthDifference = origin->GetBounds().w - destination->GetBounds().w; + if (widthDifference == 0) { + distanceBonus = 40; + } + } else { + float heightDifference = origin->GetBounds().h - destination->GetBounds().h; + if (heightDifference == 0) { + distanceBonus = 40; + } + } + + // At large distances, ignore overlap. + if (distance > 2 * originSize) + overlap = 0; + + if (wrongDirection) + return 0.0f; + else + return 10.0f / std::max(1.0f, distance - distanceBonus) + overlap; +} + +NeighborResult ViewGroup::FindNeighbor(View *view, FocusDirection direction, NeighborResult result) { + if (!IsEnabled()) + return result; + if (GetVisibility() != V_VISIBLE) + return result; + + // First, find the position of the view in the list. + int num = -1; + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i] == view) { + num = (int)i; + break; + } + } + + // TODO: Do the cardinal directions right. Now we just map to + // prev/next. + + switch (direction) { + case FOCUS_PREV: + // If view not found, no neighbor to find. + if (num == -1) + return NeighborResult(0, 0.0f); + return NeighborResult(views_[(num + views_.size() - 1) % views_.size()], 0.0f); + + case FOCUS_NEXT: + // If view not found, no neighbor to find. + if (num == -1) + return NeighborResult(0, 0.0f); + return NeighborResult(views_[(num + 1) % views_.size()], 0.0f); + + case FOCUS_UP: + case FOCUS_LEFT: + case FOCUS_RIGHT: + case FOCUS_DOWN: + { + // First, try the child views themselves as candidates + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i] == view) + continue; + + float score = GetDirectionScore(view, views_[i], direction); + if (score > result.score) { + result.score = score; + result.view = views_[i]; + } + } + + // Then go right ahead and see if any of the children contain any better candidates. + for (auto iter = views_.begin(); iter != views_.end(); ++iter) { + if ((*iter)->IsViewGroup()) { + ViewGroup *vg = static_cast(*iter); + if (vg) + result = vg->FindNeighbor(view, direction, result); + } + } + + // Boost neighbors with the same parent + if (num != -1) { + //result.score += 100.0f; + } + + return result; + } + + default: + return result; + } +} + +void MoveFocus(ViewGroup *root, FocusDirection direction) { + if (!GetFocusedView()) { + // Nothing was focused when we got in here. Focus the first non-group in the hierarchy. + root->SetFocus(); + return; + } + + NeighborResult neigh(0, 0); + neigh = root->FindNeighbor(GetFocusedView(), direction, neigh); + + if (neigh.view) { + neigh.view->SetFocus(); + root->SubviewFocused(neigh.view); + } +} + +// TODO: This code needs some cleanup/restructuring... +void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { + MeasureBySpec(layoutParams_->width, 0.0f, horiz, &measuredWidth_); + MeasureBySpec(layoutParams_->height, 0.0f, vert, &measuredHeight_); + + if (views_.empty()) + return; + + float sum = 0.0f; + float maxOther = 0.0f; + float totalWeight = 0.0f; + float weightSum = 0.0f; + float weightZeroSum = 0.0f; + + int numVisible = 0; + + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i]->GetVisibility() == V_GONE) + continue; + numVisible++; + + const LayoutParams *layoutParams = views_[i]->GetLayoutParams(); + const LinearLayoutParams *linLayoutParams = static_cast(layoutParams); + if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + + Margins margins = defaultMargins_; + + if (linLayoutParams) { + totalWeight += linLayoutParams->weight; + if (linLayoutParams->HasMargins()) + margins = linLayoutParams->margins; + } + + if (orientation_ == ORIENT_HORIZONTAL) { + MeasureSpec v = vert; + if (v.type == UNSPECIFIED && measuredHeight_ != 0.0) + v = MeasureSpec(AT_MOST, measuredHeight_); + views_[i]->Measure(dc, MeasureSpec(UNSPECIFIED, measuredWidth_), v - (float)(margins.top + margins.bottom)); + } else if (orientation_ == ORIENT_VERTICAL) { + MeasureSpec h = horiz; + if (h.type == UNSPECIFIED && measuredWidth_ != 0) h = MeasureSpec(AT_MOST, measuredWidth_); + views_[i]->Measure(dc, h - (float)(margins.left + margins.right), MeasureSpec(UNSPECIFIED, measuredHeight_)); + } + + float amount; + if (orientation_ == ORIENT_HORIZONTAL) { + amount = views_[i]->GetMeasuredWidth() + margins.left + margins.right; + maxOther = std::max(maxOther, views_[i]->GetMeasuredHeight() + margins.top + margins.bottom); + } else { + amount = views_[i]->GetMeasuredHeight() + margins.top + margins.bottom; + maxOther = std::max(maxOther, views_[i]->GetMeasuredWidth() + margins.left + margins.right); + } + + sum += amount; + if (linLayoutParams) { + if (linLayoutParams->weight == 0.0f) + weightZeroSum += amount; + + weightSum += linLayoutParams->weight; + } else { + weightZeroSum += amount; + } + } + + weightZeroSum += spacing_ * (numVisible - 1); + + // Alright, got the sum. Let's take the remaining space after the fixed-size views, + // and distribute among the weighted ones. + if (orientation_ == ORIENT_HORIZONTAL) { + MeasureBySpec(layoutParams_->width, weightZeroSum, horiz, &measuredWidth_); + MeasureBySpec(layoutParams_->height, maxOther, vert, &measuredHeight_); + + float unit = (measuredWidth_ - weightZeroSum) / weightSum; + // Redistribute the stretchy ones! and remeasure the children! + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i]->GetVisibility() == V_GONE) + continue; + const LayoutParams *layoutParams = views_[i]->GetLayoutParams(); + const LinearLayoutParams *linLayoutParams = static_cast(layoutParams); + if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + + if (linLayoutParams && linLayoutParams->weight > 0.0f) { + Margins margins = defaultMargins_; + if (linLayoutParams->HasMargins()) + margins = linLayoutParams->margins; + int marginSum = margins.left + margins.right; + MeasureSpec v = vert; + if (v.type == UNSPECIFIED && measuredHeight_ != 0.0) + v = MeasureSpec(AT_MOST, measuredHeight_); + views_[i]->Measure(dc, MeasureSpec(EXACTLY, unit * linLayoutParams->weight - marginSum), v - (float)(margins.top + margins.bottom)); + } + } + } else { + //MeasureBySpec(layoutParams_->height, vert.type == UNSPECIFIED ? sum : weightZeroSum, vert, &measuredHeight_); + MeasureBySpec(layoutParams_->height, weightZeroSum, vert, &measuredHeight_); + MeasureBySpec(layoutParams_->width, maxOther, horiz, &measuredWidth_); + + float unit = (measuredHeight_ - weightZeroSum) / weightSum; + + // Redistribute the stretchy ones! and remeasure the children! + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i]->GetVisibility() == V_GONE) + continue; + const LayoutParams *layoutParams = views_[i]->GetLayoutParams(); + const LinearLayoutParams *linLayoutParams = static_cast(layoutParams); + if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + + if (linLayoutParams && linLayoutParams->weight > 0.0f) { + Margins margins = defaultMargins_; + if (linLayoutParams->HasMargins()) + margins = linLayoutParams->margins; + int marginSum = margins.top + margins.bottom; + MeasureSpec h = horiz; + if (h.type == UNSPECIFIED && measuredWidth_ != 0.0) + h = MeasureSpec(AT_MOST, measuredWidth_); + views_[i]->Measure(dc, h - (float)(margins.left + margins.right), MeasureSpec(EXACTLY, unit * linLayoutParams->weight - marginSum)); + } + } + } +} + +// weight != 0 = fill remaining space. +void LinearLayout::Layout() { + const Bounds &bounds = bounds_; + + Bounds itemBounds; + float pos; + + if (orientation_ == ORIENT_HORIZONTAL) { + pos = bounds.x; + itemBounds.y = bounds.y; + itemBounds.h = measuredHeight_; + } else { + pos = bounds.y; + itemBounds.x = bounds.x; + itemBounds.w = measuredWidth_; + } + + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i]->GetVisibility() == V_GONE) + continue; + + const LayoutParams *layoutParams = views_[i]->GetLayoutParams(); + const LinearLayoutParams *linLayoutParams = static_cast(layoutParams); + if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + + Gravity gravity = G_TOPLEFT; + Margins margins = defaultMargins_; + if (linLayoutParams) { + if (linLayoutParams->HasMargins()) + margins = linLayoutParams->margins; + gravity = linLayoutParams->gravity; + } + + if (orientation_ == ORIENT_HORIZONTAL) { + itemBounds.x = pos; + itemBounds.w = views_[i]->GetMeasuredWidth() + margins.left + margins.right; + } else { + itemBounds.y = pos; + itemBounds.h = views_[i]->GetMeasuredHeight() + margins.top + margins.bottom; + } + + Bounds innerBounds; + ApplyGravity(itemBounds, margins, + views_[i]->GetMeasuredWidth(), views_[i]->GetMeasuredHeight(), + gravity, innerBounds); + + views_[i]->SetBounds(innerBounds); + views_[i]->Layout(); + + pos += spacing_ + (orientation_ == ORIENT_HORIZONTAL ? itemBounds.w : itemBounds.h); + } +} + +void FrameLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { + if (views_.empty()) { + MeasureBySpec(layoutParams_->width, 0.0f, horiz, &measuredWidth_); + MeasureBySpec(layoutParams_->height, 0.0f, vert, &measuredHeight_); + return; + } + + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i]->GetVisibility() == V_GONE) + continue; + views_[i]->Measure(dc, horiz, vert); + } +} + +void FrameLayout::Layout() { + for (size_t i = 0; i < views_.size(); i++) { + if (views_[i]->GetVisibility() == V_GONE) + continue; + float w = views_[i]->GetMeasuredWidth(); + float h = views_[i]->GetMeasuredHeight(); + + Bounds bounds; + bounds.w = w; + bounds.h = h; + + bounds.x = bounds_.x + (measuredWidth_ - w) / 2; + bounds.y = bounds_.y + (measuredWidth_ - h) / 2; + views_[i]->SetBounds(bounds); + } +} + +void ScrollView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { + // Respect margins + Margins margins; + if (views_.size()) { + const LinearLayoutParams *linLayoutParams = static_cast(views_[0]->GetLayoutParams()); + if (!linLayoutParams->Is(LP_LINEAR)) { + linLayoutParams = 0; + } + if (linLayoutParams) { + margins = linLayoutParams->margins; + } + } + + // The scroll view itself simply obeys its parent - but also tries to fit the child if possible. + MeasureBySpec(layoutParams_->width, 0.0f, horiz, &measuredWidth_); + MeasureBySpec(layoutParams_->height, 0.0f, vert, &measuredHeight_); + + if (views_.size()) { + if (orientation_ == ORIENT_HORIZONTAL) { + views_[0]->Measure(dc, MeasureSpec(UNSPECIFIED), MeasureSpec(UNSPECIFIED)); + MeasureBySpec(layoutParams_->height, views_[0]->GetMeasuredHeight(), vert, &measuredHeight_); + } else { + views_[0]->Measure(dc, MeasureSpec(AT_MOST, measuredWidth_ - (margins.left + margins.right)), MeasureSpec(UNSPECIFIED)); + MeasureBySpec(layoutParams_->width, views_[0]->GetMeasuredWidth(), horiz, &measuredWidth_); + } + if (orientation_ == ORIENT_VERTICAL && vert.type != EXACTLY && measuredHeight_ < views_[0]->GetBounds().h) + measuredHeight_ = views_[0]->GetBounds().h; + } +} + +void ScrollView::Layout() { + if (!views_.size()) + return; + Bounds scrolled; + + // Respect margins + Margins margins; + const LinearLayoutParams *linLayoutParams = static_cast(views_[0]->GetLayoutParams()); + if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + if (linLayoutParams) { + margins = linLayoutParams->margins; + } + + scrolled.w = views_[0]->GetMeasuredWidth() - (margins.left + margins.right); + scrolled.h = views_[0]->GetMeasuredHeight() - (margins.top + margins.bottom); + + switch (orientation_) { + case ORIENT_HORIZONTAL: + if (scrolled.w != lastViewSize_) { + ScrollTo(0.0f); + lastViewSize_ = scrolled.w; + } + scrolled.x = bounds_.x - scrollPos_; + scrolled.y = bounds_.y + margins.top; + break; + case ORIENT_VERTICAL: + if (scrolled.h != lastViewSize_ && scrollToTopOnSizeChange_) { + ScrollTo(0.0f); + lastViewSize_ = scrolled.h; + } + scrolled.x = bounds_.x + margins.left; + scrolled.y = bounds_.y - scrollPos_; + break; + } + + views_[0]->SetBounds(scrolled); + views_[0]->Layout(); +} + +bool ScrollView::Key(const KeyInput &input) { + if (visibility_ != V_VISIBLE) + return ViewGroup::Key(input); + + if (input.flags & KEY_DOWN) { + switch (input.keyCode) { + case NKCODE_EXT_MOUSEWHEEL_UP: + ScrollRelative(-250); + break; + case NKCODE_EXT_MOUSEWHEEL_DOWN: + ScrollRelative(250); + break; + case NKCODE_PAGE_DOWN: + ScrollRelative((orientation_ == ORIENT_VERTICAL ? bounds_.h : bounds_.w) - 50); + break; + case NKCODE_PAGE_UP: + ScrollRelative(-(orientation_ == ORIENT_VERTICAL ? bounds_.h : bounds_.w) + 50); + break; + case NKCODE_MOVE_HOME: + ScrollTo(0); + break; + case NKCODE_MOVE_END: + if (views_.size()) + ScrollTo(orientation_ == ORIENT_VERTICAL ? views_[0]->GetBounds().h : views_[0]->GetBounds().w); + break; + } + } + return ViewGroup::Key(input); +} + +const float friction = 0.92f; +const float stop_threshold = 0.1f; + +void ScrollView::Touch(const TouchInput &input) { + if ((input.flags & TOUCH_DOWN) && input.id == 0) { + scrollStart_ = scrollPos_; + inertia_ = 0.0f; + } + + Gesture gesture = orientation_ == ORIENT_VERTICAL ? GESTURE_DRAG_VERTICAL : GESTURE_DRAG_HORIZONTAL; + + if (input.flags & TOUCH_UP) { + float info[4]; + if (!IsDragCaptured(input.id) && gesture_.GetGestureInfo(gesture, info)) { + inertia_ = info[1]; + } + } + + TouchInput input2; + if (CanScroll() && !IsDragCaptured(input.id)) { + input2 = gesture_.Update(input, bounds_); + float info[4]; + if (gesture_.GetGestureInfo(gesture, info) && !(input.flags & TOUCH_DOWN)) { + float pos = scrollStart_ - info[0]; + ClampScrollPos(pos); + scrollPos_ = pos; + scrollTarget_ = pos; + scrollToTarget_ = false; + } + } else { + input2 = input; + scrollTarget_ = scrollPos_; + scrollToTarget_ = false; + } + + if (!(input.flags & TOUCH_DOWN) || bounds_.Contains(input.x, input.y)) { + ViewGroup::Touch(input2); + } +} + +void ScrollView::Draw(UIContext &dc) { + if (!views_.size()) { + ViewGroup::Draw(dc); + return; + } + + dc.PushScissor(bounds_); + // For debugging layout issues, this can be useful. + // dc.FillRect(Drawable(0x60FF00FF), bounds_); + views_[0]->Draw(dc); + dc.PopScissor(); + + float childHeight = views_[0]->GetBounds().h; + float scrollMax = std::max(0.0f, childHeight - bounds_.h); + + float ratio = bounds_.h / views_[0]->GetBounds().h; + + float bobWidth = 5; + if (ratio < 1.0f && scrollMax > 0.0f) { + float bobHeight = ratio * bounds_.h; + float bobOffset = (scrollPos_ / scrollMax) * (bounds_.h - bobHeight); + + Bounds bob(bounds_.x2() - bobWidth, bounds_.y + bobOffset, bobWidth, bobHeight); + dc.FillRect(Drawable(0x80FFFFFF), bob); + } +} + +bool ScrollView::SubviewFocused(View *view) { + if (!ViewGroup::SubviewFocused(view)) + return false; + + const Bounds &vBounds = view->GetBounds(); + + // Scroll so that the focused view is visible, and a bit more so that headers etc gets visible too, in most cases. + const float overscroll = std::min(view->GetBounds().h / 1.5f, GetBounds().h / 4.0f); + + switch (orientation_) { + case ORIENT_HORIZONTAL: + if (vBounds.x2() > bounds_.x2()) { + ScrollTo(scrollPos_ + vBounds.x2() - bounds_.x2() + overscroll); + } + if (vBounds.x < bounds_.x) { + ScrollTo(scrollPos_ + (vBounds.x - bounds_.x) - overscroll); + } + break; + case ORIENT_VERTICAL: + if (vBounds.y2() > bounds_.y2()) { + ScrollTo(scrollPos_ + vBounds.y2() - bounds_.y2() + overscroll); + } + if (vBounds.y < bounds_.y) { + ScrollTo(scrollPos_ + (vBounds.y - bounds_.y) - overscroll); + } + break; + } + + return true; +} + +void ScrollView::ScrollTo(float newScrollPos) { + scrollTarget_ = newScrollPos; + scrollToTarget_ = true; + ClampScrollPos(scrollTarget_); +} + +void ScrollView::ScrollRelative(float distance) { + scrollTarget_ = scrollPos_ + distance; + scrollToTarget_ = true; + ClampScrollPos(scrollTarget_); +} + +void ScrollView::ClampScrollPos(float &pos) { + if (!views_.size()) { + pos = 0.0f; + return; + } + + float childSize = orientation_ == ORIENT_VERTICAL ? views_[0]->GetBounds().h : views_[0]->GetBounds().w; + float scrollMax = std::max(0.0f, childSize - (orientation_ == ORIENT_VERTICAL ? bounds_.h : bounds_.w)); + + if (pos < 0.0f) { + pos = 0.0f; + } + if (pos > scrollMax) { + pos = scrollMax; + } +} + +void ScrollView::ScrollToBottom() { + float childHeight = views_[0]->GetBounds().h; + float scrollMax = std::max(0.0f, childHeight - bounds_.h); + scrollPos_ = scrollMax; + scrollTarget_ = scrollMax; +} + +bool ScrollView::CanScroll() const { + if (!views_.size()) + return false; + switch (orientation_) { + case ORIENT_VERTICAL: + return views_[0]->GetBounds().h > bounds_.h; + case ORIENT_HORIZONTAL: + return views_[0]->GetBounds().w > bounds_.w; + default: + return false; + } +} + +void ScrollView::Update(const InputState &input_state) { + if (visibility_ != V_VISIBLE) { + inertia_ = 0.0f; + } + ViewGroup::Update(input_state); + gesture_.UpdateFrame(); + if (scrollToTarget_) { + inertia_ = 0.0f; + if (fabsf(scrollTarget_ - scrollPos_) < 0.5f) { + scrollPos_ = scrollTarget_; + scrollToTarget_ = false; + } else { + scrollPos_ += (scrollTarget_ - scrollPos_) * 0.3f; + } + } else if (inertia_ != 0.0f && !gesture_.IsGestureActive(GESTURE_DRAG_VERTICAL)) { + scrollPos_ -= inertia_; + inertia_ *= friction; + if (fabsf(inertia_) < stop_threshold) + inertia_ = 0.0f; + ClampScrollPos(scrollPos_); + } +} + +void AnchorLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { + MeasureBySpec(layoutParams_->width, 0.0f, horiz, &measuredWidth_); + MeasureBySpec(layoutParams_->height, 0.0f, vert, &measuredHeight_); + + for (size_t i = 0; i < views_.size(); i++) { + Size width = WRAP_CONTENT; + Size height = WRAP_CONTENT; + + MeasureSpec specW(UNSPECIFIED, 0.0f); + MeasureSpec specH(UNSPECIFIED, 0.0f); + + const AnchorLayoutParams *params = static_cast(views_[i]->GetLayoutParams()); + if (!params->Is(LP_ANCHOR)) params = 0; + if (params) { + width = params->width; + height = params->height; + + if (!params->center) { + if (params->left >= 0 && params->right >= 0) { + width = measuredWidth_ - params->left - params->right; + } + if (params->top >= 0 && params->bottom >= 0) { + height = measuredHeight_ - params->top - params->bottom; + } + } + specW = width < 0 ? MeasureSpec(UNSPECIFIED) : MeasureSpec(EXACTLY, width); + specH = height < 0 ? MeasureSpec(UNSPECIFIED) : MeasureSpec(EXACTLY, height); + } + + views_[i]->Measure(dc, specW, specH); + } +} + +void AnchorLayout::Layout() { + for (size_t i = 0; i < views_.size(); i++) { + const AnchorLayoutParams *params = static_cast(views_[i]->GetLayoutParams()); + if (!params->Is(LP_ANCHOR)) params = 0; + + Bounds vBounds; + vBounds.w = views_[i]->GetMeasuredWidth(); + vBounds.h = views_[i]->GetMeasuredHeight(); + + // Clamp width/height to our own + if (vBounds.w > bounds_.w) vBounds.w = bounds_.w; + if (vBounds.h > bounds_.h) vBounds.h = bounds_.h; + + float left = 0, top = 0, right = 0, bottom = 0, center = false; + if (params) { + left = params->left; + top = params->top; + right = params->right; + bottom = params->bottom; + center = params->center; + } + + if (left >= 0) { + vBounds.x = bounds_.x + left; + if (center) + vBounds.x -= vBounds.w * 0.5f; + } else if (right >= 0) { + vBounds.x = bounds_.x2() - right - vBounds.w; + if (center) { + vBounds.x += vBounds.w * 0.5f; + } + } + + if (top >= 0) { + vBounds.y = bounds_.y + top; + if (center) + vBounds.y -= vBounds.h * 0.5f; + } else if (bottom >= 0) { + vBounds.y = bounds_.y2() - bottom - vBounds.h; + if (center) + vBounds.y += vBounds.h * 0.5f; + } + + views_[i]->SetBounds(vBounds); + views_[i]->Layout(); + } +} + +void GridLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { + MeasureSpecType measureType = settings_.fillCells ? EXACTLY : AT_MOST; + + for (size_t i = 0; i < views_.size(); i++) { + views_[i]->Measure(dc, MeasureSpec(measureType, settings_.columnWidth), MeasureSpec(measureType, settings_.rowHeight)); + } + + MeasureBySpec(layoutParams_->width, 0.0f, horiz, &measuredWidth_); + + // Okay, got the width we are supposed to adjust to. Now we can calculate the number of columns. + numColumns_ = (measuredWidth_ - settings_.spacing) / (settings_.columnWidth + settings_.spacing); + if (!numColumns_) numColumns_ = 1; + int numRows = (int)(views_.size() + (numColumns_ - 1)) / numColumns_; + + float estimatedHeight = (settings_.rowHeight + settings_.spacing) * numRows; + + MeasureBySpec(layoutParams_->height, estimatedHeight, vert, &measuredHeight_); +} + +void GridLayout::Layout() { + int y = 0; + int x = 0; + int count = 0; + for (size_t i = 0; i < views_.size(); i++) { + Bounds itemBounds, innerBounds; + + itemBounds.x = bounds_.x + x; + itemBounds.y = bounds_.y + y; + itemBounds.w = settings_.columnWidth; + itemBounds.h = settings_.rowHeight; + + ApplyGravity(itemBounds, Margins(0.0f), + views_[i]->GetMeasuredWidth(), views_[i]->GetMeasuredHeight(), + G_HCENTER | G_VCENTER, innerBounds); + + views_[i]->SetBounds(innerBounds); + views_[i]->Layout(); + + count++; + if (count == numColumns_) { + count = 0; + x = 0; + y += itemBounds.h + settings_.spacing; + } else { + x += itemBounds.w + settings_.spacing; + } + } +} + +TabHolder::TabHolder(Orientation orientation, float stripSize, LayoutParams *layoutParams) + : LinearLayout(Opposite(orientation), layoutParams), + tabStrip_(nullptr), tabScroll_(nullptr), + stripSize_(stripSize), + currentTab_(0) { + SetSpacing(0.0f); + if (orientation == ORIENT_HORIZONTAL) { + tabStrip_ = new ChoiceStrip(orientation, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); + tabStrip_->SetTopTabs(true); + tabScroll_ = new ScrollView(orientation, new LayoutParams(FILL_PARENT, FILL_PARENT)); + tabScroll_->Add(tabStrip_); + Add(tabScroll_); + } else { + tabStrip_ = new ChoiceStrip(orientation, new LayoutParams(stripSize, WRAP_CONTENT)); + tabStrip_->SetTopTabs(true); + Add(tabStrip_); + tabScroll_ = nullptr; + } + tabStrip_->OnChoice.Handle(this, &TabHolder::OnTabClick); +} + +EventReturn TabHolder::OnTabClick(EventParams &e) { + tabs_[currentTab_]->SetVisibility(V_GONE); + currentTab_ = e.a; + tabs_[currentTab_]->SetVisibility(V_VISIBLE); + return EVENT_DONE; +} + +ChoiceStrip::ChoiceStrip(Orientation orientation, LayoutParams *layoutParams) + : LinearLayout(orientation, layoutParams), selected_(0), topTabs_(false) { + SetSpacing(0.0f); +} + +void ChoiceStrip::AddChoice(const std::string &title) { + StickyChoice *c = new StickyChoice(title, "", + orientation_ == ORIENT_HORIZONTAL ? + 0 : + new LinearLayoutParams(FILL_PARENT, ITEM_HEIGHT)); + c->OnClick.Handle(this, &ChoiceStrip::OnChoiceClick); + Add(c); + if (selected_ == (int)views_.size() - 1) + c->Press(); +} + +void ChoiceStrip::AddChoice(ImageID buttonImage) { + StickyChoice *c = new StickyChoice(buttonImage, + orientation_ == ORIENT_HORIZONTAL ? + 0 : + new LinearLayoutParams(FILL_PARENT, ITEM_HEIGHT)); + c->OnClick.Handle(this, &ChoiceStrip::OnChoiceClick); + Add(c); + if (selected_ == (int)views_.size() - 1) + c->Press(); +} + +EventReturn ChoiceStrip::OnChoiceClick(EventParams &e) { + // Unstick the other choices that weren't clicked. + for (int i = 0; i < (int)views_.size(); i++) { + if (views_[i] != e.v) { + static_cast(views_[i])->Release(); + } else { + selected_ = i; + } + } + + EventParams e2; + e2.v = views_[selected_]; + e2.a = selected_; + // Dispatch immediately (we're already on the UI thread as we're in an event handler). + return OnChoice.Dispatch(e2); +} + +void ChoiceStrip::SetSelection(int sel) { + int prevSelected = selected_; + if (selected_ < (int)views_.size()) + static_cast(views_[selected_])->Release(); + selected_ = sel; + if (selected_ < (int)views_.size()) + static_cast(views_[selected_])->Press(); + if (topTabs_ && prevSelected != selected_) { + EventParams e; + e.v = views_[selected_]; + static_cast(views_[selected_])->OnClick.Trigger(e); + } +} + +void ChoiceStrip::HighlightChoice(unsigned int choice){ + if (choice < (unsigned int)views_.size()){ + static_cast(views_[choice])->HighlightChanged(true); + } +}; + +bool ChoiceStrip::Key(const KeyInput &input) { + bool ret = false; + if (input.flags & KEY_DOWN) { + if (IsTabLeftKey(input) && selected_ > 0) { + SetSelection(selected_ - 1); + ret = true; + } else if (IsTabRightKey(input) && selected_ < (int)views_.size() - 1) { + SetSelection(selected_ + 1); + ret = true; + } + } + return ret || ViewGroup::Key(input); +} + +void ChoiceStrip::Draw(UIContext &dc) { + ViewGroup::Draw(dc); + if (topTabs_) { + if (orientation_ == ORIENT_HORIZONTAL) + dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y2() - 4, bounds_.x2(), bounds_.y2(), dc.theme->itemDownStyle.background.color ); + else if (orientation_ == ORIENT_VERTICAL) + dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x2() - 4, bounds_.y, bounds_.x2(), bounds_.y2(), dc.theme->itemDownStyle.background.color ); + } +} + +ListView::ListView(ListAdaptor *a, LayoutParams *layoutParams) + : ScrollView(ORIENT_VERTICAL, layoutParams), adaptor_(a), maxHeight_(0) { + + linLayout_ = new LinearLayout(ORIENT_VERTICAL); + linLayout_->SetSpacing(0.0f); + Add(linLayout_); + CreateAllItems(); +} + +void ListView::CreateAllItems() { + linLayout_->Clear(); + // Let's not be clever yet, we'll just create them all up front and add them all in. + for (int i = 0; i < adaptor_->GetNumItems(); i++) { + View * v = linLayout_->Add(adaptor_->CreateItemView(i)); + adaptor_->AddEventCallback(v, std::bind(&ListView::OnItemCallback, this, i, placeholder::_1)); + } +} + +void ListView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { + ScrollView::Measure(dc, horiz, vert); + if (maxHeight_ > 0 && measuredHeight_ > maxHeight_) { + measuredHeight_ = maxHeight_; + } +} + +EventReturn ListView::OnItemCallback(int num, EventParams &e) { + EventParams ev; + ev.v = 0; + ev.a = num; + adaptor_->SetSelected(num); + View *focused = GetFocusedView(); + OnChoice.Trigger(ev); + CreateAllItems(); + if (focused) + SetFocusedView(linLayout_->GetViewByIndex(num)); + return EVENT_DONE; +} + +View *ChoiceListAdaptor::CreateItemView(int index) { + return new Choice(items_[index]); +} + +bool ChoiceListAdaptor::AddEventCallback(View *view, std::function callback) { + Choice *choice = (Choice *)view; + choice->OnClick.Add(callback); + return EVENT_DONE; +} + + +View *StringVectorListAdaptor::CreateItemView(int index) { + return new Choice(items_[index], "", index == selected_); +} + +bool StringVectorListAdaptor::AddEventCallback(View *view, std::function callback) { + Choice *choice = (Choice *)view; + choice->OnClick.Add(callback); + return EVENT_DONE; +} + +void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root) { + if (!root) { + ELOG("Tried to layout a view hierarchy from a zero pointer root"); + return; + } + const Bounds &rootBounds = dc.GetBounds(); + + MeasureSpec horiz(EXACTLY, rootBounds.w); + MeasureSpec vert(EXACTLY, rootBounds.h); + + // Two phases - measure contents, layout. + root->Measure(dc, horiz, vert); + // Root has a specified size. Set it, then let root layout all its children. + root->SetBounds(rootBounds); + root->Layout(); +} + +// TODO: Figure out where this should really live. +// Simple simulation of key repeat on platforms and for gamepads where we don't +// automatically get it. + +static int frameCount; + +// Ignore deviceId when checking for matches. Turns out that Ouya for example sends +// completely broken input where the original keypresses have deviceId = 10 and the repeats +// have deviceId = 0. +struct HeldKey { + int key; + int deviceId; + double triggerTime; + + // Ignores startTime + bool operator <(const HeldKey &other) const { + if (key < other.key) return true; + return false; + } + bool operator ==(const HeldKey &other) const { return key == other.key; } +}; + +static std::set heldKeys; + +const double repeatDelay = 15 * (1.0 / 60.0f); // 15 frames like before. +const double repeatInterval = 5 * (1.0 / 60.0f); // 5 frames like before. + +bool KeyEvent(const KeyInput &key, ViewGroup *root) { + bool retval = false; + // Ignore repeats for focus moves. + if ((key.flags & (KEY_DOWN | KEY_IS_REPEAT)) == KEY_DOWN) { + if (IsDPadKey(key)) { + // Let's only repeat DPAD initially. + HeldKey hk; + hk.key = key.keyCode; + hk.deviceId = key.deviceId; + hk.triggerTime = time_now_d() + repeatDelay; + + // Check if the key is already held. If it is, ignore it. This is to avoid + // multiple key repeat mechanisms colliding. + if (heldKeys.find(hk) != heldKeys.end()) { + return false; + } + + heldKeys.insert(hk); + lock_guard lock(focusLock); + focusMoves.push_back(key.keyCode); + retval = true; + } + } + if (key.flags & KEY_UP) { + // We ignore the device ID here (in the comparator for HeldKey), due to the Ouya quirk mentioned above. + if (!heldKeys.empty()) { + HeldKey hk; + hk.key = key.keyCode; + hk.deviceId = key.deviceId; + hk.triggerTime = 0.0; // irrelevant + if (heldKeys.find(hk) != heldKeys.end()) { + heldKeys.erase(hk); + retval = true; + } + } + } + + retval = root->Key(key); + + // Ignore volume keys and stuff here. Not elegant but need to propagate bools through the view hierarchy as well... + switch (key.keyCode) { + case NKCODE_VOLUME_DOWN: + case NKCODE_VOLUME_UP: + case NKCODE_VOLUME_MUTE: + retval = false; + break; + } + + return retval; +} + +static void ProcessHeldKeys(ViewGroup *root) { + double now = time_now_d(); + +restart: + + for (std::set::iterator iter = heldKeys.begin(); iter != heldKeys.end(); ++iter) { + if (iter->triggerTime < now) { + KeyInput key; + key.keyCode = iter->key; + key.deviceId = iter->deviceId; + key.flags = KEY_DOWN; + KeyEvent(key, root); + + lock_guard lock(focusLock); + focusMoves.push_back(key.keyCode); + + // Cannot modify the current item when looping over a set, so let's do this instead. + HeldKey hk = *iter; + heldKeys.erase(hk); + hk.triggerTime = now + repeatInterval; + heldKeys.insert(hk); + goto restart; + } + } +} + +bool TouchEvent(const TouchInput &touch, ViewGroup *root) { + focusForced = false; + root->Touch(touch); + if ((touch.flags & TOUCH_DOWN) && !focusForced) { + EnableFocusMovement(false); + } + return true; +} + +bool AxisEvent(const AxisInput &axis, ViewGroup *root) { + root->Axis(axis); + return true; +} + +void UpdateViewHierarchy(const InputState &input_state, ViewGroup *root) { + ProcessHeldKeys(root); + frameCount++; + + if (!root) { + ELOG("Tried to update a view hierarchy from a zero pointer root"); + return; + } + + if (focusMoves.size()) { + lock_guard lock(focusLock); + EnableFocusMovement(true); + if (!GetFocusedView()) { + if (root->GetDefaultFocusView()) { + root->GetDefaultFocusView()->SetFocus(); + } else { + root->SetFocus(); + } + root->SubviewFocused(GetFocusedView()); + } else { + for (size_t i = 0; i < focusMoves.size(); i++) { + switch (focusMoves[i]) { + case NKCODE_DPAD_LEFT: MoveFocus(root, FOCUS_LEFT); break; + case NKCODE_DPAD_RIGHT: MoveFocus(root, FOCUS_RIGHT); break; + case NKCODE_DPAD_UP: MoveFocus(root, FOCUS_UP); break; + case NKCODE_DPAD_DOWN: MoveFocus(root, FOCUS_DOWN); break; + } + } + } + focusMoves.clear(); + } + + root->Update(input_state); + DispatchEvents(); +} + +} // namespace UI diff --git a/ext/native/ui/viewgroup.h b/ext/native/ui/viewgroup.h new file mode 100644 index 0000000000..6126dc63d8 --- /dev/null +++ b/ext/native/ui/viewgroup.h @@ -0,0 +1,384 @@ +#pragma once + +#include + +#include "base/logging.h" +#include "base/mutex.h" +#include "math/geom2d.h" +#include "input/gesture_detector.h" +#include "ui/view.h" + +namespace UI { + +struct NeighborResult { + NeighborResult() : view(0), score(0) {} + NeighborResult(View *v, float s) : view(v), score(s) {} + + View *view; + float score; +}; + +class ViewGroup : public View { +public: + ViewGroup(LayoutParams *layoutParams = 0) : View(layoutParams), defaultFocusView_(0), hasDropShadow_(false), clip_(false) {} + virtual ~ViewGroup(); + + // Pass through external events to children. + virtual bool Key(const KeyInput &input) override; + virtual void Touch(const TouchInput &input) override; + virtual void Axis(const AxisInput &input) override; + + // By default, a container will layout to its own bounds. + virtual void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) = 0; + virtual void Layout() = 0; + virtual void Update(const InputState &input_state); + + virtual void Draw(UIContext &dc) override; + + // These should be unused. + virtual float GetContentWidth() const { return 0.0f; } + virtual float GetContentHeight() const { return 0.0f; } + + // Takes ownership! DO NOT add a view to multiple parents! + template + T *Add(T *view) { + lock_guard guard(modifyLock_); + views_.push_back(view); + return view; + } + + virtual bool SetFocus() override; + virtual bool SubviewFocused(View *view); + virtual void RemoveSubview(View *view); + + void SetDefaultFocusView(View *view) { defaultFocusView_ = view; } + View *GetDefaultFocusView() { return defaultFocusView_; } + + // Assumes that layout has taken place. + NeighborResult FindNeighbor(View *view, FocusDirection direction, NeighborResult best); + + virtual bool CanBeFocused() const { return false; } + virtual bool IsViewGroup() const { return true; } + + virtual void SetBG(const Drawable &bg) { bg_ = bg; } + + virtual void Clear(); + View *GetViewByIndex(int index) { return views_[index]; } + int GetNumSubviews() const { return (int)views_.size(); } + void SetHasDropShadow(bool has) { hasDropShadow_ = has; } + + void Lock() { modifyLock_.lock(); } + void Unlock() { modifyLock_.unlock(); } + + void SetClip(bool clip) { clip_ = clip; } + +protected: + recursive_mutex modifyLock_; // Hold this when changing the subviews. + std::vector views_; + View *defaultFocusView_; + Drawable bg_; + bool hasDropShadow_; + bool clip_; +}; + +// A frame layout contains a single child view (normally). +// It simply centers the child view. +class FrameLayout : public ViewGroup { +public: + void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert); + void Layout(); +}; + +enum { + NONE = -1, +}; + +class AnchorLayoutParams : public LayoutParams { +public: + AnchorLayoutParams(Size w, Size h, float l, float t, float r, float b, bool c = false) + : LayoutParams(w, h, LP_ANCHOR), left(l), top(t), right(r), bottom(b), center(c) { + + } + AnchorLayoutParams(Size w, Size h, bool c = false) + : LayoutParams(w, h, LP_ANCHOR), left(0), top(0), right(NONE), bottom(NONE), center(c) { + } + AnchorLayoutParams(float l, float t, float r, float b, bool c = false) + : LayoutParams(WRAP_CONTENT, WRAP_CONTENT, LP_ANCHOR), left(l), top(t), right(r), bottom(b), center(c) {} + + // These are not bounds, but distances from the container edges. + // Set to NONE to not attach this edge to the container. + float left, top, right, bottom; + bool center; // If set, only two "sides" can be set, and they refer to the center, not the edge, of the view being layouted. +}; + +class AnchorLayout : public ViewGroup { +public: + AnchorLayout(LayoutParams *layoutParams = 0) : ViewGroup(layoutParams) {} + void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert); + void Layout(); +}; + +class LinearLayoutParams : public LayoutParams { +public: + LinearLayoutParams() + : LayoutParams(LP_LINEAR), weight(0.0f), gravity(G_TOPLEFT), hasMargins_(false) {} + explicit LinearLayoutParams(float wgt, Gravity grav = G_TOPLEFT) + : LayoutParams(LP_LINEAR), weight(wgt), gravity(grav), hasMargins_(false) {} + LinearLayoutParams(float wgt, const Margins &mgn) + : LayoutParams(LP_LINEAR), weight(wgt), gravity(G_TOPLEFT), margins(mgn), hasMargins_(true) {} + LinearLayoutParams(Size w, Size h, float wgt = 0.0f, Gravity grav = G_TOPLEFT) + : LayoutParams(w, h, LP_LINEAR), weight(wgt), gravity(grav), hasMargins_(false) {} + LinearLayoutParams(Size w, Size h, float wgt, Gravity grav, const Margins &mgn) + : LayoutParams(w, h, LP_LINEAR), weight(wgt), gravity(grav), margins(mgn), hasMargins_(true) {} + LinearLayoutParams(Size w, Size h, const Margins &mgn) + : LayoutParams(w, h, LP_LINEAR), weight(0.0f), gravity(G_TOPLEFT), margins(mgn), hasMargins_(true) {} + LinearLayoutParams(Size w, Size h, float wgt, const Margins &mgn) + : LayoutParams(w, h, LP_LINEAR), weight(wgt), gravity(G_TOPLEFT), margins(mgn), hasMargins_(true) {} + LinearLayoutParams(const Margins &mgn) + : LayoutParams(WRAP_CONTENT, WRAP_CONTENT, LP_LINEAR), weight(0.0f), gravity(G_TOPLEFT), margins(mgn), hasMargins_(true) {} + + float weight; + Gravity gravity; + Margins margins; + + bool HasMargins() const { return hasMargins_; } + +private: + bool hasMargins_; +}; + +class LinearLayout : public ViewGroup { +public: + LinearLayout(Orientation orientation, LayoutParams *layoutParams = 0) + : ViewGroup(layoutParams), orientation_(orientation), defaultMargins_(0), spacing_(10) {} + + void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert); + void Layout(); + void SetSpacing(float spacing) { + spacing_ = spacing; + } +protected: + Orientation orientation_; +private: + Margins defaultMargins_; + float spacing_; +}; + +// GridLayout is a little different from the Android layout. This one has fixed size +// rows and columns. Items are not allowed to deviate from the set sizes. +// Initially, only horizontal layout is supported. +struct GridLayoutSettings { + GridLayoutSettings() : orientation(ORIENT_HORIZONTAL), columnWidth(100), rowHeight(50), spacing(5), fillCells(false) {} + GridLayoutSettings(int colW, int colH, int spac = 5) + : orientation(ORIENT_HORIZONTAL), columnWidth(colW), rowHeight(colH), spacing(spac), fillCells(false) {} + + Orientation orientation; + int columnWidth; + int rowHeight; + int spacing; + bool fillCells; +}; + +class GridLayout : public ViewGroup { +public: + GridLayout(GridLayoutSettings settings, LayoutParams *layoutParams = 0) + : ViewGroup(layoutParams), settings_(settings), numColumns_(1) { + if (settings.orientation != ORIENT_HORIZONTAL) + ELOG("GridLayout: Vertical layouts not yet supported"); + } + + void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert); + void Layout(); + +private: + GridLayoutSettings settings_; + int numColumns_; +}; + +// A scrollview usually contains just a single child - a linear layout or similar. +class ScrollView : public ViewGroup { +public: + ScrollView(Orientation orientation, LayoutParams *layoutParams = 0) : + ViewGroup(layoutParams), + orientation_(orientation), + scrollPos_(0), + scrollStart_(0), + scrollTarget_(0), + scrollToTarget_(false), + inertia_(0), + lastViewSize_(0.0f), + scrollToTopOnSizeChange_(true) {} + + void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert); + void Layout(); + + bool Key(const KeyInput &input); + void Touch(const TouchInput &input); + void Draw(UIContext &dc); + + void ScrollTo(float newScrollPos); + void ScrollToBottom(); + void ScrollRelative(float distance); + bool CanScroll() const; + void Update(const InputState &input_state); + + // Override so that we can scroll to the active one after moving the focus. + virtual bool SubviewFocused(View *view); + + // Quick hack to prevent scrolling to top in some lists + void SetScrollToTop(bool t) { scrollToTopOnSizeChange_ = t; } + +private: + void ClampScrollPos(float &pos); + + GestureDetector gesture_; + Orientation orientation_; + float scrollPos_; + float scrollStart_; + float scrollTarget_; + bool scrollToTarget_; + float inertia_; + float lastViewSize_; + bool scrollToTopOnSizeChange_; +}; + +class ViewPager : public ScrollView { +public: +}; + + +class ChoiceStrip : public LinearLayout { +public: + ChoiceStrip(Orientation orientation, LayoutParams *layoutParams = 0); + + void AddChoice(const std::string &title); + void AddChoice(ImageID buttonImage); + + int GetSelection() const { return selected_; } + void SetSelection(int sel); + + void HighlightChoice(unsigned int choice); + + bool Key(const KeyInput &input) override; + + void SetTopTabs(bool tabs) { topTabs_ = tabs; } + void Draw(UIContext &dc) override; + + Event OnChoice; + +private: + EventReturn OnChoiceClick(EventParams &e); + + int selected_; + bool topTabs_; // Can be controlled with L/R. +}; + + +class TabHolder : public LinearLayout { +public: + TabHolder(Orientation orientation, float stripSize, LayoutParams *layoutParams = 0); + + template + T *AddTab(const std::string &title, T *tabContents) { + tabContents->ReplaceLayoutParams(new LinearLayoutParams(1.0f)); + tabs_.push_back(tabContents); + tabStrip_->AddChoice(title); + Add(tabContents); + if (tabs_.size() > 1) + tabContents->SetVisibility(V_GONE); + return tabContents; + } + + void SetCurrentTab(int tab) { + tabs_[currentTab_]->SetVisibility(V_GONE); + currentTab_ = tab; + tabs_[currentTab_]->SetVisibility(V_VISIBLE); + tabStrip_->SetSelection(tab); + } + + int GetCurrentTab() const { return currentTab_; } + +private: + EventReturn OnTabClick(EventParams &e); + + ChoiceStrip *tabStrip_; + ScrollView *tabScroll_; + + float stripSize_; + int currentTab_; + std::vector tabs_; +}; + +// Yes, this feels a bit Java-ish... +class ListAdaptor { +public: + virtual ~ListAdaptor() {} + virtual View *CreateItemView(int index) = 0; + virtual int GetNumItems() = 0; + virtual bool AddEventCallback(View *view, std::function callback) { return false; } + virtual std::string GetTitle(int index) const { return ""; } + virtual void SetSelected(int sel) { } + virtual int GetSelected() { return -1; } +}; + +class ChoiceListAdaptor : public ListAdaptor { +public: + ChoiceListAdaptor(const char *items[], int numItems) : items_(items), numItems_(numItems) {} + virtual View *CreateItemView(int index); + virtual int GetNumItems() { return numItems_; } + virtual bool AddEventCallback(View *view, std::function callback); + +private: + const char **items_; + int numItems_; +}; + + +// The "selected" item is what was previously selected (optional). This items will be drawn differently. +class StringVectorListAdaptor : public ListAdaptor { +public: + StringVectorListAdaptor() : selected_(-1) {} + StringVectorListAdaptor(const std::vector &items, int selected = -1) : items_(items), selected_(selected) {} + virtual View *CreateItemView(int index) override; + virtual int GetNumItems() override { return (int)items_.size(); } + virtual bool AddEventCallback(View *view, std::function callback) override; + void SetSelected(int sel) { selected_ = sel; } + virtual std::string GetTitle(int index) const override { return items_[index]; } + virtual int GetSelected() override { return selected_; } + +private: + std::vector items_; + int selected_; +}; + +// A list view is a scroll view with autogenerated items. +// In the future, it might be smart and load/unload items as they go, but currently not. +class ListView : public ScrollView { +public: + ListView(ListAdaptor *a, LayoutParams *layoutParams = 0); + + int GetSelected() { return adaptor_->GetSelected(); } + virtual void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert); + virtual void SetMaxHeight(float mh) { maxHeight_ = mh; } + Event OnChoice; + +private: + void CreateAllItems(); + EventReturn OnItemCallback(int num, EventParams &e); + ListAdaptor *adaptor_; + LinearLayout *linLayout_; + float maxHeight_; +}; + +void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root); +void UpdateViewHierarchy(const InputState &input_state, ViewGroup *root); +// Hooks arrow keys for navigation +bool KeyEvent(const KeyInput &key, ViewGroup *root); +bool TouchEvent(const TouchInput &touch, ViewGroup *root); +bool AxisEvent(const AxisInput &axis, ViewGroup *root); + +void CaptureDrag(int id); +void ReleaseDrag(int id); +bool IsDragCaptured(int id); + +} // namespace UI diff --git a/ext/native/ui/virtual_input.cpp b/ext/native/ui/virtual_input.cpp new file mode 100644 index 0000000000..dc12940543 --- /dev/null +++ b/ext/native/ui/virtual_input.cpp @@ -0,0 +1,167 @@ +#include +#include + +#include "base/logging.h" +#include "gfx_es2/draw_buffer.h" +#include "gfx/texture_atlas.h" +#include "input/input_state.h" +#include "virtual_input.h" + +TouchButton::TouchButton(const Atlas *atlas, int imageIndex, int overlayImageIndex, int button, int rotationAngle, bool mirror_h) + : atlas_(atlas), imageIndex_(imageIndex), overlayImageIndex_(overlayImageIndex), button_(button), mirror_h_(mirror_h) +{ + memset(pointerDown, 0, sizeof(pointerDown)); + w_ = atlas_->images[imageIndex_].w; + h_ = atlas_->images[imageIndex_].h; + rotationAngle_ = (float)rotationAngle * 3.1415927 / 180.0f; + isDown_ = false; +} + +void TouchButton::update(InputState &input_state) +{ + bool down = false; + for (int i = 0; i < MAX_POINTERS; i++) { + if (input_state.pointer_down[i] && isInside(input_state.pointer_x[i], input_state.pointer_y[i])) + down = true; + } + + if (down) + input_state.pad_buttons |= button_; + + isDown_ = (input_state.pad_buttons & button_) != 0; +} + +void TouchButton::draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay) +{ + float scale = 1.0f; + if (isDown_) { + color |= 0xFF000000; + colorOverlay |= 0xFF000000; + scale = 2.0f; + } + scale *= scale_; + // We only mirror background + db.DrawImageRotated(imageIndex_, x_ + w_*scale_/2, y_ + h_*scale_/2, scale, rotationAngle_, color, mirror_h_); + if (overlayImageIndex_ != -1) + db.DrawImageRotated(overlayImageIndex_, x_ + w_*scale_/2, y_ + h_*scale_/2, scale, rotationAngle_, colorOverlay); +} + +TouchCrossPad::TouchCrossPad(const Atlas *atlas, int arrowIndex, int overlayIndex) + : atlas_(atlas), arrowIndex_(arrowIndex), overlayIndex_(overlayIndex), down_(0) +{ + +} + +void TouchCrossPad::update(InputState &input_state) +{ + float stick_size_ = radius_ * 2; + float inv_stick_size = 1.0f / (stick_size_ * scale_); + const float deadzone = 0.17f; + + for (int i = 0; i < MAX_POINTERS; i++) { + if (input_state.pointer_down[i]) { + float dx = (input_state.pointer_x[i] - x_) * inv_stick_size; + float dy = (input_state.pointer_y[i] - y_) * inv_stick_size; + float rad = sqrtf(dx*dx+dy*dy); + if (rad < deadzone || rad > 1.0f) + continue; + + if (dx == 0 && dy == 0) + continue; + + int direction = (int)(floorf((atan2f(dy, dx) / (2 * M_PI) * 8) + 0.5f)) & 7; + + input_state.pad_buttons &= ~(PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_UP | PAD_BUTTON_DOWN); + switch (direction) { + case 0: input_state.pad_buttons |= PAD_BUTTON_RIGHT; break; + case 1: input_state.pad_buttons |= PAD_BUTTON_RIGHT | PAD_BUTTON_DOWN; break; + case 2: input_state.pad_buttons |= PAD_BUTTON_DOWN; break; + case 3: input_state.pad_buttons |= PAD_BUTTON_DOWN | PAD_BUTTON_LEFT; break; + case 4: input_state.pad_buttons |= PAD_BUTTON_LEFT; break; + case 5: input_state.pad_buttons |= PAD_BUTTON_UP | PAD_BUTTON_LEFT; break; + case 6: input_state.pad_buttons |= PAD_BUTTON_UP; break; + case 7: input_state.pad_buttons |= PAD_BUTTON_UP | PAD_BUTTON_RIGHT; break; + } + } + } + down_ = input_state.pad_buttons & (PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_UP | PAD_BUTTON_DOWN); +} + +void TouchCrossPad::draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay) +{ + static const float xoff[4] = {1, 0, -1, 0}; + static const float yoff[4] = {0, 1, 0, -1}; + static const int dir[4] = {PAD_BUTTON_RIGHT, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, PAD_BUTTON_UP}; + for (int i = 0; i < 4; i++) { + float x = x_ + xoff[i] * scale_ * radius_; + float y = y_ + yoff[i] * scale_ * radius_; + float angle = i * M_PI / 2; + float imgScale = (down_ & dir[i]) ? scale_ * 2 : scale_; + db.DrawImageRotated(arrowIndex_, x, y, imgScale, angle + PI, color, false); + if (overlayIndex_ != -1) + db.DrawImageRotated(overlayIndex_, x, y, imgScale, angle + PI, colorOverlay); + } +} + +TouchStick::TouchStick(const Atlas *atlas, int bgImageIndex, int stickImageIndex, int stick) + : atlas_(atlas), bgImageIndex_(bgImageIndex), stickImageIndex_(stickImageIndex), stick_(stick) +{ + stick_size_ = atlas_->images[bgImageIndex].w / 3.5f; + memset(dragging_, 0, sizeof(dragging_)); + memset(lastPointerDown_, 0, sizeof(lastPointerDown_)); +} + +void TouchStick::update(InputState &input_state) +{ + float inv_stick_size = 1.0f / (stick_size_ * scale_); + for (int i = 0; i < MAX_POINTERS; i++) { + if (input_state.pointer_down[i]) { + float dx = (input_state.pointer_x[i] - stick_x_) * inv_stick_size; + float dy = (input_state.pointer_y[i] - stick_y_) * inv_stick_size; + // Ignore outside box + if (!dragging_[i] && (fabsf(dx) > 1.4f || fabsf(dy) > 1.4f)) + goto skip; + if (!lastPointerDown_[i] && (fabsf(dx) < 1.4f && fabsf(dy) < 1.4f)) { + dragging_[i] = true; + } + if (!dragging_[i]) + goto skip; + + // Do not clamp to a circle! The PSP has nearly square range! + + // Old code to clamp to a circle + // float len = sqrtf(dx * dx + dy * dy); + // if (len > 1.0f) { + // dx /= len; + // dy /= len; + //} + + // Still need to clamp to a square + dx = std::min(1.0f, std::max(-1.0f, dx)); + dy = std::min(1.0f, std::max(-1.0f, dy)); + + if (stick_ == 0) { + input_state.pad_lstick_x = dx; + input_state.pad_lstick_y = -dy; + } else if (stick_ == 1) { + input_state.pad_rstick_x = dx; + input_state.pad_rstick_y = -dy; + } + + } else { + dragging_[i] = false; + } +skip: + lastPointerDown_[i] = input_state.pointer_down[i]; + } + + stick_delta_x_ = input_state.pad_lstick_x; + stick_delta_y_ = -input_state.pad_lstick_y; +} + +void TouchStick::draw(DrawBuffer &db, uint32_t color) +{ + if (bgImageIndex_ != -1) + db.DrawImage(bgImageIndex_, stick_x_, stick_y_, 1.0f * scale_, color, ALIGN_CENTER); + db.DrawImage(stickImageIndex_, stick_x_ + stick_delta_x_ * stick_size_ * scale_, stick_y_ + stick_delta_y_ * stick_size_ * scale_, 1.0f * scale_, color, ALIGN_CENTER); +} diff --git a/ext/native/ui/virtual_input.h b/ext/native/ui/virtual_input.h new file mode 100644 index 0000000000..a383cd467b --- /dev/null +++ b/ext/native/ui/virtual_input.h @@ -0,0 +1,114 @@ +#pragma once + +#include "math/math_util.h" +#include "gfx/texture_atlas.h" + +class DrawBuffer; + +// Multitouch-enabled emulation of a hardware button. +// Many of these can be pressed simultaneously with multitouch. +// (any finger will work, simultaneously with other virtual button/stick actions). +class TouchButton +{ +public: + TouchButton(const Atlas *atlas, int imageIndex, int overlayImageIndex, int button, int rotationAngle = 0, bool mirror_h = false); + + void update(InputState &input_state); + void draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay); + + void setPos(float x, float y, float scale = 1.0f) { + scale_ = scale; + x_ = x - w_ * scale / 2; + y_ = y - h_ * scale / 2; + } + +private: + virtual bool isInside(float px, float py) const + { + float margin = 5.0f; + return px >= x_ - margin * scale_ && py >= y_ - margin * scale_ && px <= x_ + (w_ + margin) * scale_ && py <= y_ + (h_ + margin) * scale_; + } + + const Atlas *atlas_; + + int imageIndex_; + int overlayImageIndex_; + int button_; + float rotationAngle_; + bool mirror_h_; + + float x_, y_; + float w_; + float h_; + float scale_; + + bool isDown_; + + // TODO: simplify into flags. + bool pointerDown[MAX_POINTERS]; +}; + +// 4-in-one directional pad, with support for single touch diagonals. +class TouchCrossPad +{ +public: + TouchCrossPad(const Atlas *atlas, int arrowIndex, int overlayIndex); + + void update(InputState &input_state); + void draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay); + + void setPos(float x, float y, float radius, float scale = 1.0f) { + x_ = x; + y_ = y; + radius_ = radius; + scale_ = scale; + } + +private: + const Atlas *atlas_; + + float x_; + float y_; + float radius_; + float scale_; + + int arrowIndex_; + int overlayIndex_; + int down_; +}; + + +// Multi-touch enabled virtual joystick +// Many of these can be used simultaneously with multitouch. +// (any finger will work, simultaneously with other virtual button/stick actions). +class TouchStick +{ +public: + TouchStick(const Atlas *atlas, int bgImageIndex, int stickImageIndex, int stick); + + void update(InputState &input_state); + void draw(DrawBuffer &db, uint32_t color); + + void setPos(float x, float y, float scale = 1.0f) { + stick_x_ = x; + stick_y_ = y; + scale_ = scale; + } + +private: + const Atlas *atlas_; + int bgImageIndex_; + int stickImageIndex_; + int stick_; + int stick_size_; + float stick_x_; + float stick_y_; + float scale_; + bool dragging_[MAX_POINTERS]; + bool lastPointerDown_[MAX_POINTERS]; + + // maintained for drawing only + float stick_delta_x_; + float stick_delta_y_; +}; + diff --git a/ext/native/util/CMakeLists.txt b/ext/native/util/CMakeLists.txt new file mode 100644 index 0000000000..34e4dd907e --- /dev/null +++ b/ext/native/util/CMakeLists.txt @@ -0,0 +1,16 @@ +set(SRCS + bits/bits.cpp + bits/varint.cpp + random/perlin.cpp + hash/hash.cpp + text/utf8.cpp +) + +set(SRCS ${SRCS}) + +add_library(util STATIC ${SRCS}) + +if(UNIX) + add_definitions(-fPIC) +endif(UNIX) + diff --git a/ext/native/util/bits/bits.cpp b/ext/native/util/bits/bits.cpp new file mode 100644 index 0000000000..d8bf9d1296 --- /dev/null +++ b/ext/native/util/bits/bits.cpp @@ -0,0 +1,40 @@ +#include "util/bits/bits.h" + +namespace bits { + +// See http://graphics.stanford.edu/~seander/bithacks.html + +static const unsigned char BitsSetTable256[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +int CountBits8(uint8_t v) { + return BitsSetTable256[v]; +} + +int CountBits16(uint16_t v) { + return BitsSetTable256[v & 0xFF] + BitsSetTable256[v >> 8]; +} + +int CountBits32(uint32_t v) { + v = v - ((v >> 1) & 0x55555555); // reuse input as temporary + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp + return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count +} + +} // namespace bits diff --git a/ext/native/util/bits/bits.h b/ext/native/util/bits/bits.h new file mode 100644 index 0000000000..0c1b630f9b --- /dev/null +++ b/ext/native/util/bits/bits.h @@ -0,0 +1,65 @@ +#ifndef _UTIL_BITS_BITS +#define _UTIL_BITS_BITS + +#include "base/basictypes.h" + +namespace bits { + +int CountBits8(uint8_t v); +int CountBits16(uint16_t v); +int CountBits32(uint32_t v); + +// where mask is 0, the result is a. +// where mask is 1, the result is b. +inline uint32_t MixBits(uint32_t a, uint32_t b, uint32_t mask) { + return a ^ ((a ^ b) & mask); +} + +inline uint32_t ComputeParity(uint32_t v) { + v ^= v >> 16; + v ^= v >> 8; + v ^= v >> 4; + v &= 0xf; + return (0x6996 >> v) & 1; +} + +} // namespace bits + +#ifndef _MSC_VER + +// These are built-ins in MSVC, let's define them for other OS:es as well. + +inline uint32_t _rotl(uint32_t val, int shift) { + return (val << shift) | (val >> (31 - shift)); +} + +inline uint32_t _rotr(uint32_t val, int shift) { + return (val << shift) | (val >> (31 - shift)); +} + +/* +template +class BitArray { +public: + BitArray() { + memset(data, 0, sizeof(data)); + } + + BitArray And(const BitArray &other) { + BitArray retVal; + for (int i = 0; i < DATACOUNT; i++) { + retVal.data[i] = data[i] & other.data[i]; + } + } + +private: + uint32 data[(SZ + 31) / 32]; + enum { + DATACOUNT = (SZ + 31) / 32; + }; +}; +*/ + +#endif + +#endif diff --git a/ext/native/util/bits/hamming.h b/ext/native/util/bits/hamming.h new file mode 100644 index 0000000000..82217a8376 --- /dev/null +++ b/ext/native/util/bits/hamming.h @@ -0,0 +1,27 @@ +#ifndef _UTIL_BITS_HAMMING +#define _UTIL_BITS_HAMMING + +#include + +#include "base/logging.h" + +inline int Hamming(const std::string &a, const std::string &b) { + CHECK_EQ(a.size(), b.size()); + int hamming = 0; + for (size_t i = 0; i < a.size(); i++) + hamming += a[i] == b[i]; + return hamming; +} + +inline int Hamming4(const std::string &a, const std::string &b) { + CHECK_EQ(a.size(), b.size()); + int hamming = 0; + const uint32 *au = (const uint32 *)a.data(); + const uint32 *bu = (const uint32 *)b.data(); + for (size_t i = 0; i < a.size() / 4; i++) + hamming += au[i] == bu[i]; + return hamming * 4; +} + + +#endif // _UTIL_BITS_HAMMING diff --git a/ext/native/util/bits/varint.cpp b/ext/native/util/bits/varint.cpp new file mode 100644 index 0000000000..2992599e72 --- /dev/null +++ b/ext/native/util/bits/varint.cpp @@ -0,0 +1,35 @@ +#include "util/bits/varint.h" + +namespace varint { + +void Encode32(uint32_t value, char **dest) { + // Simple varint + char *p = *dest; + while (value > 127) { + *p++ = (value & 127); + value >>= 7; + } + *p++ = value | 0x80; + *dest = p; +} + +uint32_t Decode32(const char **ptr) { + uint32_t value = 0; + const char *p = *ptr; + while (true) { + uint8_t b = *p++; + if (b & 0x80) { + *ptr = p; + return value | (b & 0x7F); + } else { + value |= *p++; + value <<= 7; + } + } + *ptr = p; + return value; +} + +} // namespace varint + + diff --git a/ext/native/util/bits/varint.h b/ext/native/util/bits/varint.h new file mode 100644 index 0000000000..e2fdd20583 --- /dev/null +++ b/ext/native/util/bits/varint.h @@ -0,0 +1,13 @@ +#ifndef _UTIL_BITS_VARINT +#define _UTIL_BITS_VARINT + +#include "base/basictypes.h" + +namespace varint { + +void Encode32(uint32_t value, char **dest); +uint32_t Decode32(const char **ptr); + +} // namespace varint + +#endif // _UTIL_BITS_VARINT diff --git a/ext/native/util/const_map.h b/ext/native/util/const_map.h new file mode 100644 index 0000000000..6b1fe0e165 --- /dev/null +++ b/ext/native/util/const_map.h @@ -0,0 +1,24 @@ +#pragma once + +template +class InitConstMap +{ +private: + std::map m_map; +public: + InitConstMap(const T& key, const U& val) + { + m_map[key] = val; + } + + InitConstMap& operator()(const T& key, const U& val) + { + m_map[key] = val; + return *this; + } + + operator std::map() + { + return m_map; + } +}; diff --git a/ext/native/util/hash/hash.cpp b/ext/native/util/hash/hash.cpp new file mode 100644 index 0000000000..3ebaea7d02 --- /dev/null +++ b/ext/native/util/hash/hash.cpp @@ -0,0 +1,65 @@ +#include "base/basictypes.h" +#include "util/hash/hash.h" + +namespace hash { + +// uint32_t +// WARNING - may read one more byte! Fine if the input is a null-terminated string. +// Implementation from Wikipedia. +uint32_t Fletcher(const uint8_t *data_uint8, size_t length) { + const uint16_t *data = (const uint16_t *)data_uint8; + size_t len = (length + 1) / 2; + uint32_t sum1 = 0xffff, sum2 = 0xffff; + + while (len) { + size_t tlen = len > 360 ? 360 : len; + len -= tlen; + + do { + sum1 += *data++; + sum2 += sum1; + } while (--tlen); + + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + } + + /* Second reduction step to reduce sums to 16 bits */ + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + return sum2 << 16 | sum1; +} + +// Implementation from Wikipedia +// Slightly slower than Fletcher above, but slighly more reliable. +#define MOD_ADLER 65521 +// data: Pointer to the data to be summed; len is in bytes +uint32_t Adler32(const uint8_t *data, size_t len) { + uint32_t a = 1, b = 0; + while (len) { + size_t tlen = len > 5550 ? 5550 : len; + len -= tlen; + do { + a += *data++; + b += a; + } while (--tlen); + + a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); + b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); + } + + // It can be shown that a <= 0x1013a here, so a single subtract will do. + if (a >= MOD_ADLER) { + a -= MOD_ADLER; + } + + // It can be shown that b can reach 0xfff87 here. + b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); + + if (b >= MOD_ADLER) { + b -= MOD_ADLER; + } + return (b << 16) | a; +} + +} // namespace hash diff --git a/ext/native/util/hash/hash.h b/ext/native/util/hash/hash.h new file mode 100644 index 0000000000..0c7ac64326 --- /dev/null +++ b/ext/native/util/hash/hash.h @@ -0,0 +1,15 @@ +#ifndef _UTIL_HASH_HASH_H +#define _UTIL_HASH_HASH_H + +#include + +#include "base/basictypes.h" + +namespace hash { + +uint32_t Fletcher(const uint8_t *data_u8, size_t length); // FAST. Length & 1 == 0. +uint32_t Adler32(const uint8_t *data, size_t len); // Fairly accurate, slightly slower + +} // namespace hash + +#endif diff --git a/ext/native/util/random/perlin.cpp b/ext/native/util/random/perlin.cpp new file mode 100644 index 0000000000..e8a8a578df --- /dev/null +++ b/ext/native/util/random/perlin.cpp @@ -0,0 +1,72 @@ +#include "util/random/perlin.h" + +#include + +// This should go in the const section of the binary. +static const int p[512] = { + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, +}; + +inline float fade(float t) { + return t * t * t * (t * (t * 6 - 15) + 10); +} + +inline float lerp(float t, float a, float b) { + return a + t * (b - a); +} + +inline float grad(int hash, float x, float y, float z) { + int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE + float u = h < 8 ? x : y; // INTO 12 GRADIENT DIRECTIONS. + float v = h < 4 ? y : (h == 12 || h == 14 ? x : z); + return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); +} + +float Noise(double iz, double iy, double ix) { + double fx = floor(ix), fy = floor(iy), fz = floor(iz); + int X = (int)fx & 255, // FIND UNIT CUBE THAT + Y = (int)fy & 255, // CONTAINS POINT. + Z = (int)fz & 255; + float x = (float)(ix - fx); // FIND RELATIVE X,Y,Z + float y = (float)(iy - fy); // OF POINT IN CUBE. + float z = (float)(iz - fz); + float u = fade(x); // COMPUTE FADE CURVES + float v = fade(y); // FOR EACH OF X,Y,Z. + float w = fade(z); + int A = p[X ]+Y, B = p[X+1]+Y; + int AA = p[A]+Z, AB = p[A+1]+Z; // HASH COORDINATES OF + int BA = p[B]+Z, BB = p[B+1]+Z; // THE 8 CUBE CORNERS, + return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD + grad(p[BA ], x-1, y , z )), // BLENDED + lerp(u, grad(p[AB ], x , y-1, z ), // RESULTS + grad(p[BB ], x-1, y-1, z ))), // FROM 8 + lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), // CORNERS + grad(p[BA+1], x-1, y , z-1 )), // OF CUBE + lerp(u, grad(p[AB+1], x , y-1, z-1 ), + grad(p[BB+1], x-1, y-1, z-1 )))); +} diff --git a/ext/native/util/random/perlin.h b/ext/native/util/random/perlin.h new file mode 100644 index 0000000000..ecda001c23 --- /dev/null +++ b/ext/native/util/random/perlin.h @@ -0,0 +1,6 @@ +#pragma once + +// Implementation of "Improved Noise" +// http://mrl.nyu.edu/~perlin/noise/ +// doubles are only used at the very start, not a big performance worry +float Noise(double x, double y, double z); diff --git a/ext/native/util/random/rng.h b/ext/native/util/random/rng.h new file mode 100644 index 0000000000..15ace2bb71 --- /dev/null +++ b/ext/native/util/random/rng.h @@ -0,0 +1,71 @@ +#pragma once + +#include "base/basictypes.h" + +// George Marsaglia-style random number generator. +class GMRng { +public: + GMRng() { + m_w = 0x23E866ED; + m_z = 0x80FD5AF2; + } + void Init(int seed) { + m_w = seed ^ (seed << 16); + if (!m_w) m_w = 1337; + m_z = ~seed; + if (!m_z) m_z = 31337; + } + uint32_t R32() { + m_z = 36969 * (m_z & 65535) + (m_z >> 16); + m_w = 18000 * (m_w & 65535) + (m_w >> 16); + return (m_z << 16) + m_w; + } + float F() { + return (float)R32() / (float)(0xFFFFFFFF); + } + + // public for easy save/load. Yes a bit ugly but better than moving DoState into native. + uint32_t m_w; + uint32_t m_z; +}; + + +// Data must consist only of the index and the twister array. This matches the PSP +// MT context exactly. +class MersenneTwister { +public: + MersenneTwister(uint32_t seed) : index_(0) { + mt_[0] = seed; + for (uint32_t i = 1; i < MT_SIZE; i++) + mt_[i] = (1812433253UL * (mt_[i - 1] ^ (mt_[i - 1] >> 30)) + i); + } + + uint32_t R32() { + if (index_ == 0) + gen(); + uint32_t y = mt_[index_]; + y ^= y >> 11; + y ^= (y << 7) & 2636928640UL; + y ^= (y << 15) & 4022730752UL; + y ^= y >> 18; + index_ = (index_ + 1) % MT_SIZE; + return y; + } + +private: + enum { + MT_SIZE = 624, + }; + + uint32_t index_; + uint32_t mt_[MT_SIZE]; + + void gen() { + for(uint32_t i = 0; i < MT_SIZE; i++){ + uint32_t y = (mt_[i] & 0x80000000) + (mt_[(i + 1) % MT_SIZE] & 0x80000000); + mt_[i] = mt_[(i + 397) % MT_SIZE] ^ (y >> 1); + if (y % 2) mt_[i] ^= 2567483615UL; + } + return; + } +}; diff --git a/ext/native/util/text/parsers.cpp b/ext/native/util/text/parsers.cpp new file mode 100644 index 0000000000..42af1da916 --- /dev/null +++ b/ext/native/util/text/parsers.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include "util/text/parsers.h" + +bool Version::ParseVersionString(std::string str) { + if (str.empty()) + return false; + if (str[0] == 'v') + str = str.substr(1); + return 3 == sscanf(str.c_str(), "%i.%i.%i", &major, &minor, &sub); +} + +std::string Version::ToString() const { + char temp[128]; + sprintf(temp, "%i.%i.%i", major, minor, sub); + return std::string(temp); +} + +bool ParseMacAddress(std::string str, uint8_t macAddr[6]) { + int mac[6]; + if (6 != sscanf(str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5])) { + return false; + } + for (int i = 0; i < 6; i++) { + macAddr[i] = mac[i]; + } + return true; +} \ No newline at end of file diff --git a/ext/native/util/text/parsers.h b/ext/native/util/text/parsers.h new file mode 100644 index 0000000000..7f763cf9b8 --- /dev/null +++ b/ext/native/util/text/parsers.h @@ -0,0 +1,55 @@ +#pragma once + +#include + +#include "base/basictypes.h" + +#undef major +#undef minor + +// Parses version strings of the format "Major.Minor.Sub" and lets you interact with them conveniently. +struct Version { + Version() : major(0), minor(0), sub(0) {} + Version(const std::string &str) { + if (!ParseVersionString(str)) { + major = -1; + minor = -1; + sub = -1; + } + } + + int major; + int minor; + int sub; + + bool IsValid() const { + return sub >= 0 && minor >= 0 && major >= 0; + } + + bool operator == (const Version &other) const { + return major == other.major && minor == other.minor && sub == other.sub; + } + bool operator != (const Version &other) const { + return !(*this == other); + } + + bool operator <(const Version &other) const { + if (major < other.major) return true; + if (major > other.major) return false; + if (minor < other.minor) return true; + if (minor > other.minor) return false; + if (sub < other.sub) return true; + if (sub > other.sub) return false; + return false; + } + + bool operator >=(const Version &other) const { + return !(*this < other); + } + + std::string ToString() const; +private: + bool ParseVersionString(std::string str); +}; + +bool ParseMacAddress(std::string str, uint8_t macAddr[6]); \ No newline at end of file diff --git a/ext/native/util/text/shiftjis.h b/ext/native/util/text/shiftjis.h new file mode 100644 index 0000000000..e92df04db6 --- /dev/null +++ b/ext/native/util/text/shiftjis.h @@ -0,0 +1,140 @@ +#pragma once + +#include "base/basictypes.h" + +// Warning: decodes/encodes JIS, not Unicode. +// Use a table to map. +struct ShiftJIS { + static const uint32_t INVALID = (uint32_t) -1; + + ShiftJIS(const char *c) : c_(c), index_(0) {} + + uint32_t next() { + uint32_t j = (uint8_t)c_[index_++]; + + int row; + bool emojiAdjust = false; + switch (j >> 4) { + case 0x8: + if (j == 0x80) { + return INVALID; + } + // Intentional fall-through. + case 0x9: + case 0xE: + row = ((j & 0x3F) << 1) - 0x01; + break; + + case 0xF: + emojiAdjust = true; + if (j < 0xF4) { + row = ((j & 0x7F) << 1) - 0x59; + } else if (j < 0xFD) { + row = ((j & 0x7F) << 1) - 0x1B; + } else { + return j; + } + break; + + // Anything else (i.e. <= 0x7x, 0xAx, 0xBx, 0xCx, and 0xDx) is JIS X 0201, return directly. + default: + return j; + } + + // Okay, if we didn't return, it's time for the second byte (the cell.) + j = (uint8_t)c_[index_++]; + // Not a valid second byte. + if (j < 0x40 || j == 0x7F || j >= 0xFD) { + return INVALID; + } + + if (j >= 0x9F) { + // This range means the row was even. + ++row; + j -= 0x7E; + } else { + if (j >= 0x80) { + j -= 0x20; + } else { + // Yuck. They wrapped around 0x7F, so we subtract one less. + j -= 0x20 - 1; + } + + if (emojiAdjust) { + // These are shoved in where they'll fit. + if (row == 0x87) { + // First byte was 0xF0. + row = 0x81; + } else if (row == 0x8B) { + // First byte was 0xF2. + row = 0x85; + } else if (row == 0xCD) { + // First byte was 0xF4. + row = 0x8F; + } + } + } + + // j is already the cell + 0x20. + return ((row + 0x20) << 8) | j; + } + + bool end() const { + return c_[index_] == 0; + } + + int length() const { + int len = 0; + for (ShiftJIS dec(c_); !dec.end(); dec.next()) + ++len; + return len; + } + + int byteIndex() const { + return index_; + } + + static int encode(char *dest, uint32_t j) { + int row = (j >> 8) - 0x20; + int offsetCell = j & 0xFF; + + // JIS X 0201. + if ((j & ~0xFF) == 0) { + *dest = j; + return 1; + } + + if (row < 0x3F) { + *dest++ = 0x80 + ((row + 1) >> 1); + } else if (row < 0x5F) { + // Reduce by 0x40 to account for the above range. + *dest++ = 0xE0 + ((row - 0x40 + 1) >> 1); + } else if (row >= 0x80) { + // TODO + } + + if (row & 1) { + if (offsetCell < 0x60) { + // Subtract one to shift around 0x7F. + *dest++ = offsetCell + 0x20 - 1; + } else { + *dest++ = offsetCell + 0x20; + } + } else { + *dest++ = offsetCell + 0x7E; + } + + return 2; + } + + static int encodeUnits(uint32_t j) { + if ((j & ~0xFF) == 0) { + return 1; + } + return 2; + } + +private: + const char *c_; + int index_; +}; \ No newline at end of file diff --git a/ext/native/util/text/utf16.h b/ext/native/util/text/utf16.h new file mode 100644 index 0000000000..2475b7292a --- /dev/null +++ b/ext/native/util/text/utf16.h @@ -0,0 +1,75 @@ +#pragma once + +#include "base/basictypes.h" + +// Should optimize out. +#define UTF16_IS_LITTLE_ENDIAN (*(const uint16_t *)"\0\xff" >= 0x100) + +template +uint16_t UTF16_Swap(uint16_t u) { + if (is_little) { + return UTF16_IS_LITTLE_ENDIAN ? u : swap16(u); + } else { + return UTF16_IS_LITTLE_ENDIAN ? swap16(u) : u; + } +} + +template +struct UTF16_Type { +public: + static const uint32_t INVALID = (uint32_t)-1; + + UTF16_Type(const uint16_t *c) : c_(c), index_(0) {} + + uint32_t next() { + const uint32_t u = UTF16_Swap(c_[index_++]); + + // Surrogate pair. UTF-16 is so simple. We assume it's valid. + if ((u & 0xF800) == 0xD800) { + return 0x10000 + (((u & 0x3FF) << 10) | (UTF16_Swap(c_[index_++]) & 0x3FF)); + } + return u; + } + + bool end() const { + return c_[index_] == 0; + } + + int length() const { + int len = 0; + for (UTF16_Type dec(c_); !dec.end(); dec.next()) + ++len; + return len; + } + + int shortIndex() const { + return index_; + } + + static int encode(uint16_t *dest, uint32_t u) { + if (u >= 0x10000) { + u -= 0x10000; + *dest++ = UTF16_Swap(0xD800 + ((u >> 10) & 0x3FF)); + *dest = UTF16_Swap(0xDC00 + ((u >> 0) & 0x3FF)); + return 2; + } else { + *dest = UTF16_Swap((uint16_t)u); + return 1; + } + } + + static int encodeUnits(uint32_t u) { + if (u >= 0x10000) { + return 2; + } else { + return 1; + } + } + +private: + const uint16_t *c_; + int index_; +}; + +typedef UTF16_Type UTF16LE; +typedef UTF16_Type UTF16BE; diff --git a/ext/native/util/text/utf8.cpp b/ext/native/util/text/utf8.cpp new file mode 100644 index 0000000000..33e780d663 --- /dev/null +++ b/ext/native/util/text/utf8.cpp @@ -0,0 +1,511 @@ +/* + Basic UTF-8 manipulation routines + by Jeff Bezanson + placed in the public domain Fall 2005 + + This code is designed to provide the utilities you need to manipulate + UTF-8 as an internal string encoding. These functions do not perform the + error checking normally needed when handling UTF-8 data, so if you happen + to be from the Unicode Consortium you will want to flay me alive. + I do this because error checking can be performed at the boundaries (I/O), + with these routines reserved for higher performance on data known to be + valid. +*/ + +#ifdef _WIN32 +#include +#undef min +#undef max +#endif + +#include +#include +#include +#include + +#include +#include + +#include "base/basictypes.h" +#include "utf8.h" +#include "utf16.h" + +// is start of UTF sequence +inline bool isutf(char c) { + return (c & 0xC0) != 0x80; +} + +static const uint32_t offsetsFromUTF8[6] = { + 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL +}; + +static const uint8_t trailingBytesForUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5, +}; + +/* returns length of next utf-8 sequence */ +int u8_seqlen(const char *s) +{ + return trailingBytesForUTF8[(unsigned int)(unsigned char)s[0]] + 1; +} + +/* conversions without error checking + only works for valid UTF-8, i.e. no 5- or 6-byte sequences + srcsz = source size in bytes, or -1 if 0-terminated + sz = dest size in # of wide characters + + returns # characters converted + dest will always be L'\0'-terminated, even if there isn't enough room + for all the characters. + if sz = srcsz+1 (i.e. 4*srcsz+4 bytes), there will always be enough space. +*/ +int u8_toucs(uint32_t *dest, int sz, const char *src, int srcsz) +{ + uint32_t ch; + const char *src_end = src + srcsz; + int nb; + int i=0; + + while (i < sz-1) { + nb = trailingBytesForUTF8[(unsigned char)*src]; + if (srcsz == -1) { + if (*src == 0) + goto done_toucs; + } + else { + if (src + nb >= src_end) + goto done_toucs; + } + ch = 0; + switch (nb) { + /* these fall through deliberately */ + case 3: ch += (unsigned char)*src++; ch <<= 6; + case 2: ch += (unsigned char)*src++; ch <<= 6; + case 1: ch += (unsigned char)*src++; ch <<= 6; + case 0: ch += (unsigned char)*src++; + } + ch -= offsetsFromUTF8[nb]; + dest[i++] = ch; + } + done_toucs: + dest[i] = 0; + return i; +} + +/* srcsz = number of source characters, or -1 if 0-terminated + sz = size of dest buffer in bytes + + returns # characters converted + dest will only be '\0'-terminated if there is enough space. this is + for consistency; imagine there are 2 bytes of space left, but the next + character requires 3 bytes. in this case we could NUL-terminate, but in + general we can't when there's insufficient space. therefore this function + only NUL-terminates if all the characters fit, and there's space for + the NUL as well. + the destination string will never be bigger than the source string. +*/ +int u8_toutf8(char *dest, int sz, uint32_t *src, int srcsz) +{ + uint32_t ch; + int i = 0; + char *dest_end = dest + sz; + + while (srcsz<0 ? src[i]!=0 : i < srcsz) { + ch = src[i]; + if (ch < 0x80) { + if (dest >= dest_end) + return i; + *dest++ = (char)ch; + } + else if (ch < 0x800) { + if (dest >= dest_end-1) + return i; + *dest++ = (ch>>6) | 0xC0; + *dest++ = (ch & 0x3F) | 0x80; + } + else if (ch < 0x10000) { + if (dest >= dest_end-2) + return i; + *dest++ = (ch>>12) | 0xE0; + *dest++ = ((ch>>6) & 0x3F) | 0x80; + *dest++ = (ch & 0x3F) | 0x80; + } + else if (ch < 0x110000) { + if (dest >= dest_end-3) + return i; + *dest++ = (ch>>18) | 0xF0; + *dest++ = ((ch>>12) & 0x3F) | 0x80; + *dest++ = ((ch>>6) & 0x3F) | 0x80; + *dest++ = (ch & 0x3F) | 0x80; + } + i++; + } + if (dest < dest_end) + *dest = '\0'; + return i; +} + +int u8_wc_toutf8(char *dest, uint32_t ch) +{ + if (ch < 0x80) { + dest[0] = (char)ch; + return 1; + } + if (ch < 0x800) { + dest[0] = (ch>>6) | 0xC0; + dest[1] = (ch & 0x3F) | 0x80; + return 2; + } + if (ch < 0x10000) { + dest[0] = (ch>>12) | 0xE0; + dest[1] = ((ch>>6) & 0x3F) | 0x80; + dest[2] = (ch & 0x3F) | 0x80; + return 3; + } + if (ch < 0x110000) { + dest[0] = (ch>>18) | 0xF0; + dest[1] = ((ch>>12) & 0x3F) | 0x80; + dest[2] = ((ch>>6) & 0x3F) | 0x80; + dest[3] = (ch & 0x3F) | 0x80; + return 4; + } + return 0; +} + +/* charnum => byte offset */ +int u8_offset(const char *str, int charnum) +{ + int offs=0; + + while (charnum > 0 && str[offs]) { + (void)(isutf(str[++offs]) || isutf(str[++offs]) || + isutf(str[++offs]) || ++offs); + charnum--; + } + return offs; +} + +/* byte offset => charnum */ +int u8_charnum(const char *s, int offset) +{ + int charnum = 0, offs=0; + + while (offs < offset && s[offs]) { + (void)(isutf(s[++offs]) || isutf(s[++offs]) || + isutf(s[++offs]) || ++offs); + charnum++; + } + return charnum; +} + +/* number of characters */ +int u8_strlen(const char *s) +{ + int count = 0; + int i = 0; + + while (u8_nextchar(s, &i) != 0) + count++; + + return count; +} + +/* reads the next utf-8 sequence out of a string, updating an index */ +uint32_t u8_nextchar(const char *s, int *i) +{ + uint32_t ch = 0; + int sz = 0; + + do { + ch <<= 6; + ch += (unsigned char)s[(*i)++]; + sz++; + } while (s[*i] && !isutf(s[*i])); + ch -= offsetsFromUTF8[sz-1]; + + return ch; +} + +void u8_inc(const char *s, int *i) +{ + (void)(isutf(s[++(*i)]) || isutf(s[++(*i)]) || + isutf(s[++(*i)]) || ++(*i)); +} + +void u8_dec(const char *s, int *i) +{ + (void)(isutf(s[--(*i)]) || isutf(s[--(*i)]) || + isutf(s[--(*i)]) || --(*i)); +} + +int octal_digit(char c) +{ + return (c >= '0' && c <= '7'); +} + +int hex_digit(char c) +{ + return ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'F') || + (c >= 'a' && c <= 'f')); +} + +/* assumes that src points to the character after a backslash + returns number of input characters processed */ +int u8_read_escape_sequence(const char *str, uint32_t *dest) +{ + long ch; + char digs[9]="\0\0\0\0\0\0\0\0"; + int dno=0, i=1; + + ch = (uint32_t)str[0]; /* take literal character */ + if (str[0] == 'n') + ch = L'\n'; + else if (str[0] == 't') + ch = L'\t'; + else if (str[0] == 'r') + ch = L'\r'; + else if (str[0] == 'b') + ch = L'\b'; + else if (str[0] == 'f') + ch = L'\f'; + else if (str[0] == 'v') + ch = L'\v'; + else if (str[0] == 'a') + ch = L'\a'; + else if (octal_digit(str[0])) { + i = 0; + do { + digs[dno++] = str[i++]; + } while (octal_digit(str[i]) && dno < 3); + ch = strtol(digs, NULL, 8); + } + else if (str[0] == 'x') { + while (hex_digit(str[i]) && dno < 2) { + digs[dno++] = str[i++]; + } + if (dno > 0) + ch = strtol(digs, NULL, 16); + } + else if (str[0] == 'u') { + while (hex_digit(str[i]) && dno < 4) { + digs[dno++] = str[i++]; + } + if (dno > 0) + ch = strtol(digs, NULL, 16); + } + else if (str[0] == 'U') { + while (hex_digit(str[i]) && dno < 8) { + digs[dno++] = str[i++]; + } + if (dno > 0) + ch = strtol(digs, NULL, 16); + } + *dest = (uint32_t)ch; + + return i; +} + +/* convert a string with literal \uxxxx or \Uxxxxxxxx characters to UTF-8 + example: u8_unescape(mybuf, 256, "hello\\u220e") + note the double backslash is needed if called on a C string literal */ +int u8_unescape(char *buf, int sz, char *src) +{ + int c=0, amt; + uint32_t ch; + char temp[4]; + + while (*src && c < sz) { + if (*src == '\\') { + src++; + amt = u8_read_escape_sequence(src, &ch); + } + else { + ch = (uint32_t)*src; + amt = 1; + } + src += amt; + amt = u8_wc_toutf8(temp, ch); + if (amt > sz-c) + break; + memcpy(&buf[c], temp, amt); + c += amt; + } + if (c < sz) + buf[c] = '\0'; + return c; +} + +const char *u8_strchr(const char *s, uint32_t ch, int *charn) +{ + int i = 0, lasti=0; + uint32_t c; + + *charn = 0; + while (s[i]) { + c = u8_nextchar(s, &i); + if (c == ch) { + return &s[lasti]; + } + lasti = i; + (*charn)++; + } + return NULL; +} + +const char *u8_memchr(const char *s, uint32_t ch, size_t sz, int *charn) +{ + size_t i = 0, lasti=0; + uint32_t c; + int csz; + + *charn = 0; + while (i < sz) { + c = csz = 0; + do { + c <<= 6; + c += (unsigned char)s[i++]; + csz++; + } while (i < sz && !isutf(s[i])); + c -= offsetsFromUTF8[csz-1]; + + if (c == ch) { + return &s[lasti]; + } + lasti = i; + (*charn)++; + } + return NULL; +} + +int u8_is_locale_utf8(const char *locale) +{ + /* this code based on libutf8 */ + const char* cp = locale; + + for (; *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ','; cp++) { + if (*cp == '.') { + const char* encoding = ++cp; + for (; *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ','; cp++) + ; + if ((cp-encoding == 5 && !strncmp(encoding, "UTF-8", 5)) + || (cp-encoding == 4 && !strncmp(encoding, "utf8", 4))) + return 1; /* it's UTF-8 */ + break; + } + } + return 0; +} + +int UTF8StringNonASCIICount(const char *utf8string) { + UTF8 utf(utf8string); + int count = 0; + while (!utf.end()) { + int c = utf.next(); + if (c > 127) + ++count; + } + return count; +} + +bool UTF8StringHasNonASCII(const char *utf8string) { + return UTF8StringNonASCIICount(utf8string) > 0; +} + +#ifdef _WIN32 + +std::string ConvertWStringToUTF8(const wchar_t *wstr) { + int len = (int)wcslen(wstr); + int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); + std::string s; + s.resize(size); + if (size > 0) { + WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); + } + return s; +} + +std::string ConvertWStringToUTF8(const std::wstring &wstr) { + int len = (int)wstr.size(); + int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); + std::string s; + s.resize(size); + if (size > 0) { + WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); + } + return s; +} + +void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { + int len = (int)source.size(); + int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); + MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); +} + +std::wstring ConvertUTF8ToWString(const std::string &source) { + int len = (int)source.size(); + int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); + std::wstring str; + str.resize(size); + if (size > 0) { + MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size); + } + return str; +} + +#else + +static size_t ConvertUTF8ToWStringInternal(wchar_t *dest, size_t destSize, const std::string &source) { + const wchar_t *const orig = dest; + const wchar_t *const destEnd = dest + destSize; + + UTF8 utf(source.c_str()); + + if (sizeof(wchar_t) == 2) { + uint16_t *destw = (uint16_t *)dest; + const uint16_t *const destwEnd = destw + destSize; + while (uint32_t c = utf.next()) { + if (destw + UTF16LE::encodeUnits(c) >= destwEnd) { + break; + } + destw += UTF16LE::encode(destw, c); + } + } else { + while (uint32_t c = utf.next()) { + if (dest + 1 >= destEnd) { + break; + } + *dest++ = c; + } + } + + // No ++ to not count the terminal in length. + if (dest < destEnd) { + *dest = 0; + } + + return dest - orig; +} + +void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { + ConvertUTF8ToWStringInternal(dest, destSize, source); +} + +std::wstring ConvertUTF8ToWString(const std::string &source) { + std::wstring dst; + // utf-8 won't be less bytes than there are characters. But need +1 for terminator. + dst.resize(source.size() + 1, 0); + size_t realLen = ConvertUTF8ToWStringInternal(&dst[0], source.size() + 1, source); + dst.resize(realLen); + return dst; +} + +#endif diff --git a/ext/native/util/text/utf8.h b/ext/native/util/text/utf8.h new file mode 100644 index 0000000000..70dbf80b07 --- /dev/null +++ b/ext/native/util/text/utf8.h @@ -0,0 +1,90 @@ +/* + Basic UTF-8 manipulation routines + by Jeff Bezanson + placed in the public domain Fall 2005 + + This code is designed to provide the utilities you need to manipulate + UTF-8 as an internal string encoding. These functions do not perform the + error checking normally needed when handling UTF-8 data, so if you happen + to be from the Unicode Consortium you will want to flay me alive. + I do this because error checking can be performed at the boundaries (I/O), + with these routines reserved for higher performance on data known to be + valid. +*/ + +// Further modified, and C++ stuff added, by hrydgard@gmail.com. + +#pragma once + +#include "base/basictypes.h" +#include + +uint32_t u8_nextchar(const char *s, int *i); +int u8_wc_toutf8(char *dest, uint32_t ch); +int u8_strlen(const char *s); +void u8_inc(const char *s, int *i); +void u8_dec(const char *s, int *i); + +class UTF8 { +public: + static const uint32_t INVALID = (uint32_t)-1; + UTF8(const char *c) : c_(c), index_(0) {} + UTF8(const char *c, int index) : c_(c), index_(index) {} + bool end() const { return c_[index_] == 0; } + uint32_t next() { + return u8_nextchar(c_, &index_); + } + uint32_t peek() { + int tempIndex = index_; + return u8_nextchar(c_, &tempIndex); + } + void fwd() { + u8_inc(c_, &index_); + } + void bwd() { + u8_dec(c_, &index_); + } + int length() const { + return u8_strlen(c_); + } + int byteIndex() const { + return index_; + } + static int encode(char *dest, uint32_t ch) { + return u8_wc_toutf8(dest, ch); + } + static int encodeUnits(uint32_t ch) { + if (ch < 0x80) { + return 1; + } else if (ch < 0x800) { + return 2; + } else if (ch < 0x10000) { + return 3; + } else if (ch < 0x110000) { + return 4; + } + return 0; + } + +private: + const char *c_; + int index_; +}; + +int UTF8StringNonASCIICount(const char *utf8string); + +bool UTF8StringHasNonASCII(const char *utf8string); + + +// UTF8 to Win32 UTF-16 +// Should be used when calling Win32 api calls +#ifdef _WIN32 + +std::string ConvertWStringToUTF8(const std::wstring &wstr); +std::string ConvertWStringToUTF8(const wchar_t *wstr); + +#endif + +// Dest size in units, not bytes. +void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source); +std::wstring ConvertUTF8ToWString(const std::string &source);