Browse Source

first commit

Iver 2 months ago
parent
commit
60a93b7519
47 changed files with 2095 additions and 22059 deletions
  1. 12 2
      .vscode/settings.json
  2. 5 5
      Makefile
  3. BIN
      builds/final binaries/librasteriver.so
  4. BIN
      builds/final binaries/main.bin
  5. BIN
      builds/librasteriver.so
  6. BIN
      builds/main.bin
  7. 1 1
      dbg
  8. 59 0
      errcodes.txt
  9. 193 0
      main.c
  10. 0 12
      objects/cube.mtl
  11. 0 46
      objects/error_object.obj
  12. 0 974
      objects/gourd.obj
  13. 0 46
      objects/obj_file.obj
  14. 0 46
      objects/rotated_cube.obj
  15. 0 9965
      objects/teapot.obj
  16. 0 12
      objects/test_guy.mtl
  17. 0 12
      objects/test_guy_hd.mtl
  18. 0 427
      objects/test_guy_hd.obj
  19. 13 0
      pocl.log
  20. 0 92
      readme.md
  21. 1 1
      run
  22. 0 210
      src/RasterIver/headers/bugMath.h
  23. 0 82
      src/RasterIver/headers/object.h
  24. 0 172
      src/RasterIver/headers/rasteriver.h
  25. 0 7988
      src/RasterIver/headers/stb_image.h
  26. 0 526
      src/RasterIver/kernels/master_kernel.cl
  27. 0 152
      src/RasterIver/kernels/non_master_kernel.cl
  28. 0 215
      src/RasterIver/kernels/transformer.cl
  29. 0 196
      src/RasterIver/source code/non-lib src/main_CPU.c
  30. 0 292
      src/RasterIver/source code/non-lib src/main_GPU_fixed_polygons.c
  31. 0 253
      src/RasterIver/source code/non-lib src/main_test.c
  32. 0 175
      src/RasterIver/source code/rasteriver.c
  33. 35 0
      src/headers/functions.h
  34. 169 0
      src/headers/math.h
  35. 127 0
      src/headers/memory.h
  36. 8 0
      src/headers/rasteriver.h
  37. 160 0
      src/headers/types.h
  38. 644 0
      src/kernels/kernels.cl
  39. 52 137
      src/launch program/main.c
  40. 615 0
      src/main/main.c
  41. 0 4
      src/scripts/build_all.sh
  42. 0 3
      src/scripts/build_rasteriver.sh
  43. 0 3
      src/scripts/build_test_program.sh
  44. 0 3
      src/scripts/dcopy.sh
  45. 0 6
      src/scripts/debug.sh
  46. BIN
      textures/test_guy_texture_256.png
  47. 1 1
      val

+ 12 - 2
.vscode/settings.json

@@ -13,7 +13,17 @@
         "stdint.h": "c",
         "cmath": "c",
         "time.h": "c",
-        "*.cl": "c",
-        "sdl_ttf.h": "c"
+        "*.cl": "opencl",
+        "sdl_ttf.h": "c",
+        "types.h": "c",
+        "__hash_table": "c",
+        "__locale": "c",
+        "ios": "c",
+        "algorithm": "c",
+        "__node_handle": "c",
+        "chrono": "c",
+        "random": "c",
+        "limits": "c",
+        "queue": "c"
     }
 }

+ 5 - 5
Makefile

@@ -1,13 +1,13 @@
 COMPILER=gcc
 FLAGS_ALL=-g -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter
-FLAGS_EXAMPLE=-Lbuilds/final\ binaries -lrasteriver -Wl,-rpath=builds/final\ binaries/ -lm -lSDL2
-FLAGS_LIB=-D CL_TARGET_OPENCL_VERSION=120 -fPIC -shared -lc -lSDL2 -lSDL2_ttf -lm -lOpenCL
+FLAGS_EXAMPLE=-Lbuilds/ -lrasteriver -Wl,-rpath=builds/ -lm -lSDL2
+FLAGS_LIB=-fPIC -shared -lc -lSDL2 -lm -lOpenCL
 
 main.bin: rasteriver.so
-	$(COMPILER) $(FLAGS_ALL) src/launch\ program/main.c -o builds/final\ binaries/main.bin $(FLAGS_EXAMPLE) 
+	$(COMPILER) $(FLAGS_ALL) src/launch\ program/main.c -o builds/main.bin $(FLAGS_EXAMPLE) 
 
 rasteriver.so:
-	$(COMPILER) $(FLAGS_ALL) src/RasterIver/source\ code/rasteriver.c -o builds/final\ binaries/librasteriver.so $(FLAGS_LIB) 
+	$(COMPILER) $(FLAGS_ALL) src/main/main.c -o builds/librasteriver.so $(FLAGS_LIB) 
 
 clean:
-	rm builds/final\ binaries/*
+	rm builds/*

BIN
builds/final binaries/librasteriver.so


BIN
builds/final binaries/main.bin


BIN
builds/librasteriver.so


BIN
builds/main.bin


+ 1 - 1
dbg

@@ -1 +1 @@
-gdb -ex run builds/final\ binaries/main.bin
+gdb -ex run builds/main.bin

+ 59 - 0
errcodes.txt

@@ -0,0 +1,59 @@
+CL_SUCCESS                                  0
+CL_DEVICE_NOT_FOUND                         -1
+CL_DEVICE_NOT_AVAILABLE                     -2
+CL_COMPILER_NOT_AVAILABLE                   -3
+CL_MEM_OBJECT_ALLOCATION_FAILURE            -4
+CL_OUT_OF_RESOURCES                         -5
+CL_OUT_OF_HOST_MEMORY                       -6
+CL_PROFILING_INFO_NOT_AVAILABLE             -7
+CL_MEM_COPY_OVERLAP                         -8
+CL_IMAGE_FORMAT_MISMATCH                    -9
+CL_IMAGE_FORMAT_NOT_SUPPORTED               -10
+CL_BUILD_PROGRAM_FAILURE                    -11
+CL_MAP_FAILURE                              -12
+CL_MISALIGNED_SUB_BUFFER_OFFSET             -13
+CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14
+CL_COMPILE_PROGRAM_FAILURE                  -15
+CL_LINKER_NOT_AVAILABLE                     -16
+CL_LINK_PROGRAM_FAILURE                     -17
+CL_DEVICE_PARTITION_FAILED                  -18
+CL_KERNEL_ARG_INFO_NOT_AVAILABLE            -19
+CL_INVALID_VALUE                            -30
+CL_INVALID_DEVICE_TYPE                      -31
+CL_INVALID_PLATFORM                         -32
+CL_INVALID_DEVICE                           -33
+CL_INVALID_CONTEXT                          -34
+CL_INVALID_QUEUE_PROPERTIES                 -35
+CL_INVALID_COMMAND_QUEUE                    -36
+CL_INVALID_HOST_PTR                         -37
+CL_INVALID_MEM_OBJECT                       -38
+CL_INVALID_IMAGE_FORMAT_DESCRIPTOR          -39
+CL_INVALID_IMAGE_SIZE                       -40
+CL_INVALID_SAMPLER                          -41
+CL_INVALID_BINARY                           -42
+CL_INVALID_BUILD_OPTIONS                    -43
+CL_INVALID_PROGRAM                          -44
+CL_INVALID_PROGRAM_EXECUTABLE               -45
+CL_INVALID_KERNEL_NAME                      -46
+CL_INVALID_KERNEL_DEFINITION                -47
+CL_INVALID_KERNEL                           -48
+CL_INVALID_ARG_INDEX                        -49
+CL_INVALID_ARG_VALUE                        -50
+CL_INVALID_ARG_SIZE                         -51
+CL_INVALID_KERNEL_ARGS                      -52
+CL_INVALID_WORK_DIMENSION                   -53
+CL_INVALID_WORK_GROUP_SIZE                  -54
+CL_INVALID_WORK_ITEM_SIZE                   -55
+CL_INVALID_GLOBAL_OFFSET                    -56
+CL_INVALID_EVENT_WAIT_LIST                  -57
+CL_INVALID_EVENT                            -58
+CL_INVALID_OPERATION                        -59
+CL_INVALID_GL_OBJECT                        -60
+CL_INVALID_BUFFER_SIZE                      -61
+CL_INVALID_MIP_LEVEL                        -62
+CL_INVALID_GLOBAL_WORK_SIZE                 -63
+CL_INVALID_PROPERTY                         -64
+CL_INVALID_IMAGE_DESCRIPTOR                 -65
+CL_INVALID_COMPILER_OPTIONS                 -66
+CL_INVALID_LINKER_OPTIONS                   -67
+CL_INVALID_DEVICE_PARTITION_COUNT           -68

+ 193 - 0
main.c

@@ -0,0 +1,193 @@
+#include <CL/cl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK_ERROR(err, msg) \
+    if (err != CL_SUCCESS) { \
+        fprintf(stderr, "❌ %s failed (%d)\n", msg, err); \
+        exit(EXIT_FAILURE); \
+    }
+
+void print_platform_info(cl_platform_id platform) {
+    char buffer[1024];
+    printf("\n🌍 Platform Info:\n");
+
+    clGetPlatformInfo(platform, CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL);
+    printf("🏷️ Name: %s\n", buffer);
+
+    clGetPlatformInfo(platform, CL_PLATFORM_VENDOR, sizeof(buffer), buffer, NULL);
+    printf("🏢 Vendor: %s\n", buffer);
+
+    clGetPlatformInfo(platform, CL_PLATFORM_VERSION, sizeof(buffer), buffer, NULL);
+    printf("💿 Version: %s\n", buffer);
+
+    clGetPlatformInfo(platform, CL_PLATFORM_PROFILE, sizeof(buffer), buffer, NULL);
+    printf("🧩 Profile: %s\n", buffer);
+
+    printf("\n");
+}
+
+void print_device_info(cl_device_id device) {
+    char name[256], vendor[256], version[256];
+    cl_uint compute_units;
+    cl_ulong global_mem;
+    cl_ulong local_mem;
+    size_t max_wg;
+
+    clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(name), name, NULL);
+    clGetDeviceInfo(device, CL_DEVICE_VENDOR, sizeof(vendor), vendor, NULL);
+    clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(version), version, NULL);
+    clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL);
+    clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(global_mem), &global_mem, NULL);
+    clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(local_mem), &local_mem, NULL);
+    clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(max_wg), &max_wg, NULL);
+
+    printf("🔹 Device: %s\n", name);
+    printf("   Vendor: %s\n", vendor);
+    printf("   Version: %s\n", version);
+    printf("   Compute Units: %u\n", compute_units);
+    printf("   Global Memory: %.2f MB\n", global_mem / (1024.0 * 1024.0));
+    printf("   Local Memory: %.2f KB\n", local_mem / 1024.0);
+    printf("   Max Work Group Size: %zu\n\n", max_wg);
+}
+
+int main(void) {
+    cl_int err;
+
+    printf("🚀 Starting OpenCL diagnostic + compute test\n");
+
+    // 1. Get all platforms
+    cl_uint num_platforms = 0;
+    err = clGetPlatformIDs(0, NULL, &num_platforms);
+    CHECK_ERROR(err, "clGetPlatformIDs(count)");
+
+    cl_platform_id *platforms = malloc(sizeof(cl_platform_id) * num_platforms);
+    err = clGetPlatformIDs(num_platforms, platforms, NULL);
+    CHECK_ERROR(err, "clGetPlatformIDs(list)");
+
+    printf("🌍 Found %u OpenCL platform(s)\n", num_platforms);
+
+    // 2. List platforms and pick POCL if available
+    cl_platform_id chosen_platform = NULL;
+    char pname[256];
+    for (cl_uint i = 0; i < num_platforms; i++) {
+        print_platform_info(platforms[i]);
+        clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(pname), pname, NULL);
+
+        if (strstr(pname, "Portable") || strstr(pname, "pocl") || strstr(pname, "POCL")) {
+            chosen_platform = platforms[i];
+        }
+    }
+
+    if (!chosen_platform) {
+        printf("⚠️  No POCL platform found, using first available.\n");
+        chosen_platform = platforms[0];
+    }
+
+    clGetPlatformInfo(chosen_platform, CL_PLATFORM_NAME, sizeof(pname), pname, NULL);
+    printf("✅ Selected platform: %s\n", pname);
+
+    // 3. Get devices
+    cl_uint num_devices = 0;
+    err = clGetDeviceIDs(chosen_platform, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
+    CHECK_ERROR(err, "clGetDeviceIDs(count)");
+
+    cl_device_id *devices = malloc(sizeof(cl_device_id) * num_devices);
+    err = clGetDeviceIDs(chosen_platform, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
+    CHECK_ERROR(err, "clGetDeviceIDs(list)");
+
+    printf("🧩 Found %u device(s)\n\n", num_devices);
+
+    for (cl_uint i = 0; i < num_devices; i++) {
+        print_device_info(devices[i]);
+    }
+
+    cl_device_id device = devices[0];
+
+    // 4. Create context and queue
+    cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
+    CHECK_ERROR(err, "clCreateContext");
+
+    cl_command_queue queue = clCreateCommandQueue(context, device, 0, &err);
+    CHECK_ERROR(err, "clCreateCommandQueue");
+
+    // 5. Example kernel
+    const char *source =
+        "__kernel void vector_add(__global const float* a, __global const float* b, __global float* c) {"
+        "    int id = get_global_id(0);"
+        "    c[id] = a[id] + b[id];"
+        "}";
+
+    cl_program program = clCreateProgramWithSource(context, 1, &source, NULL, &err);
+    CHECK_ERROR(err, "clCreateProgramWithSource");
+
+    err = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
+    if (err != CL_SUCCESS) {
+        size_t log_size;
+        clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
+        char *log = malloc(log_size);
+        clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, log, NULL);
+        fprintf(stderr, "❌ Build log:\n%s\n", log);
+        free(log);
+        CHECK_ERROR(err, "clBuildProgram");
+    }
+
+    printf("✅ Program built successfully.\n");
+
+    cl_kernel kernel = clCreateKernel(program, "vector_add", &err);
+    CHECK_ERROR(err, "clCreateKernel");
+
+    // 6. Prepare data
+    const int N = 10;
+    float A[N], B[N], C[N];
+    for (int i = 0; i < N; i++) {
+        A[i] = (float)i;
+        B[i] = (float)(N - i);
+    }
+
+    cl_mem bufA = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(A), A, &err);
+    CHECK_ERROR(err, "clCreateBuffer(A)");
+
+    cl_mem bufB = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(B), B, &err);
+    CHECK_ERROR(err, "clCreateBuffer(B)");
+
+    cl_mem bufC = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(C), NULL, &err);
+    CHECK_ERROR(err, "clCreateBuffer(C)");
+
+    // 7. Set kernel args
+    err  = clSetKernelArg(kernel, 0, sizeof(cl_mem), &bufA);
+    err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &bufB);
+    err |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &bufC);
+    CHECK_ERROR(err, "clSetKernelArg");
+
+    // 8. Run kernel
+    size_t global = N;
+    err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, NULL, 0, NULL, NULL);
+    CHECK_ERROR(err, "clEnqueueNDRangeKernel");
+
+    clFinish(queue);
+
+    // 9. Read results
+    err = clEnqueueReadBuffer(queue, bufC, CL_TRUE, 0, sizeof(C), C, 0, NULL, NULL);
+    CHECK_ERROR(err, "clEnqueueReadBuffer");
+
+    printf("\n✅ Kernel executed successfully. Results:\n");
+    for (int i = 0; i < N; i++) {
+        printf("  %.2f + %.2f = %.2f\n", A[i], B[i], C[i]);
+    }
+
+    // 10. Cleanup
+    clReleaseMemObject(bufA);
+    clReleaseMemObject(bufB);
+    clReleaseMemObject(bufC);
+    clReleaseKernel(kernel);
+    clReleaseProgram(program);
+    clReleaseCommandQueue(queue);
+    clReleaseContext(context);
+    free(platforms);
+    free(devices);
+
+    printf("\n🎉 All done!\n");
+    return 0;
+}

+ 0 - 12
objects/cube.mtl

@@ -1,12 +0,0 @@
-# Blender 4.4.3 MTL File: 'None'
-# www.blender.org
-
-newmtl Material
-Ns 250.000000
-Ka 1.000000 1.000000 1.000000
-Kd 0.800000 0.800000 0.800000
-Ks 0.500000 0.500000 0.500000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2

+ 0 - 46
objects/error_object.obj

@@ -1,46 +0,0 @@
-# Blender v2.76 (sub 0) OBJ File: ''
-# www.blender.org
-mtllib cube.mtl
-o Cube
-v 1.000000 -1.000000 -1.000000
-v 1.000000 -1.000000 1.000000
-v -1.000000 -1.000000 1.000000
-v -1.000000 -1.000000 -1.000000
-v 1.000000 1.000000 -0.999999
-v 0.999999 1.000000 1.000001
-v -1.000000 1.000000 1.000000
-v -1.000000 1.000000 -1.000000
-vt 1.000000 0.333333
-vt 1.000000 0.666667
-vt 0.666667 0.666667
-vt 0.666667 0.333333
-vt 0.666667 0.000000
-vt 0.000000 0.333333
-vt 0.000000 0.000000
-vt 0.333333 0.000000
-vt 0.333333 1.000000
-vt 0.000000 1.000000
-vt 0.000000 0.666667
-vt 0.333333 0.333333
-vt 0.333333 0.666667
-vt 1.000000 0.000000
-vn 0.000000 -1.000000 0.000000
-vn 0.000000 1.000000 0.000000
-vn 1.000000 0.000000 0.000000
-vn -0.000000 0.000000 1.000000
-vn -1.000000 -0.000000 -0.000000
-vn 0.000000 0.000000 -1.000000
-usemtl Material
-s off
-f 2/1/1 3/2/1 4/3/1
-f 8/1/2 7/4/2 6/5/2
-f 5/6/3 6/7/3 2/8/3
-f 6/8/4 7/5/4 3/4/4
-f 3/9/5 7/10/5 8/11/5
-f 1/12/6 4/13/6 8/11/6
-f 1/4/1 2/1/1 4/3/1
-f 5/14/2 8/1/2 6/5/2
-f 1/12/3 5/6/3 2/8/3
-f 2/12/4 6/8/4 3/4/4
-f 4/13/5 3/9/5 8/11/5
-f 5/6/6 1/12/6 8/11/6

+ 0 - 974
objects/gourd.obj

@@ -1,974 +0,0 @@
-v -0.23876920554499864 1.3103797270601687 0.13001260700009193
-v -0.27582915374543276 1.2582563331865875 0.12364597630502337
-v -0.2674888336016338 1.3474373225751202 0.15912747459742976
-v -0.3128662756980407 1.222713216834852 0.14623565543301947
-v -0.3018967864385568 1.3832552573955716 0.1992584345763206
-v -0.3291084911674431 1.4015778151496097 0.23515159787549716
-v -0.3393653203892503 1.1606446817887044 0.25033862660881895
-v -0.32933702685159627 1.3872894114706185 0.30297184764306634
-v -0.34413945029647036 1.1847846590886826 0.3161902839586921
-v -0.32731404147036136 1.3472171185436952 0.33599708012099205
-v -0.31993727304296354 1.2010232341929186 0.3533614819463716
-v -0.30726711945847285 1.2956437760677335 0.3643485926629952
-v -0.2877856463729185 1.2493470906219926 0.38230872912669633
-v -0.21034318989786122 1.3531672444828033 0.1537169917653439
-v -0.21145627080982005 1.3818523867813413 0.35175494063536605
-v -0.2338628137428242 1.3442372246769223 0.37948021085512573
-v -0.25614030179208813 1.2952633550210815 0.3911502328871025
-v -0.596105380500693 -0.6768462432797441 -0.9120215121805894
-v -0.10001338605742703 -0.9910441617396678 -0.7028175040329147
-v -0.16086384627984987 -1.127277664194341 -0.7434844726798386
-v -0.008083895898474806 -1.0921252683249256 -0.5243409146431066
-v -0.07976516143635025 -1.276866970105867 -0.5252506365091272
-v -0.020060506382965703 -1.2334385749192633 -0.301325040448603
-v -0.07990779791476262 -1.3509036976740292 -0.341070036161337
-v -0.10169053410627815 -1.2068870189299477 -0.04876722079973187
-v -0.1519817903091755 -1.365510665871866 -0.15692439889429793
-v -0.2601279041091756 -1.1885795093023326 0.10988970110975217
-v -0.31729579292888604 -1.321268264156361 0.059441628673455316
-v -0.848568870055825 -0.9383248633714683 0.23982837834317694
-v -0.2841115740583825 -1.2078773490579697 -0.8036506322954367
-v -0.22231836409372388 -1.3705711792653117 -0.6258835168322516
-v -0.19808583052036852 -1.4522159317791117 -0.3886956275749503
-v -0.31271194883273773 -1.4812229673897357 -0.1662599441498861
-v -0.4468655428183257 -1.4081208865117936 0.030309816870830293
-v -0.3988207279452833 -0.9783603900495396 -0.8833077012801736
-v -0.4261847167822431 -1.2538563022802836 -0.832657802483938
-v -0.38091428944031497 -1.4323612424714172 -0.6713096485927353
-v -0.34392672880812863 -1.5296402016703727 -0.4359666117195356
-v -0.47121275738702567 -1.5427481346322585 -0.212699971365956
-v -0.5840335467653923 -1.4499471972736035 -0.01688965681846319
-v -0.5965324664537639 -1.2310376567603918 0.15439728723762638
-v -0.603970626930515 -0.9730496272867387 -0.9442929048887062
-v -0.6584407430024051 -1.2331761333320834 -0.8746205623410716
-v -0.709409821847784 -1.4659429722203778 -0.7154020228441985
-v -0.6644813362834862 -1.5771682475681057 -0.51042113309235
-v -0.7894059105187994 -1.5638233094298595 -0.3088200440614581
-v -0.8162833445262949 -1.4310813233699453 -0.05752847701987319
-v -0.8117676576018125 -1.234439602574674 0.13414076435148883
-v -0.25834762010828993 -0.6951673252373165 -0.7923673206368221
-v -0.06248973045542924 -0.7665910821077954 -0.6540399700991502
-v 0.07611239708492351 -0.9156476836861951 -0.20536770047473785
-v -0.031081271477573048 -0.8994758181564453 0.04312489218518984
-v -0.2509457867081838 -0.9602191023294494 0.1949888000417654
-v -0.5314775775236663 -0.9170871483914047 0.27604867586122167
-v -0.698201286366758 -0.8975001213210745 -0.9599982435061234
-v -0.8293665978692493 -1.11509528462743 -0.9146490325020323
-v -0.9619048200796854 -1.343162090335404 -0.7880316555337348
-v -1.0472124286277014 -1.4730438773829664 -0.5605464015223269
-v -1.060765551847539 -1.4641134058825243 -0.2855663528073091
-v -1.0004246660561544 -1.3283874042894974 -0.03361413042981279
-v -0.9104906458141931 -1.1662066485845088 0.1470252534214227
-v -0.9586855869711515 -0.6710831333901544 -0.9367557030770179
-v -1.2445793305522892 -0.817542042890274 -0.8973407152418248
-v -1.2659871743768685 -0.6801247466768301 -0.8490486738261083
-v -1.4417357951365137 -0.892844113645334 -0.7517043712681761
-v -1.476802737695221 -0.7360019859679737 -0.6685856347091148
-v -1.5639841715332439 -0.9191614582919794 -0.5287575689432107
-v -1.5681656901876435 -0.7927271011174322 -0.4991311239237613
-v -1.5326259636093063 -1.0039824068887115 -0.28969248502613
-v -1.5489494701267934 -0.8242411750516833 -0.3018251138498018
-v -1.407890071989428 -1.018040171212245 -0.06605615148067337
-v -1.4223317944946532 -0.8723090313725681 -0.05316658252587531
-v -1.1652203387672957 -0.9337169196632413 0.1334184078263284
-v -1.1255438855619244 -0.45287889159761474 -0.7915489789158711
-v -1.3279205175383988 -0.42378587112767446 -0.6057450114372587
-v -1.453237253290355 -0.5055549645946847 -0.40734951169873873
-v -1.4148957872068073 -0.5304237767693063 -0.16308494761654216
-v -1.289436358384456 -0.6584542134820716 0.049305709577394455
-v -0.8874951265560681 -0.8248028576559522 -0.9565338521560323
-v -1.1657720297488638 -0.9232322177159897 -0.9113461515493453
-v -1.3737606650637482 -1.05988953884744 -0.7658589961519274
-v -1.5010039128600727 -1.0931510893936602 -0.5582767873636508
-v -1.4601034487302784 -1.1654443984569987 -0.3270400944072667
-v -1.3300721765655639 -1.126145329626444 -0.07288783559541256
-v -1.094027683771837 -1.084366608811451 0.10682087754556222
-v -1.0875937948798378 -1.0722876078076398 -0.8950930575225976
-v -1.2487802398372811 -1.199621201720314 -0.770810356893762
-v -1.3871797127872325 -1.2453352818416719 -0.5725538075637561
-v -1.3336683013633743 -1.303381182432141 -0.33953009810380114
-v -1.2386603306792545 -1.2586899629846382 -0.12341526133552151
-v -0.847389582770811 -0.478492980249323 -0.871016832402294
-v -1.0629050406633582 -0.33601400374427853 -0.7258100434517166
-v -1.2190735055805353 -0.29624060404360103 -0.5635619964306117
-v -1.3517105212108151 -0.3476974272688013 -0.3492936473235696
-v -1.3091051787212946 -0.40781276676789235 -0.10339425594585269
-v -1.2168089660357586 -0.5274920225978963 0.06741335477163105
-v -1.0511503152740245 -0.7416804143259951 0.2049141271815988
-v -0.6820493320101108 -0.4073454070130155 -0.8362462682349809
-v -0.8480346738093036 -0.22394454471293013 -0.6859356370420204
-v -0.9382037144425833 -0.08920601913082365 -0.4560668167387506
-v -1.0896315173661946 -0.13537742027486113 -0.24763788309746104
-v -1.0177578267683933 -0.19112387317463178 7.070529650376467E-4
-v -1.0348062333853838 -0.41038161623017794 0.1399093358829532
-v -0.9396488481908281 -0.6321302849485207 0.24387425328076773
-v -0.09560436290090499 1.339214093370152 0.1477579579447047
-v -0.15273510877349308 1.2957419873888067 0.10995645328754174
-v -0.062050527956707575 1.3692309912304754 0.1955267069140381
-v -1.521773942288455E-4 1.3554620235219368 0.3227203242573578
-v -0.10349110756088271 1.3137976974225336 0.4178816230110331
-v -0.15085642703030017 1.2694959538207045 0.43225990586812474
-v -0.21433174824491863 1.2202115319934645 0.42359844208844455
-v -0.21917009134413754 1.249857125588988 0.0995416059368744
-v -0.28246419070242684 1.2050401515702542 0.11644643644430475
-v -0.3129756717999029 1.163166153030332 0.14503962345021287
-v -0.32664932338661334 1.1471685974256742 0.3296679490818033
-v -0.2751151389208091 1.178548147296377 0.38859847543695397
-v -0.07117824697642426 1.2833923335104869 0.10155506218543657
-v 0.01952628579214415 1.2268383174511577 0.08762970595474523
-v -0.0533728492267706 1.1780899339795514 0.041486476961526436
-v -0.12159853328026078 1.2160393526967515 0.06191305596390384
-v -0.03216112253813483 1.3372853305457484 0.16511543805230214
-v 0.0731556655610805 1.26540329490592 0.1618196085705
-v -0.018012120440415495 1.3646669050570877 0.22983374254345476
-v 0.10367094281488036 1.2843407275170273 0.25238198525389427
-v 0.13140177353855467 1.2478160316648583 0.32763802931035096
-v -0.056021811076326464 1.3299507664867958 0.39305267822379214
-v 0.07522175402077194 1.2507143399891454 0.3956619662984644
-v -0.08281234911568472 1.2703421796138938 0.4402240123229857
-v 0.01795293748424096 1.1977292385399962 0.4495759996401428
-v -0.140084567072329 1.1981313068931814 0.4549247925876616
-v -0.055730483438343095 1.134204503245634 0.4743453892047482
-v -0.195843423418774 1.1250804448063756 0.4395501060994016
-v -0.13648241697035543 1.0762988502857962 0.4642071929538253
-v -0.1320833582585817 1.118879626710536 0.03027101424435127
-v -0.17789451123739403 1.1419876741742214 0.052250123394135074
-v -0.20244412759751665 1.062628011979282 0.0508408807532532
-v -0.23210941728461448 1.0796495973528117 0.07190570714367979
-v -0.26030340316362355 1.0179148935053772 0.10527188614157675
-v -0.29525684897940946 0.9675080117623716 0.1792173306975986
-v -0.28826541284389207 0.9677050604055095 0.2798794723956473
-v -0.2632513574265279 0.9931303693008816 0.3514136070432927
-v -0.28646037093541493 1.0185581755171358 0.3282172719023405
-v -0.2086964110925687 1.0259454248881235 0.4189416705014296
-v -0.2467883757867712 1.0595447508107605 0.3933816015630798
-v 0.17872313693801953 1.025246834722123 0.04349401870518004
-v 0.06748632295477272 1.0328368970330073 -0.0012005056093327012
-v 0.2561423061057405 1.0136281055295011 0.10835507124081907
-v 0.300950261734067 0.9431608110206416 0.28643187767591677
-v 0.18936841832020435 0.9319869673270735 0.44817741477373196
-v 0.09325438236168647 0.9204810011470623 0.4786885904815903
-v -0.026875929876898914 0.9171992918687374 0.4788032161574475
-v -0.050991484084989845 1.030898509265369 -0.008079474184983611
-v -0.16209114356370188 1.0159498925407309 0.024676756222088137
-v -0.229159459612385 0.9354422138631637 0.36859933084343927
-v -0.1391731970008425 0.9234519262530181 0.44119603386135564
-v 0.17861510065239114 0.9029942588889944 -0.005193118717157615
-v 0.20885071989207965 0.5755957905566027 -0.07667087792795438
-v 0.07966628487324764 0.8444141445957631 -0.05571698567292751
-v 0.10836530729913466 0.5997704001367645 -0.10999773301638337
-v 0.267798986856911 0.9395661466021183 0.07867890346497927
-v 0.2937291293341934 0.962459454773473 0.17552656684668122
-v 0.3397881281649465 0.4568368997780585 0.1767550046536417
-v 0.25272039926472245 0.9123418286838364 0.3839045766826548
-v 0.1960131812497361 0.8515960540706153 0.4438518114132365
-v 0.08617665401052353 0.7897714182096348 0.4648540365288201
-v 0.11695626676834338 0.46301165363215435 0.39082411170929
-v -0.018812474436488397 0.7237549378258146 0.44527487016595946
-v 0.009515024453930019 0.47867577559453145 0.3928715296525722
-v -0.012905137512460198 0.6217365064396034 -0.10774026933953917
-v -0.020542415672755155 0.7766143499424125 -0.07025333721081264
-v -0.11420333688264363 0.6301372081172665 -0.072320114787061
-v -0.12027343756275882 0.7162053532704167 -0.04479408000218762
-v -0.19469603733957327 0.6638012353563264 0.0019509816624666348
-v -0.24865269735816442 0.5979937949414752 0.09451062907589113
-v -0.23773508294912143 0.6112776440191625 0.21892825264540403
-v -0.18634370550533172 0.5413926271476547 0.2949493622643064
-v -0.1895051304036615 0.6312093666452024 0.3081881168248471
-v -0.10427297470446559 0.5097569398714669 0.35705778790619097
-v -0.11098916529176285 0.6655311694160618 0.39159830628358067
-v 0.1876342069811111 0.5033061437989215 -0.10483268880194742
-v 0.09809358624263935 0.17576055344835947 -0.22660111284413842
-v 9.980600042878598E-4 0.2776940657404102 -0.23833721224985494
-v 0.06202604473373216 0.5143367290533036 -0.14430238389579206
-v 0.2601771625596767 0.5132495618693441 -0.0419826119632792
-v 0.2267034323045877 -0.07934967297543495 0.02556359016082569
-v 0.18248639872254088 0.4180673661872462 0.35325990274594876
-v 0.09338059505857496 0.38783248945634874 0.3746744992397327
-v -0.005211606777756715 0.04917999260227923 0.2990491470058861
-v -0.03849106672839849 0.39120902770935095 0.367016939925659
-v -0.10848056289935136 0.1435512953626317 0.31865722665290575
-v -0.0932417226328324 0.3598705333665368 -0.2074025730478351
-v -0.06719701000163651 0.5066450508624447 -0.1397429150410627
-v -0.1804473794799147 0.41746664230742225 -0.1415871127280521
-v -0.16404691441086264 0.5008696549815044 -0.09943713866384862
-v -0.24991610243976733 0.46142536820852903 -0.04084433768174924
-v -0.28761411639861034 0.44737779602280475 0.051054453447751835
-v -0.28675863948263974 0.416295470137208 0.14635962931629456
-v -0.254500590852495 0.32669003381612766 0.23531552878884276
-v -0.231372001824006 0.41834268077179726 0.24280756749780402
-v -0.19207899925896893 0.23874733244600602 0.29550374929060313
-v -0.15628752178315608 0.3974920744082751 0.31353339526127444
-v -0.018720751877417497 0.062427271517513046 -0.3423575873860938
-v -0.05158961781091372 -0.2563933968214236 -0.49800580550559054
-v -0.20088495830404476 -0.13126411196599852 -0.5453441726394352
-v -0.18340769457458989 0.09825169285259472 -0.3943097123183823
-v 0.12115365957039037 0.014420223788874923 -0.24037782041932212
-v 0.056559451013174264 -0.36062459822625886 -0.40692266576968744
-v 0.12212578753997294 -0.6050598321387264 -0.12437295900412774
-v 0.025258295975196174 -0.10322945063945176 0.24768994532951785
-v -0.06640266552744624 -0.5010310085837314 0.19723160290838115
-v -0.145384934862913 -0.09303562620026448 0.3026990669448157
-v -0.2080530513736607 -0.4402766255051616 0.27854398626511434
-v -0.3201688747286834 -0.069472750700044 0.3021999728028007
-v -0.3764229875624985 -0.3372841738879878 0.3196175137825808
-v -0.37103840912195013 -0.018343714126245417 -0.5181695682676257
-v -0.3624876398424141 0.11792333476126983 -0.3885156944272048
-v -0.5369907859125455 0.05987335312325521 -0.420070558870981
-v -0.49722492713673616 0.13410703737954682 -0.3286188877172944
-v -0.6294317441594179 0.11556113739693963 -0.26391312063853545
-v -0.74173498336992 0.08053780182128528 -0.12522747001774567
-v -0.6901485280221654 0.042138462724677694 0.04298647182897286
-v -0.6583061345706847 -0.08271666421665431 0.17909368084528765
-v -0.5930778951386746 0.01940614282887867 0.15083850228675535
-v -0.5336280893809849 -0.20845754472929892 0.2850729045500069
-v -0.4863419744110133 -0.033084460741767234 0.24177778209818324
-v -0.16421418750489497 -0.3009066302678531 -0.613469962903272
-v -0.19121648139938338 -0.49736348828867183 -0.7024015487555098
-v -0.3804429066794447 -0.3517580490090136 -0.7461890303461363
-v -0.36911610223035285 -0.19924428750907905 -0.6606716953472738
-v 0.00764144937164241 -0.41591976904898176 -0.48949143091766145
-v -0.00703132676232705 -0.639152352439578 -0.5705632382430396
-v 0.11082364953963271 -0.46984782407830805 -0.3169906454178008
-v 0.07681783005303255 -0.7589168860036708 -0.4146953894835867
-v 0.023932473668473467 -0.5670301759646578 0.09632170271937375
-v -0.139698107729481 -0.5845442431079642 0.224328828951515
-v -0.12909344686888494 -0.82452130403786 0.17197986976368612
-v -0.35629678802794823 -0.5164555824199508 0.3146739763415395
-v -0.3207143923909673 -0.7555247084101276 0.27546974969494803
-v -0.5751666842740498 -0.42980212239695187 0.3247894461401142
-v -0.5608819388605969 -0.6300128226097699 0.3256888806317336
-v -0.6119993988065029 -0.2039436789589 -0.7058985888062624
-v -0.5690995198999165 -0.12062867425850417 -0.6367858256444157
-v -0.7745480379862542 -0.08299685419757988 -0.5533065828441973
-v -0.9059965161698623 -0.27579432003345206 0.1565710587409764
-v -0.7733491979650087 -0.48524750438686576 0.2900036375382926
-v -0.7448096323038795 -0.3254807309936029 0.26563969024312495
-v -0.1292811121767781 0.24541226127424362 -0.27813642684707096
-v -0.012722182411993922 0.17872354694047157 -0.2856442543998048
-v -0.2428141364892664 0.29395739556129535 -0.22349063319337525
-v -0.3411247577494312 0.31901208295467953 -0.12724776419557868
-v -0.3992091957752286 0.31073037338569687 -0.0036776738917693227
-v -0.39029961638808786 0.25895363915674446 0.12264318016053902
-v -0.3311242920511251 0.18560722865550605 0.22621753264795585
-v -0.24091339429176825 0.1083564943253534 0.2905482642422535
-v -0.12951005521262673 0.03536832888417705 0.30925230551932015
-v 0.09116388438362256 0.10905454185092361 -0.24903014897171805
-v 0.16893286792711723 0.09534659783694158 -0.17487528542655814
-v 0.08621995597156243 -0.006153152546389401 0.24651124997927
-v -0.013839682800429801 -0.01976756022956282 0.2857709647911246
-v -0.14224466965791016 1.3831523327333446 0.30144101500423315
-v -0.13605604833821014 1.393857595270661 0.2766140427570333
-v -0.13002715466520928 1.3934280277792825 0.2520685743777088
-v -0.12423922657418207 1.388769918728889 0.23066988277566788
-v -0.19518443866089988 1.3928509577654855 0.20378772481501994
-v -0.24148774025737788 1.3945399882729024 0.23016096348757714
-v -0.25791021093344335 1.4037411161856639 0.24787129664381718
-v -0.2620654518979459 1.3957442061286076 0.284527879789462
-v -0.20139872286954744 1.389485467634939 0.32349211851139514
-v -0.1488091510125688 1.3781207203872883 0.3200274224926117
-v -0.13158193764344558 1.4250679750579258 0.2807314628260412
-v -0.11595643515633988 1.4245682404098425 0.22163997660384924
-v -0.20627424326148192 1.4124911965266467 0.18741680061016427
-v -0.26445442393150115 1.400769211913228 0.22122294388061534
-v -0.2872685557740087 1.406883382542881 0.2444293361608223
-v -0.2899360821624794 1.3935839799698049 0.29084828102857163
-v -0.21178559249014803 1.3994915112001476 0.34039022323541024
-v -0.1429001429580068 1.3993976870289333 0.3353182110462305
-v -0.2857648326576529 1.5187468359348737 0.3082338172397895
-v -0.27727616014547757 1.530338168645061 0.2625549569640586
-v -0.3334604957630521 1.4880341091190048 0.23308840213734724
-v -0.36604087340725666 1.453055527215242 0.25713264595649266
-v -0.3828999421792846 1.4454714177478138 0.2753297576919234
-v -0.37751818239371726 1.4313472154601539 0.31006947817311087
-v -0.32631523474701046 1.4631317857783432 0.35061576401157374
-v -0.2807143588260308 1.4921408310497963 0.34796225284311
-v -0.359718447897886 1.5667423492396997 0.3249332982344497
-v -0.35604269069748223 1.5843518466712045 0.27844553809784006
-v -0.3980451782163092 1.5262919573931168 0.24430381106553892
-v -0.4181656377402749 1.4792909565111614 0.2664080870596363
-v -0.43194785784379036 1.4648905070555227 0.2846242013341748
-v -0.42130540631457 1.4501970581589543 0.31964088446057193
-v -0.3805277869148768 1.4954324349453687 0.3644531272029499
-v -0.34517821394105 1.5392865146237846 0.36417365388479916
-v -0.525253166509216 1.5797756350730938 0.3618339573500447
-v -0.5427781715907363 1.600035553232815 0.32113583567835097
-v -0.5227646170883478 1.5418236240694803 0.27390553690397157
-v -0.4933105257778895 1.4972331194307962 0.2843137977922944
-v -0.48710328833367594 1.4754098821989285 0.2977991260001166
-v -0.46547571828721857 1.4702527709605107 0.3292892793473014
-v -0.474604834039762 1.518936744884534 0.3841417968234773
-v -0.4907531253963674 1.570392934863122 0.3952265040148293
-v -0.6190130970388793 1.5696558595459142 0.38003232814495125
-v -0.6355019539055907 1.585899126949611 0.3462181836390502
-v -0.6139504237029327 1.5398059391590697 0.3053658122107581
-v -0.5784210799208646 1.4868135510777596 0.32414429004118506
-v -0.5598034658588011 1.483728452273698 0.350505735413888
-v -0.5714200313571158 1.5226275895992984 0.3975745784787094
-v -0.5892615137516267 1.5640904735931778 0.40790221218885614
-v -0.7207897200255293 1.5567789987446936 0.40116346301661054
-v -0.7290467383099924 1.5726640148199242 0.3702920060376821
-v -0.7270750137803762 1.525483825821082 0.33867446181335653
-v -0.71560668386606 1.4727027815509461 0.3595899705139178
-v -0.7013827394050692 1.4661328607881354 0.38307846161479897
-v -0.6976434083183529 1.504754391368148 0.4208247199303316
-v -0.6983812574358621 1.5446905536547915 0.42637673695906997
-v -0.9070526524958897 1.4960808856355494 0.4172580276830761
-v -0.8863039803791803 1.474513559264521 0.3901551190206042
-v -0.8554404727488869 1.4489886081267185 0.39960983011290785
-v -0.8436098200111913 1.4494922096871927 0.415802278250204
-v -0.875124048994981 1.4891447909953186 0.4545401079578815
-v -0.9884730850864034 1.4369108601544263 0.4354713488045925
-v -1.0097509656761623 1.402303016901423 0.41539549299271056
-v -1.0261663143967716 1.3653907886614334 0.43778258638601936
-v -1.0193881127383304 1.3571557442500386 0.4576102108491951
-v -0.9801045292318034 1.4108781558731749 0.4839256718868889
-v -1.0646015617123321 1.3754696203441494 0.4676547749135673
-f 1 2 3
-f 4 5 3
-f 4 3 2
-f 9 10 7
-f 10 8 7
-f 11 12 9
-f 12 10 9
-f 12 11 13
-f 1 3 14
-f 10 16 15
-f 10 15 8
-f 12 17 16
-f 12 16 10
-f 17 12 13
-f 21 22 20
-f 21 20 19
-f 23 24 22
-f 23 22 21
-f 25 26 23
-f 26 24 23
-f 27 28 25
-f 28 26 25
-f 22 31 20
-f 31 30 20
-f 24 32 22
-f 32 31 22
-f 26 33 32
-f 26 32 24
-f 28 34 33
-f 28 33 26
-f 31 37 30
-f 37 36 30
-f 32 38 31
-f 38 37 31
-f 33 39 38
-f 33 38 32
-f 34 40 39
-f 34 39 33
-f 18 35 42
-f 36 43 35
-f 43 42 35
-f 37 44 36
-f 44 43 36
-f 38 45 37
-f 45 44 37
-f 39 46 45
-f 39 45 38
-f 40 47 46
-f 40 46 39
-f 41 48 47
-f 41 47 40
-f 48 41 29
-f 51 23 21
-f 52 25 51
-f 25 23 51
-f 53 27 52
-f 27 25 52
-f 18 42 55
-f 43 56 42
-f 56 55 42
-f 44 57 43
-f 57 56 43
-f 45 58 44
-f 58 57 44
-f 46 59 58
-f 46 58 45
-f 47 60 59
-f 47 59 46
-f 48 61 60
-f 48 60 47
-f 61 48 29
-f 63 64 62
-f 65 66 64
-f 65 64 63
-f 67 68 66
-f 67 66 65
-f 69 70 67
-f 70 68 67
-f 71 72 69
-f 72 70 69
-f 73 72 71
-f 64 74 62
-f 66 75 64
-f 75 74 64
-f 68 76 66
-f 76 75 66
-f 70 77 76
-f 70 76 68
-f 72 78 77
-f 72 77 70
-f 73 78 72
-f 81 65 63
-f 81 63 80
-f 82 67 65
-f 82 65 81
-f 83 69 82
-f 69 67 82
-f 84 71 83
-f 71 69 83
-f 86 80 79
-f 87 81 80
-f 87 80 86
-f 88 82 81
-f 88 81 87
-f 89 83 88
-f 83 82 88
-f 90 84 89
-f 84 83 89
-f 85 84 90
-f 57 87 86
-f 57 86 56
-f 58 88 87
-f 58 87 57
-f 59 89 58
-f 89 88 58
-f 60 90 59
-f 90 89 59
-f 75 93 74
-f 93 92 74
-f 76 94 75
-f 94 93 75
-f 77 95 94
-f 77 94 76
-f 78 96 95
-f 78 95 77
-f 18 91 98
-f 92 99 91
-f 99 98 91
-f 93 100 92
-f 100 99 92
-f 94 101 93
-f 101 100 93
-f 95 102 101
-f 95 101 94
-f 96 103 102
-f 96 102 95
-f 97 104 103
-f 97 103 96
-f 104 97 29
-f 14 105 106
-f 14 106 1
-f 16 109 15
-f 17 110 16
-f 110 109 16
-f 13 111 17
-f 111 110 17
-f 112 2 1
-f 112 1 106
-f 113 4 2
-f 113 2 112
-f 114 4 113
-f 116 11 115
-f 11 9 115
-f 111 13 116
-f 13 11 116
-f 117 118 119
-f 117 119 120
-f 121 122 118
-f 121 118 117
-f 123 124 122
-f 123 122 121
-f 108 125 124
-f 108 124 123
-f 126 127 108
-f 127 125 108
-f 128 129 126
-f 129 127 126
-f 130 131 128
-f 131 129 128
-f 132 133 130
-f 133 131 130
-f 134 135 120
-f 134 120 119
-f 136 137 135
-f 136 135 134
-f 143 144 141
-f 144 142 141
-f 133 132 143
-f 132 144 143
-f 118 145 146
-f 118 146 119
-f 122 147 145
-f 122 145 118
-f 124 147 122
-f 129 149 127
-f 131 150 129
-f 150 149 129
-f 133 151 131
-f 151 150 131
-f 152 134 119
-f 152 119 146
-f 153 136 134
-f 153 134 152
-f 155 143 154
-f 143 141 154
-f 151 133 155
-f 133 143 155
-f 156 157 158
-f 157 159 158
-f 148 162 161
-f 163 162 148
-f 167 168 166
-f 167 166 165
-f 169 170 159
-f 170 158 159
-f 171 172 169
-f 172 170 169
-f 173 172 171
-f 176 177 175
-f 178 179 177
-f 178 177 176
-f 168 167 179
-f 168 179 178
-f 180 181 182
-f 180 182 183
-f 184 181 180
-f 187 188 186
-f 189 190 187
-f 190 188 187
-f 191 192 183
-f 191 183 182
-f 193 194 192
-f 193 192 191
-f 200 201 198
-f 201 199 198
-f 190 189 200
-f 189 201 200
-f 202 203 204
-f 202 204 205
-f 206 207 203
-f 206 203 202
-f 211 212 209
-f 212 210 209
-f 213 214 211
-f 214 212 211
-f 215 216 205
-f 215 205 204
-f 217 218 216
-f 217 216 215
-f 224 225 222
-f 225 223 222
-f 214 213 224
-f 213 225 224
-f 226 227 228
-f 226 228 229
-f 230 231 227
-f 230 227 226
-f 232 233 231
-f 232 231 230
-f 208 51 233
-f 208 233 232
-f 235 236 234
-f 237 238 235
-f 238 236 235
-f 239 240 237
-f 240 238 237
-f 241 242 229
-f 241 229 228
-f 240 239 245
-f 239 246 245
-f 242 215 229
-f 215 204 229
-f 243 217 242
-f 217 215 242
-f 246 224 222
-f 246 222 244
-f 239 214 224
-f 239 224 246
-f 203 226 204
-f 226 229 204
-f 207 230 203
-f 230 226 203
-f 232 230 207
-f 210 235 234
-f 212 237 235
-f 212 235 210
-f 214 239 237
-f 214 237 212
-f 216 247 205
-f 247 248 205
-f 218 249 216
-f 249 247 216
-f 219 250 218
-f 250 249 218
-f 220 251 219
-f 251 250 219
-f 221 252 251
-f 221 251 220
-f 223 253 252
-f 223 252 221
-f 225 254 253
-f 225 253 223
-f 213 255 254
-f 213 254 225
-f 256 202 248
-f 202 205 248
-f 257 206 256
-f 206 202 256
-f 259 211 209
-f 259 209 258
-f 255 213 211
-f 255 211 259
-f 247 191 182
-f 247 182 248
-f 249 193 191
-f 249 191 247
-f 250 193 249
-f 253 198 252
-f 254 200 253
-f 200 198 253
-f 255 190 254
-f 190 200 254
-f 181 256 248
-f 181 248 182
-f 190 255 188
-f 255 259 188
-f 192 169 183
-f 169 159 183
-f 194 171 192
-f 171 169 192
-f 196 174 195
-f 197 174 196
-f 201 178 176
-f 201 176 199
-f 189 168 178
-f 189 178 201
-f 157 180 159
-f 180 183 159
-f 184 180 157
-f 166 187 186
-f 168 189 187
-f 168 187 166
-f 170 152 158
-f 152 146 158
-f 172 153 170
-f 153 152 170
-f 174 139 173
-f 175 139 174
-f 179 155 154
-f 179 154 177
-f 167 151 155
-f 167 155 179
-f 145 156 146
-f 156 158 146
-f 147 160 145
-f 160 156 145
-f 161 160 147
-f 149 164 163
-f 150 165 164
-f 150 164 149
-f 151 167 165
-f 151 165 150
-f 135 112 120
-f 112 106 120
-f 137 113 135
-f 113 112 135
-f 138 114 137
-f 114 113 137
-f 144 116 115
-f 144 115 142
-f 132 111 116
-f 132 116 144
-f 105 117 106
-f 117 120 106
-f 107 121 105
-f 121 117 105
-f 123 121 107
-f 109 128 126
-f 110 130 128
-f 110 128 109
-f 111 132 130
-f 111 130 110
-f 29 240 245
-f 29 245 104
-f 241 98 99
-f 228 18 98
-f 228 98 241
-f 236 53 52
-f 238 54 53
-f 238 53 236
-f 240 29 54
-f 240 54 238
-f 50 231 233
-f 49 227 231
-f 49 231 50
-f 18 228 227
-f 18 227 49
-f 8 6 7
-f 7 6 5
-f 114 7 4
-f 7 114 138
-f 139 7 138
-f 140 7 139
-f 7 5 4
-f 18 49 35
-f 20 30 35
-f 30 36 35
-f 19 20 35
-f 50 19 35
-f 50 35 49
-f 41 34 28
-f 41 40 34
-f 41 54 29
-f 41 27 53
-f 41 28 27
-f 54 41 53
-f 18 79 62
-f 80 63 62
-f 80 62 79
-f 73 71 84
-f 73 85 29
-f 85 73 84
-f 18 55 79
-f 56 86 79
-f 56 79 55
-f 85 90 60
-f 85 61 29
-f 61 85 60
-f 18 62 91
-f 74 91 62
-f 74 92 91
-f 73 97 78
-f 97 73 29
-f 97 96 78
-f 115 9 7
-f 142 115 7
-f 142 7 140
-f 138 137 136
-f 141 142 140
-f 173 171 194
-f 174 173 195
-f 195 173 194
-f 197 175 174
-f 199 176 175
-f 199 175 197
-f 195 194 193
-f 250 195 193
-f 251 196 195
-f 251 195 250
-f 197 196 251
-f 198 199 197
-f 198 197 252
-f 252 197 251
-f 219 218 217
-f 219 217 243
-f 222 223 221
-f 244 222 221
-f 243 242 241
-f 241 99 243
-f 243 99 100
-f 245 246 244
-f 104 245 244
-f 104 244 103
-f 185 208 232
-f 234 208 185
-f 184 257 181
-f 257 256 181
-f 188 258 186
-f 188 259 258
-f 160 184 156
-f 184 157 156
-f 165 186 164
-f 165 166 186
-f 124 161 147
-f 125 161 124
-f 125 148 161
-f 127 163 125
-f 149 163 127
-f 163 148 125
-f 109 126 15
-f 234 52 208
-f 236 52 234
-f 52 51 208
-f 233 21 19
-f 51 21 233
-f 233 19 50
-f 138 136 153
-f 138 153 172
-f 139 138 173
-f 173 138 172
-f 175 140 139
-f 154 141 140
-f 177 154 140
-f 177 140 175
-f 100 219 243
-f 101 220 100
-f 220 219 100
-f 102 220 101
-f 103 244 102
-f 244 221 102
-f 102 221 220
-f 269 260 277
-f 270 277 260
-f 260 261 270
-f 261 262 270
-f 271 270 262
-f 262 263 271
-f 263 264 271
-f 272 271 264
-f 264 265 272
-f 273 272 265
-f 265 266 273
-f 274 273 266
-f 266 267 274
-f 275 274 267
-f 276 275 267
-f 267 268 276
-f 268 269 276
-f 277 276 269
-f 277 270 285
-f 278 285 270
-f 270 271 279
-f 279 278 270
-f 271 272 279
-f 280 279 272
-f 272 273 280
-f 281 280 273
-f 273 274 281
-f 282 281 274
-f 274 275 282
-f 283 282 275
-f 275 276 284
-f 284 283 275
-f 276 277 285
-f 285 284 276
-f 285 278 293
-f 286 293 278
-f 278 279 287
-f 287 286 278
-f 279 280 287
-f 288 287 280
-f 280 281 288
-f 289 288 281
-f 281 282 289
-f 290 289 282
-f 282 283 291
-f 291 290 282
-f 283 284 292
-f 292 291 283
-f 284 285 293
-f 293 292 284
-f 293 286 301
-f 294 301 286
-f 286 287 295
-f 295 294 286
-f 287 288 296
-f 296 295 287
-f 288 289 297
-f 297 296 288
-f 289 290 297
-f 298 297 290
-f 290 291 299
-f 299 298 290
-f 291 292 299
-f 300 299 292
-f 292 293 300
-f 301 300 293
-f 301 294 308
-f 302 308 294
-f 294 295 302
-f 303 302 295
-f 295 296 304
-f 304 303 295
-f 297 298 305
-f 298 299 306
-f 306 305 298
-f 299 300 306
-f 307 306 300
-f 300 301 307
-f 308 307 301
-f 308 302 315
-f 309 315 302
-f 302 303 309
-f 310 309 303
-f 303 304 311
-f 311 310 303
-f 305 306 313
-f 313 312 305
-f 306 307 313
-f 314 313 307
-f 307 308 314
-f 315 314 308
-f 315 309 320
-f 309 310 316
-f 310 311 317
-f 317 316 310
-f 312 313 319
-f 319 318 312
-f 313 314 319
-f 316 317 321
-f 322 321 317
-f 318 319 324
-f 324 323 318
-f 321 322 326
-f 323 324 326
-f 108 261 260
-f 260 126 108
-f 123 262 261
-f 261 108 123
-f 123 107 263
-f 262 123 263
-f 5 6 266
-f 265 5 266
-f 6 8 267
-f 266 6 267
-f 15 268 267
-f 267 8 15
-f 268 15 269
-f 126 260 269
-f 15 126 269
-f 185 206 257
-f 185 207 206
-f 185 232 207
-f 162 257 184
-f 162 184 160
-f 162 185 257
-f 161 162 160
-f 186 258 162
-f 164 186 162
-f 164 162 163
-f 258 185 162
-f 258 209 185
-f 210 234 185
-f 209 210 185
-f 5 264 3
-f 264 5 265
-f 264 14 3
-f 264 105 14
-f 264 107 105
-f 263 107 264
-f 296 297 305
-f 305 304 296
-f 304 305 312
-f 312 311 304
-f 316 320 309
-f 320 316 321
-f 311 312 317
-f 318 317 312
-f 320 319 314
-f 314 315 320
-f 321 325 320
-f 325 321 326
-f 323 322 317
-f 322 323 326
-f 317 318 323
-f 319 320 325
-f 325 324 319
-f 324 325 326

+ 0 - 46
objects/obj_file.obj

@@ -1,46 +0,0 @@
-# Blender v2.76 (sub 0) OBJ File: ''
-# www.blender.org
-mtllib cube.mtl
-o Cube
-v 1.000000 -1.000000 -1.000000
-v 1.000000 -1.000000 1.000000
-v -1.000000 -1.000000 1.000000
-v -1.000000 -1.000000 -1.000000
-v 1.000000 1.000000 -0.999999
-v 0.999999 1.000000 1.000001
-v -1.000000 1.000000 1.000000
-v -1.000000 1.000000 -1.000000
-vt 1.000000 0.333333
-vt 1.000000 0.666667
-vt 0.666667 0.666667
-vt 0.666667 0.333333
-vt 0.666667 0.000000
-vt 0.000000 0.333333
-vt 0.000000 0.000000
-vt 0.333333 0.000000
-vt 0.333333 1.000000
-vt 0.000000 1.000000
-vt 0.000000 0.666667
-vt 0.333333 0.333333
-vt 0.333333 0.666667
-vt 1.000000 0.000000
-vn 0.000000 -1.000000 0.000000
-vn 0.000000 1.000000 0.000000
-vn 1.000000 0.000000 0.000000
-vn -0.000000 0.000000 1.000000
-vn -1.000000 -0.000000 -0.000000
-vn 0.000000 0.000000 -1.000000
-usemtl Material
-s off
-f 2/1/1 3/2/1 4/3/1
-f 8/1/2 7/4/2 6/5/2
-f 5/6/3 6/7/3 2/8/3
-f 6/8/4 7/5/4 3/4/4
-f 3/9/5 7/10/5 8/11/5
-f 1/12/6 4/13/6 8/11/6
-f 1/4/1 2/1/1 4/3/1
-f 5/14/2 8/1/2 6/5/2
-f 1/12/3 5/6/3 2/8/3
-f 2/12/4 6/8/4 3/4/4
-f 4/13/5 3/9/5 8/11/5
-f 5/6/6 1/12/6 8/11/6

+ 0 - 46
objects/rotated_cube.obj

@@ -1,46 +0,0 @@
-# Blender 4.4.3
-# www.blender.org
-mtllib rotated_cube.mtl
-o Cube
-v 1.636202 0.478275 -0.306753
-v 0.377775 -0.271598 -1.668389
-v 1.069844 -0.932032 0.993353
-v -0.188583 -1.681905 -0.368283
-v 0.188583 1.681905 0.368283
-v -1.069844 0.932032 -0.993353
-v -0.377775 0.271598 1.668389
-v -1.636202 -0.478275 0.306753
-vn 0.6292 0.3749 0.6808
-vn -0.2832 -0.7052 0.6501
-vn -0.7238 0.6018 0.3375
-vn -0.6292 -0.3749 -0.6808
-vn 0.7238 -0.6018 -0.3375
-vn 0.2832 0.7052 -0.6501
-vt 0.875000 0.500000
-vt 0.625000 0.750000
-vt 0.625000 0.500000
-vt 0.375000 1.000000
-vt 0.375000 0.750000
-vt 0.625000 0.000000
-vt 0.375000 0.250000
-vt 0.375000 0.000000
-vt 0.375000 0.500000
-vt 0.125000 0.750000
-vt 0.125000 0.500000
-vt 0.625000 0.250000
-vt 0.875000 0.750000
-vt 0.625000 1.000000
-s 0
-usemtl Material
-f 5/1/1 3/2/1 1/3/1
-f 3/2/2 8/4/2 4/5/2
-f 7/6/3 6/7/3 8/8/3
-f 2/9/4 8/10/4 6/11/4
-f 1/3/5 4/5/5 2/9/5
-f 5/12/6 2/9/6 6/7/6
-f 5/1/1 7/13/1 3/2/1
-f 3/2/2 7/14/2 8/4/2
-f 7/6/3 5/12/3 6/7/3
-f 2/9/4 4/5/4 8/10/4
-f 1/3/5 3/2/5 4/5/5
-f 5/12/6 1/3/6 2/9/6

+ 0 - 9965
objects/teapot.obj

@@ -1,9965 +0,0 @@
-v -3.000000 1.800000 0.000000
-v -2.991600 1.800000 -0.081000
-v -2.991600 1.800000 0.081000
-v -2.989450 1.666162 0.000000
-v -2.985000 1.921950 0.000000
-v -2.985000 1.921950 0.000000
-v -2.981175 1.667844 -0.081000
-v -2.981175 1.667844 0.081000
-v -2.976687 1.920243 -0.081000
-v -2.976687 1.920243 0.081000
-v -2.968800 1.800000 -0.144000
-v -2.968800 1.800000 0.144000
-v -2.958713 1.672406 -0.144000
-v -2.958713 1.672406 0.144000
-v -2.957600 1.534800 0.000000
-v -2.957600 1.534800 0.000000
-v -2.954122 1.915609 -0.144000
-v -2.954122 1.915609 0.144000
-v -2.949693 1.537790 -0.081000
-v -2.949693 1.537790 0.081000
-v -2.940000 2.019600 0.000000
-v -2.935200 1.800000 -0.189000
-v -2.935200 1.800000 0.189000
-v -2.931958 2.016526 0.081000
-v -2.931958 2.016526 -0.081000
-v -2.928230 1.545907 -0.144000
-v -2.928230 1.545907 0.144000
-v -2.925611 1.679131 -0.189000
-v -2.925611 1.679131 0.189000
-v -2.920870 1.908779 -0.189000
-v -2.920870 1.908779 0.189000
-v -2.910131 2.008181 -0.144000
-v -2.910131 2.008181 0.144000
-v -2.904150 1.406137 0.000000
-v -2.904150 1.406137 0.000000
-v -2.896846 1.410135 0.081000
-v -2.896846 1.410135 -0.081000
-v -2.896602 1.557869 -0.189000
-v -2.896602 1.557869 0.189000
-v -2.894400 1.800000 -0.216000
-v -2.894400 1.800000 0.216000
-v -2.885416 1.687296 -0.216000
-v -2.885416 1.687296 0.216000
-v -2.880491 1.900487 -0.216000
-v -2.880491 1.900487 0.216000
-v -2.877965 1.995883 -0.189000
-v -2.877965 1.995883 0.189000
-v -2.877022 1.420985 -0.144000
-v -2.877022 1.420985 0.144000
-v -2.865000 2.095650 0.000000
-v -2.858195 1.572394 0.216000
-v -2.858195 1.572394 -0.216000
-v -2.857432 2.091511 -0.081000
-v -2.857432 2.091511 0.081000
-v -2.850000 1.800000 -0.225000
-v -2.850000 1.800000 0.225000
-v -2.847806 1.436974 0.189000
-v -2.847806 1.436974 -0.189000
-v -2.841675 1.696181 0.225000
-v -2.841675 1.696181 -0.225000
-v -2.838906 1.980950 -0.216000
-v -2.838906 1.980950 0.216000
-v -2.836889 2.080276 -0.144000
-v -2.836889 2.080276 0.144000
-v -2.836550 1.891463 -0.225000
-v -2.836550 1.891463 0.225000
-v -2.828800 1.280400 0.000000
-v -2.822326 1.285171 -0.081000
-v -2.822326 1.285171 0.081000
-v -2.816400 1.588200 -0.225000
-v -2.816400 1.588200 0.225000
-v -2.812331 1.456390 0.216000
-v -2.812331 1.456390 -0.216000
-v -2.806615 2.063720 -0.189000
-v -2.806615 2.063720 0.189000
-v -2.805600 1.800000 -0.216000
-v -2.805600 1.800000 0.216000
-v -2.804755 1.298122 -0.144000
-v -2.804755 1.298122 0.144000
-v -2.797934 1.705067 -0.216000
-v -2.797934 1.705067 0.216000
-v -2.796400 1.964700 0.225000
-v -2.796400 1.964700 -0.225000
-v -2.792609 1.882438 -0.216000
-v -2.792609 1.882438 0.216000
-v -2.778861 1.317206 -0.189000
-v -2.778861 1.317206 0.189000
-v -2.774605 1.604006 0.216000
-v -2.774605 1.604006 -0.216000
-v -2.773725 1.477519 0.225000
-v -2.773725 1.477519 -0.225000
-v -2.769854 2.043616 -0.216000
-v -2.769854 2.043616 0.216000
-v -2.764800 1.800000 -0.189000
-v -2.764800 1.800000 0.189000
-v -2.760000 2.152800 0.000000
-v -2.760000 2.152800 0.000000
-v -2.757739 1.713232 -0.189000
-v -2.757739 1.713232 0.189000
-v -2.753894 1.948450 -0.216000
-v -2.753894 1.948450 0.216000
-v -2.753123 2.147861 -0.081000
-v -2.753123 2.147861 0.081000
-v -2.752230 1.874146 -0.189000
-v -2.752230 1.874146 0.189000
-v -2.747418 1.340381 -0.216000
-v -2.747418 1.340381 0.216000
-v -2.736198 1.618531 -0.189000
-v -2.736198 1.618531 0.189000
-v -2.735119 1.498648 0.216000
-v -2.735119 1.498648 -0.216000
-v -2.734458 2.134454 -0.144000
-v -2.734458 2.134454 0.144000
-v -2.731250 1.157813 0.000000
-v -2.731250 1.157813 0.000000
-v -2.731200 1.800000 -0.144000
-v -2.731200 1.800000 0.144000
-v -2.729850 2.021737 -0.225000
-v -2.729850 2.021737 0.225000
-v -2.725825 1.163194 0.081000
-v -2.725825 1.163194 -0.081000
-v -2.724637 1.719956 -0.144000
-v -2.724637 1.719956 0.144000
-v -2.718978 1.867316 -0.144000
-v -2.718978 1.867316 0.144000
-v -2.714835 1.933517 -0.189000
-v -2.714835 1.933517 0.189000
-v -2.713200 1.365600 -0.225000
-v -2.713200 1.365600 0.225000
-v -2.711100 1.177800 -0.144000
-v -2.711100 1.177800 0.144000
-v -2.708400 1.800000 -0.081000
-v -2.708400 1.800000 0.081000
-v -2.706950 2.114698 -0.189000
-v -2.706950 2.114698 0.189000
-v -2.704570 1.630493 -0.144000
-v -2.704570 1.630493 0.144000
-v -2.702175 1.724519 -0.081000
-v -2.702175 1.724519 0.081000
-v -2.700000 1.800000 0.000000
-v -2.699644 1.518063 0.189000
-v -2.699644 1.518063 -0.189000
-v -2.696413 1.862682 -0.081000
-v -2.696413 1.862682 0.081000
-v -2.693900 1.726200 0.000000
-v -2.689846 1.999859 -0.216000
-v -2.689846 1.999859 0.216000
-v -2.689400 1.199325 -0.189000
-v -2.689400 1.199325 0.189000
-v -2.688100 1.860975 0.000000
-v -2.688100 1.860975 0.000000
-v -2.683107 1.638610 -0.081000
-v -2.683107 1.638610 0.081000
-v -2.682669 1.921219 -0.144000
-v -2.682669 1.921219 0.144000
-v -2.678982 1.390819 -0.216000
-v -2.678982 1.390819 0.216000
-v -2.675200 1.641600 0.000000
-v -2.675200 1.641600 0.000000
-v -2.673549 2.090707 -0.216000
-v -2.673549 2.090707 0.216000
-v -2.670428 1.534053 -0.144000
-v -2.670428 1.534053 0.144000
-v -2.663050 1.225463 -0.216000
-v -2.663050 1.225463 0.216000
-v -2.660842 1.912874 0.081000
-v -2.660842 1.912874 -0.081000
-v -2.653085 1.979755 -0.189000
-v -2.653085 1.979755 0.189000
-v -2.652800 1.909800 0.000000
-v -2.652800 1.909800 0.000000
-v -2.650604 1.544903 0.081000
-v -2.650604 1.544903 -0.081000
-v -2.647539 1.413994 -0.189000
-v -2.647539 1.413994 0.189000
-v -2.643300 1.548900 0.000000
-v -2.637200 2.064600 -0.225000
-v -2.637200 2.064600 0.225000
-v -2.634375 1.253906 0.225000
-v -2.634375 1.253906 -0.225000
-v -2.625000 2.193750 0.000000
-v -2.622811 1.963199 -0.144000
-v -2.622811 1.963199 0.144000
-v -2.621645 1.433078 -0.144000
-v -2.621645 1.433078 0.144000
-v -2.619050 2.188238 -0.081000
-v -2.619050 2.188238 0.081000
-v -2.611200 1.038600 0.000000
-v -2.611200 1.038600 0.000000
-v -2.607034 1.044497 0.081000
-v -2.607034 1.044497 -0.081000
-v -2.605700 1.282350 -0.216000
-v -2.605700 1.282350 0.216000
-v -2.604074 1.446029 -0.081000
-v -2.604074 1.446029 0.081000
-v -2.602900 2.173275 -0.144000
-v -2.602900 2.173275 0.144000
-v -2.602268 1.951964 -0.081000
-v -2.602268 1.951964 0.081000
-v -2.600851 2.038493 -0.216000
-v -2.600851 2.038493 0.216000
-v -2.597600 1.450800 0.000000
-v -2.595725 1.060502 -0.144000
-v -2.595725 1.060502 0.144000
-v -2.594700 1.947825 0.000000
-v -2.579350 1.308488 -0.189000
-v -2.579350 1.308488 0.189000
-v -2.579100 2.151225 -0.189000
-v -2.579100 2.151225 0.189000
-v -2.579059 1.084090 -0.189000
-v -2.579059 1.084090 0.189000
-v -2.567450 2.014502 -0.189000
-v -2.567450 2.014502 0.189000
-v -2.558822 1.112731 0.216000
-v -2.558822 1.112731 -0.216000
-v -2.557650 1.330013 -0.144000
-v -2.557650 1.330013 0.144000
-v -2.550200 2.124450 -0.216000
-v -2.550200 2.124450 0.216000
-v -2.542925 1.344619 0.081000
-v -2.542925 1.344619 -0.081000
-v -2.539942 1.994746 -0.144000
-v -2.539942 1.994746 0.144000
-v -2.537500 1.350000 0.000000
-v -2.537500 1.350000 0.000000
-v -2.536800 1.143900 0.225000
-v -2.536800 1.143900 -0.225000
-v -2.521277 1.981339 -0.081000
-v -2.521277 1.981339 0.081000
-v -2.518750 2.095312 -0.225000
-v -2.518750 2.095312 0.225000
-v -2.514778 1.175069 0.216000
-v -2.514778 1.175069 -0.216000
-v -2.514400 1.976400 0.000000
-v -2.514400 1.976400 0.000000
-v -2.494541 1.203710 -0.189000
-v -2.494541 1.203710 0.189000
-v -2.487300 2.066175 -0.216000
-v -2.487300 2.066175 0.216000
-v -2.477875 1.227298 -0.144000
-v -2.477875 1.227298 0.144000
-v -2.468350 0.922987 0.000000
-v -2.466566 1.243303 0.081000
-v -2.466566 1.243303 -0.081000
-v -2.465644 0.929375 -0.081000
-v -2.465644 0.929375 0.081000
-v -2.462400 1.249200 0.000000
-v -2.462400 1.249200 0.000000
-v -2.460000 2.221200 0.000000
-v -2.460000 2.221200 0.000000
-v -2.458400 2.039400 -0.189000
-v -2.458400 2.039400 0.189000
-v -2.458298 0.946711 -0.144000
-v -2.458298 0.946711 0.144000
-v -2.455229 2.215303 -0.081000
-v -2.455229 2.215303 0.081000
-v -2.447474 0.972260 0.189000
-v -2.447474 0.972260 -0.189000
-v -2.442278 2.199298 -0.144000
-v -2.442278 2.199298 0.144000
-v -2.434600 2.017350 -0.144000
-v -2.434600 2.017350 0.144000
-v -2.434329 1.003283 -0.216000
-v -2.434329 1.003283 0.216000
-v -2.423194 2.175710 -0.189000
-v -2.423194 2.175710 0.189000
-v -2.420025 1.037044 -0.225000
-v -2.420025 1.037044 0.225000
-v -2.418450 2.002387 -0.081000
-v -2.418450 2.002388 0.081000
-v -2.412500 1.996875 0.000000
-v -2.412500 1.996875 0.000000
-v -2.405721 1.070804 -0.216000
-v -2.405721 1.070804 0.216000
-v -2.400019 2.147069 -0.216000
-v -2.400019 2.147069 0.216000
-v -2.392576 1.101828 -0.189000
-v -2.392576 1.101828 0.189000
-v -2.381752 1.127376 -0.144000
-v -2.381752 1.127376 0.144000
-v -2.374800 2.115900 -0.225000
-v -2.374800 2.115900 0.225000
-v -2.374406 1.144713 0.081000
-v -2.374406 1.144713 -0.081000
-v -2.371700 1.151100 0.000000
-v -2.349581 2.084731 -0.216000
-v -2.349581 2.084731 0.216000
-v -2.326406 2.056090 -0.189000
-v -2.326406 2.056090 0.189000
-v -2.307322 2.032502 -0.144000
-v -2.307322 2.032502 0.144000
-v -2.302400 0.811200 0.000000
-v -2.302400 0.811200 0.000000
-v -2.301347 0.818122 0.081000
-v -2.301347 0.818122 -0.081000
-v -2.298490 0.836909 0.144000
-v -2.298490 0.836909 -0.144000
-v -2.294371 2.016497 -0.081000
-v -2.294371 2.016497 0.081000
-v -2.294278 0.864595 0.189000
-v -2.294278 0.864595 -0.189000
-v -2.289600 2.010600 0.000000
-v -2.289600 2.010600 0.000000
-v -2.289165 0.898214 0.216000
-v -2.289165 0.898214 -0.216000
-v -2.283600 0.934800 0.225000
-v -2.283600 0.934800 -0.225000
-v -2.278035 0.971386 0.216000
-v -2.278035 0.971386 -0.216000
-v -2.272922 1.005005 0.189000
-v -2.272922 1.005005 -0.189000
-v -2.268710 1.032691 -0.144000
-v -2.268710 1.032691 0.144000
-v -2.265853 1.051478 0.081000
-v -2.265853 1.051478 -0.081000
-v -2.265000 2.237850 0.000000
-v -2.264800 1.058400 0.000000
-v -2.264800 1.058400 0.000000
-v -2.261676 2.231720 -0.081000
-v -2.261676 2.231720 0.081000
-v -2.252655 2.215082 -0.144000
-v -2.252655 2.215082 0.144000
-v -2.239361 2.190562 -0.189000
-v -2.239361 2.190562 0.189000
-v -2.223218 2.160788 -0.216000
-v -2.223218 2.160788 0.216000
-v -2.205650 2.128387 0.225000
-v -2.205650 2.128388 -0.225000
-v -2.188082 2.095987 -0.216000
-v -2.188082 2.095987 0.216000
-v -2.171939 2.066213 -0.189000
-v -2.171939 2.066213 0.189000
-v -2.158645 2.041693 -0.144000
-v -2.158645 2.041693 0.144000
-v -2.149624 2.025055 -0.081000
-v -2.149624 2.025055 0.081000
-v -2.146300 2.018925 0.000000
-v -2.141100 0.973800 0.000000
-v -2.141100 0.973800 0.000000
-v -2.140315 0.966231 0.081000
-v -2.140315 0.966231 -0.081000
-v -2.138183 0.945685 0.144000
-v -2.138183 0.945685 -0.144000
-v -2.135041 0.915407 0.189000
-v -2.135041 0.915407 -0.189000
-v -2.131226 0.878641 0.216000
-v -2.131226 0.878641 -0.216000
-v -2.127075 0.838631 0.225000
-v -2.127075 0.838631 -0.225000
-v -2.122924 0.798621 0.216000
-v -2.122924 0.798621 -0.216000
-v -2.119109 0.761855 0.189000
-v -2.119109 0.761855 -0.189000
-v -2.115967 0.731578 0.144000
-v -2.115967 0.731578 -0.144000
-v -2.113835 0.711032 0.081000
-v -2.113835 0.711032 -0.081000
-v -2.113050 0.703463 0.000000
-v -2.113050 0.703463 0.000000
-v -2.040000 2.246400 0.000000
-v -2.040000 2.246400 0.000000
-v -2.038410 2.240150 -0.081000
-v -2.038410 2.240150 0.081000
-v -2.034093 2.223187 -0.144000
-v -2.034093 2.223187 0.144000
-v -2.027731 2.198189 -0.189000
-v -2.027731 2.198189 0.189000
-v -2.020006 2.167834 0.216000
-v -2.020006 2.167834 -0.216000
-v -2.011600 2.134800 0.225000
-v -2.011600 2.134800 -0.225000
-v -2.003194 2.101766 0.216000
-v -2.003194 2.101766 -0.216000
-v -2.000000 0.900000 0.000000
-v -2.000000 0.900000 0.000000
-v -2.000000 0.900000 0.000000
-v -1.997200 0.891600 0.081000
-v -1.997200 0.891600 -0.081000
-v -1.995469 2.071411 -0.189000
-v -1.995469 2.071411 0.189000
-v -1.992750 1.037175 -0.000000
-v -1.992750 1.037175 0.000000
-v -1.989600 0.868800 0.144000
-v -1.989600 0.868800 -0.144000
-v -1.989107 2.046413 0.144000
-v -1.989107 2.046413 -0.144000
-v -1.986000 0.771675 0.000000
-v -1.986000 0.771675 0.000000
-v -1.984790 2.029450 -0.081000
-v -1.984790 2.029450 0.081000
-v -1.983200 2.023200 0.000000
-v -1.983200 2.023200 0.000000
-v -1.978400 0.835200 0.189000
-v -1.978400 0.835200 -0.189000
-v -1.974240 0.900000 -0.328160
-v -1.974240 0.900000 -0.328160
-v -1.974240 0.900000 0.328160
-v -1.972000 1.178400 -0.000000
-v -1.972000 1.178400 0.000000
-v -1.967083 1.037175 -0.326970
-v -1.967083 1.037175 0.326970
-v -1.964800 0.794400 0.216000
-v -1.964800 0.794400 -0.216000
-v -1.960420 0.771675 -0.325863
-v -1.960420 0.771675 0.325863
-v -1.950000 0.750000 -0.225000
-v -1.950000 0.750000 0.225000
-v -1.948000 0.656400 0.000000
-v -1.948000 0.656400 0.000000
-v -1.946601 1.178400 -0.323566
-v -1.946601 1.178400 0.323566
-v -1.939250 1.323225 0.000000
-v -1.939250 1.323225 0.000000
-v -1.935200 0.705600 0.216000
-v -1.935200 0.705600 -0.216000
-v -1.922910 0.656400 -0.319628
-v -1.922910 0.656400 0.319628
-v -1.921600 0.664800 0.189000
-v -1.921600 0.664800 -0.189000
-v -1.914272 1.323225 -0.318192
-v -1.914272 1.323225 0.318192
-v -1.910400 0.631200 0.144000
-v -1.910400 0.631200 -0.144000
-v -1.902800 0.608400 0.081000
-v -1.902800 0.608400 -0.081000
-v -1.900000 0.600000 0.000000
-v -1.900000 0.600000 0.000000
-v -1.899520 0.900000 -0.638080
-v -1.899520 0.900000 -0.638080
-v -1.899520 0.900000 0.638080
-v -1.899520 0.900000 0.638080
-v -1.896000 1.471200 0.000000
-v -1.896000 1.471200 0.000000
-v -1.892634 1.037175 -0.635767
-v -1.892634 1.037175 0.635767
-v -1.892000 0.553725 0.000000
-v -1.892000 0.553725 0.000000
-v -1.886223 0.771675 -0.633613
-v -1.886223 0.771675 0.633613
-v -1.872927 1.178400 -0.629147
-v -1.872927 1.178400 0.629147
-v -1.871580 1.471200 -0.311096
-v -1.871580 1.471200 0.311096
-v -1.867631 0.553725 -0.310439
-v -1.867631 0.553725 0.310439
-v -1.850132 0.656400 -0.621490
-v -1.850132 0.656400 0.621490
-v -1.843750 1.621875 0.000000
-v -1.843750 1.621875 0.000000
-v -1.841822 1.323225 -0.618698
-v -1.841822 1.323225 0.618698
-v -1.824000 0.463200 -0.000000
-v -1.824000 0.463200 0.000000
-v -1.820003 1.621875 -0.302522
-v -1.820003 1.621875 0.302523
-v -1.800900 2.024775 0.000000
-v -1.800745 1.471200 -0.604900
-v -1.800745 1.471200 0.604900
-v -1.800507 0.463200 -0.299282
-v -1.800507 0.463200 0.299282
-v -1.800455 2.031069 -0.081000
-v -1.800455 2.031069 0.081000
-v -1.799246 2.048152 -0.144000
-v -1.799246 2.048152 0.144000
-v -1.797466 2.073326 -0.189000
-v -1.797466 2.073326 0.189000
-v -1.796946 0.553725 -0.603624
-v -1.796946 0.553725 0.603624
-v -1.795303 2.103896 -0.216000
-v -1.795303 2.103896 0.216000
-v -1.792950 2.137163 -0.225000
-v -1.792950 2.137163 0.225000
-v -1.790597 2.170429 -0.216000
-v -1.790597 2.170429 0.216000
-v -1.788434 2.200999 -0.189000
-v -1.788434 2.200999 0.189000
-v -1.786654 2.226173 -0.144000
-v -1.786654 2.226173 0.144000
-v -1.785445 2.243256 -0.081000
-v -1.785445 2.243256 0.081000
-v -1.785000 2.249550 0.000000
-v -1.784000 1.774800 -0.000000
-v -1.784000 1.774800 0.000000
-v -1.779680 0.900000 -0.925920
-v -1.779680 0.900000 -0.925920
-v -1.779680 0.900000 0.925920
-v -1.779680 0.900000 0.925920
-v -1.773229 1.037175 -0.922564
-v -1.773229 1.037175 0.922564
-v -1.767222 0.771675 -0.919439
-v -1.767222 0.771675 0.919439
-v -1.761022 1.774800 -0.292719
-v -1.761022 1.774800 0.292719
-v -1.754764 1.178400 -0.912957
-v -1.754764 1.178400 0.912957
-v -1.751120 1.621875 -0.588230
-v -1.751120 1.621875 0.588230
-v -1.750000 0.384375 -0.000000
-v -1.750000 0.384375 0.000000
-v -1.733408 0.656400 -0.901846
-v -1.733408 0.656400 0.901846
-v -1.732362 0.463200 -0.581929
-v -1.732362 0.463200 0.581929
-v -1.727460 0.384375 -0.287140
-v -1.727460 0.384375 0.287140
-v -1.725622 1.323225 -0.897795
-v -1.725622 1.323225 0.897795
-v -1.718250 1.929525 -0.000000
-v -1.718250 1.929525 0.000000
-v -1.696119 1.929525 -0.281930
-v -1.696119 1.929525 0.281930
-v -1.694372 1.774800 -0.569167
-v -1.694372 1.774800 0.569167
-v -1.687137 1.471200 -0.877772
-v -1.687137 1.471200 0.877772
-v -1.683577 0.553725 -0.875920
-v -1.683577 0.553725 0.875920
-v -1.676000 0.316800 0.000000
-v -1.676000 0.316800 0.000000
-v -1.662080 0.384375 -0.558320
-v -1.662080 0.384375 0.558320
-v -1.654413 0.316800 -0.274998
-v -1.654413 0.316800 0.274998
-v -1.648000 2.085600 0.000000
-v -1.648000 2.085600 0.000000
-v -1.640643 1.621875 -0.853583
-v -1.640643 1.621875 0.853583
-v -1.631925 1.929525 -0.548190
-v -1.631925 1.929525 0.548190
-v -1.626774 2.085600 -0.270404
-v -1.626774 2.085600 0.270404
-v -1.623068 0.463200 -0.844439
-v -1.623068 0.463200 0.844439
-v -1.618560 0.900000 -1.187840
-v -1.618560 0.900000 -1.187840
-v -1.618560 0.900000 1.187840
-v -1.618560 0.900000 1.187840
-v -1.612693 1.037175 -1.183534
-v -1.612693 1.037175 1.183534
-v -1.608000 0.260025 -0.000000
-v -1.608000 0.260025 0.000000
-v -1.607230 0.771675 -1.179525
-v -1.607230 0.771675 1.179525
-v -1.600000 2.025000 0.000000
-v -1.597200 2.031300 -0.081000
-v -1.597200 2.031300 0.081000
-v -1.595900 1.178400 -1.171210
-v -1.595900 1.178400 1.171210
-v -1.591798 0.316800 -0.534711
-v -1.591798 0.316800 0.534711
-v -1.589600 2.048400 -0.144000
-v -1.589600 2.048400 0.144000
-v -1.587475 1.774800 -0.825921
-v -1.587475 1.774800 0.825921
-v -1.587289 0.260025 0.263841
-v -1.587289 0.260025 -0.263841
-v -1.578400 2.073600 -0.189000
-v -1.578400 2.073600 0.189000
-v -1.576477 0.656400 -1.156956
-v -1.576477 0.656400 1.156956
-v -1.574750 2.242575 0.000000
-v -1.574750 2.242575 0.000000
-v -1.569396 1.323225 -1.151759
-v -1.569396 1.323225 1.151759
-v -1.565204 2.085600 -0.525778
-v -1.565204 2.085600 0.525778
-v -1.564800 2.104200 -0.216000
-v -1.564800 2.104200 0.216000
-v -1.557220 0.384375 -0.810180
-v -1.557220 0.384375 0.810180
-v -1.554467 2.242575 -0.258385
-v -1.554467 2.242575 0.258385
-v -1.552000 0.213600 0.000000
-v -1.552000 0.213600 0.000000
-v -1.550000 2.137500 -0.225000
-v -1.550000 2.137500 0.225000
-v -1.535200 2.170800 -0.216000
-v -1.535200 2.170800 0.216000
-v -1.534395 1.471200 -1.126072
-v -1.534395 1.471200 1.126072
-v -1.532010 0.213600 0.254652
-v -1.532010 0.213600 -0.254652
-v -1.531158 0.553725 -1.123697
-v -1.531158 0.553725 1.123697
-v -1.528968 1.929525 -0.795481
-v -1.528968 1.929525 0.795481
-v -1.527214 0.260025 -0.513016
-v -1.527214 0.260025 0.513016
-v -1.521600 2.201400 -0.189000
-v -1.521600 2.201400 0.189000
-v -1.514000 0.177075 0.000000
-v -1.514000 0.177075 0.000000
-v -1.510400 2.226600 -0.144000
-v -1.510400 2.226600 0.144000
-v -1.502800 2.243700 -0.081000
-v -1.502800 2.243700 0.081000
-v -1.500000 2.400000 0.000000
-v -1.500000 0.150000 0.000000
-v -1.500000 2.250000 0.000000
-v -1.500000 2.400000 0.000000
-v -1.500000 0.150000 0.000000
-v -1.496475 0.127575 -0.000000
-v -1.496475 0.127575 0.000000
-v -1.495635 2.242575 -0.502408
-v -1.495635 2.242575 0.502408
-v -1.494500 0.177075 0.248417
-v -1.494500 0.177075 -0.248417
-v -1.492110 1.621875 -1.095040
-v -1.492110 1.621875 1.095040
-v -1.491372 0.316800 -0.775921
-v -1.491372 0.316800 0.775921
-v -1.480800 0.105600 0.000000
-v -1.480800 0.105600 -0.000000
-v -1.480680 2.400000 -0.246120
-v -1.480680 0.150000 0.246120
-v -1.480680 2.400000 0.246120
-v -1.480680 0.150000 -0.246120
-v -1.480680 0.150000 -0.246120
-v -1.480680 0.150000 0.246120
-v -1.480325 2.435437 0.000000
-v -1.480325 2.435437 0.000000
-v -1.477200 0.127575 0.245542
-v -1.477200 0.127575 -0.245542
-v -1.476127 0.463200 -1.083310
-v -1.476127 0.463200 1.083310
-v -1.474028 0.213600 0.495150
-v -1.474028 0.213600 -0.495150
-v -1.466456 2.085600 -0.762958
-v -1.466456 2.085600 0.762958
-v -1.461727 0.105600 -0.242970
-v -1.461727 0.105600 0.242970
-v -1.461258 2.435437 -0.242892
-v -1.461258 2.435437 0.242892
-v -1.459600 2.463000 0.000000
-v -1.459600 2.463000 0.000000
-v -1.445325 0.084525 0.000000
-v -1.445325 0.084525 0.000000
-v -1.443756 1.774800 -1.059553
-v -1.443756 1.774800 1.059553
-v -1.440800 2.463000 -0.239491
-v -1.440800 2.463000 0.239491
-v -1.439025 2.482687 0.000000
-v -1.437937 0.177075 0.483027
-v -1.437937 0.177075 -0.483027
-v -1.430863 0.260025 0.744440
-v -1.430863 0.260025 -0.744440
-v -1.426709 0.084525 -0.237149
-v -1.426709 0.084525 0.237149
-v -1.424640 2.400000 -0.478560
-v -1.424640 0.150000 -0.478560
-v -1.424640 0.150000 -0.478560
-v -1.424640 0.150000 0.478560
-v -1.424640 0.150000 0.478560
-v -1.424640 2.400000 0.478560
-v -1.421292 0.127575 0.477435
-v -1.421292 0.127575 -0.477435
-v -1.420490 2.482687 -0.236115
-v -1.420490 2.482687 0.236115
-v -1.420000 0.900000 -1.420000
-v -1.420000 0.900000 -1.420000
-v -1.420000 0.900000 1.420000
-v -1.420000 0.900000 1.420000
-v -1.419800 2.494500 0.000000
-v -1.419800 2.494500 0.000000
-v -1.416240 0.384375 -1.039360
-v -1.416240 0.384375 1.039360
-v -1.414853 1.037175 -1.414853
-v -1.414853 1.037175 1.414853
-v -1.410060 0.771675 -1.410060
-v -1.410060 0.771675 1.410060
-v -1.406405 0.105600 -0.472434
-v -1.406405 0.105600 0.472434
-v -1.405953 2.435437 -0.472283
-v -1.405953 2.435437 0.472283
-v -1.403125 2.498438 0.000000
-v -1.403125 2.498438 0.000000
-v -1.401513 2.494500 -0.232961
-v -1.401513 2.494500 0.232961
-v -1.401276 2.242575 -0.729046
-v -1.401276 2.242575 0.729046
-v -1.400120 1.178400 -1.400120
-v -1.400120 1.178400 1.400120
-v -1.400000 2.400000 0.000000
-v -1.400000 2.400000 0.000000
-v -1.390545 1.929525 -1.020503
-v -1.390545 1.929525 1.020503
-v -1.390200 2.494500 0.000000
-v -1.390200 2.494500 0.000000
-v -1.386270 2.463000 -0.465671
-v -1.386270 2.463000 0.465671
-v -1.385925 2.435437 0.000000
-v -1.385925 2.435437 0.000000
-v -1.385053 2.498438 -0.230225
-v -1.385053 2.498438 0.230225
-v -1.383080 0.656400 -1.383080
-v -1.383080 0.656400 1.383080
-v -1.382400 0.064800 -0.000000
-v -1.382400 0.064800 0.000000
-v -1.382225 2.482687 -0.000000
-v -1.382225 2.482687 0.000000
-v -1.381968 2.400000 -0.229712
-v -1.381968 2.400000 0.229712
-v -1.381032 0.213600 0.718514
-v -1.381032 0.213600 -0.718514
-v -1.380400 2.463000 0.000000
-v -1.380400 2.463000 0.000000
-v -1.376868 1.323225 -1.376867
-v -1.376867 1.323225 1.376868
-v -1.372712 0.084525 -0.461116
-v -1.372712 0.084525 0.461116
-v -1.372294 2.494500 -0.228104
-v -1.372294 2.494500 0.228104
-v -1.368074 2.435437 -0.227403
-v -1.368074 2.435437 0.227403
-v -1.366728 2.482687 -0.459107
-v -1.366728 2.482687 0.459107
-v -1.364595 0.064800 -0.226824
-v -1.364595 0.064800 0.226824
-v -1.364422 2.482687 -0.226795
-v -1.364422 2.482687 0.226795
-v -1.362620 2.463000 -0.226496
-v -1.362620 2.463000 0.226496
-v -1.356353 0.316800 -0.995410
-v -1.356353 0.316800 0.995410
-v -1.348469 2.494500 -0.452973
-v -1.348469 2.494500 0.452973
-v -1.347218 0.177075 0.700921
-v -1.347218 0.177075 -0.700921
-v -1.346160 1.471200 -1.346160
-v -1.346160 1.471200 1.346160
-v -1.343320 0.553725 -1.343320
-v -1.343320 0.553725 1.343320
-v -1.334760 2.400000 -0.694440
-v -1.334760 0.150000 -0.694440
-v -1.334760 0.150000 0.694440
-v -1.334760 0.150000 0.694440
-v -1.334760 2.400000 0.694440
-v -1.334760 0.150000 -0.694440
-v -1.333693 2.085600 -0.978780
-v -1.333693 2.085600 0.978780
-v -1.332632 2.498438 -0.447653
-v -1.332632 2.498438 0.447653
-v -1.331623 0.127575 0.692808
-v -1.331623 0.127575 -0.692808
-v -1.329664 2.400000 -0.446656
-v -1.329664 2.400000 0.446656
-v -1.320356 2.494500 -0.443529
-v -1.320356 2.494500 0.443529
-v -1.317675 0.105600 -0.685551
-v -1.317675 0.105600 0.685551
-v -1.317252 2.435437 -0.685331
-v -1.317252 2.435437 0.685331
-v -1.316296 2.435437 -0.442166
-v -1.316296 2.435437 0.442166
-v -1.312948 0.064800 0.441041
-v -1.312948 0.064800 -0.441041
-v -1.312782 2.482687 -0.440985
-v -1.312782 2.482687 0.440985
-v -1.311049 2.463000 -0.440403
-v -1.311049 2.463000 0.440403
-v -1.309063 1.621875 -1.309063
-v -1.309063 1.621875 1.309063
-v -1.301322 0.260025 0.955023
-v -1.301322 0.260025 -0.955023
-v -1.300000 2.400000 0.000000
-v -1.300000 2.400000 0.000000
-v -1.298810 2.463000 -0.675736
-v -1.298810 2.463000 0.675736
-v -1.295040 0.463200 -1.295040
-v -1.295040 0.463200 1.295040
-v -1.286108 0.084525 -0.669128
-v -1.286108 0.084525 0.669128
-v -1.284375 0.046875 0.000000
-v -1.284375 0.046875 0.000000
-v -1.283256 2.400000 -0.213304
-v -1.283256 2.400000 0.213304
-v -1.280502 2.482687 -0.666211
-v -1.280502 2.482687 0.666211
-v -1.274600 2.440800 0.000000
-v -1.274600 2.440800 0.000000
-v -1.274414 2.242575 -0.935276
-v -1.274414 2.242575 0.935276
-v -1.267832 0.046875 -0.210740
-v -1.267832 0.046875 0.210740
-v -1.266640 1.774800 -1.266640
-v -1.266640 1.774800 1.266640
-v -1.263395 2.494500 -0.657311
-v -1.263395 2.494500 0.657311
-v -1.258183 2.440800 0.209136
-v -1.258183 2.440800 -0.209136
-v -1.256003 0.213600 0.921764
-v -1.256003 0.213600 -0.921764
-v -1.248557 2.498438 -0.649591
-v -1.248557 2.498438 0.649591
-v -1.245776 2.400000 -0.648144
-v -1.245776 2.400000 0.648144
-v -1.242500 0.384375 -1.242500
-v -1.242500 0.384375 1.242500
-v -1.237056 2.494500 -0.643607
-v -1.237056 2.494500 0.643607
-v -1.234688 2.400000 -0.414752
-v -1.234688 2.400000 0.414752
-v -1.233252 2.435437 -0.641628
-v -1.233252 2.435437 0.641628
-v -1.230115 0.064800 -0.639996
-v -1.230115 0.064800 0.639996
-v -1.229959 2.482687 -0.639915
-v -1.229959 2.482687 0.639915
-v -1.228335 2.463000 -0.639070
-v -1.228335 2.463000 0.639070
-v -1.225250 0.177075 0.899195
-v -1.225250 0.177075 -0.899195
-v -1.219958 1.929525 1.219958
-v -1.219958 1.929525 -1.219958
-v -1.219848 0.046875 -0.409767
-v -1.219848 0.046875 0.409767
-v -1.213920 2.400000 -0.890880
-v -1.213920 0.150000 -0.890880
-v -1.213920 0.150000 -0.890880
-v -1.213920 0.150000 0.890880
-v -1.213920 0.150000 0.890880
-v -1.213920 2.400000 0.890880
-v -1.211067 0.127575 0.888786
-v -1.211067 0.127575 -0.888786
-v -1.210564 2.440800 0.406648
-v -1.210564 2.440800 -0.406648
-v -1.204800 2.474400 0.000000
-v -1.204800 2.474400 0.000000
-v -1.198382 0.105600 -0.879477
-v -1.198382 0.105600 0.879477
-v -1.197997 2.435437 -0.879195
-v -1.197997 2.435437 0.879195
-v -1.189960 0.316800 -1.189960
-v -1.189960 0.316800 1.189960
-v -1.189282 2.474400 -0.197684
-v -1.189282 2.474400 0.197684
-v -1.187840 0.900000 -1.618560
-v -1.187840 0.900000 -1.618560
-v -1.187840 0.900000 1.618560
-v -1.187840 0.900000 1.618560
-v -1.183534 1.037175 -1.612693
-v -1.183534 1.037175 1.612693
-v -1.181225 2.463000 -0.866886
-v -1.181225 2.463000 0.866886
-v -1.179525 0.771675 -1.607230
-v -1.179525 0.771675 1.607230
-v -1.171210 1.178400 -1.595900
-v -1.171210 1.178400 1.595900
-v -1.170080 2.085600 -1.170080
-v -1.170080 2.085600 1.170080
-v -1.169673 0.084525 -0.858407
-v -1.169673 0.084525 0.858407
-v -1.164574 2.482687 -0.854666
-v -1.164574 2.482687 0.854666
-v -1.156956 0.656400 -1.576477
-v -1.156956 0.656400 1.576477
-v -1.156792 2.400000 -0.601848
-v -1.156792 2.400000 0.601848
-v -1.151759 1.323225 -1.569396
-v -1.151759 1.323225 1.569396
-v -1.149016 2.494500 -0.843248
-v -1.149016 2.494500 0.843248
-v -1.144271 2.474400 -0.384379
-v -1.144271 2.474400 0.384379
-v -1.143600 0.031200 0.000000
-v -1.143600 0.031200 0.000000
-v -1.142888 0.046875 -0.594614
-v -1.142888 0.046875 0.594614
-v -1.141680 0.260025 1.141680
-v -1.141680 0.260025 -1.141680
-v -1.135521 2.498438 -0.833344
-v -1.135521 2.498438 0.833344
-v -1.134190 2.440800 0.590089
-v -1.134190 2.440800 -0.590089
-v -1.132992 2.400000 -0.831488
-v -1.132992 2.400000 0.831488
-v -1.128870 0.031200 -0.187642
-v -1.128870 0.031200 0.187642
-v -1.126072 1.471200 -1.534395
-v -1.126072 1.471200 1.534395
-v -1.125061 2.494500 -0.825668
-v -1.125061 2.494500 0.825668
-v -1.123697 0.553725 -1.531158
-v -1.123697 0.553725 1.531158
-v -1.121601 2.435437 -0.823129
-v -1.121601 2.435437 0.823129
-v -1.118749 0.064800 -0.821035
-v -1.118749 0.064800 0.821035
-v -1.118607 2.482687 -0.820931
-v -1.118607 2.482687 0.820931
-v -1.118073 2.242575 -1.118073
-v -1.118073 2.242575 1.118073
-v -1.117130 2.463000 -0.819847
-v -1.117130 2.463000 0.819847
-v -1.101920 0.213600 1.101920
-v -1.101920 0.213600 -1.101920
-v -1.100200 2.502600 0.000000
-v -1.100200 2.502600 0.000000
-v -1.095040 1.621875 -1.492110
-v -1.095040 1.621875 1.492110
-v -1.086146 0.031200 0.364854
-v -1.086146 0.031200 -0.364854
-v -1.086029 2.502600 0.180521
-v -1.086029 2.502600 -0.180521
-v -1.083310 0.463200 -1.476127
-v -1.083310 0.463200 1.476127
-v -1.074940 0.177075 -1.074940
-v -1.074940 0.177075 1.074940
-v -1.072079 2.474400 -0.557774
-v -1.072079 2.474400 0.557774
-v -1.065000 2.400000 -1.065000
-v -1.065000 0.150000 -1.065000
-v -1.065000 0.150000 1.065000
-v -1.065000 2.400000 1.065000
-v -1.062497 0.127575 1.062497
-v -1.062497 0.127575 -1.062497
-v -1.059553 1.774800 -1.443756
-v -1.059553 1.774800 1.443756
-v -1.052064 2.400000 -0.772096
-v -1.052064 2.400000 0.772096
-v -1.051368 0.105600 -1.051368
-v -1.051368 0.105600 1.051368
-v -1.051031 2.435437 -1.051031
-v -1.051031 2.435437 1.051031
-v -1.044926 2.502600 -0.351008
-v -1.044926 2.502600 0.351008
-v -1.039419 0.046875 -0.762816
-v -1.039419 0.046875 0.762816
-v -1.039360 0.384375 -1.416240
-v -1.039360 0.384375 1.416240
-v -1.036316 2.463000 -1.036316
-v -1.036316 2.463000 1.036316
-v -1.031508 2.440800 0.757010
-v -1.031508 2.440800 -0.757010
-v -1.026181 0.084525 -1.026181
-v -1.026181 0.084525 1.026181
-v -1.021708 2.482687 -1.021708
-v -1.021708 2.482687 1.021708
-v -1.020503 1.929525 -1.390545
-v -1.020503 1.929525 1.390545
-v -1.017621 0.031200 0.529441
-v -1.017621 0.031200 -0.529441
-v -1.008058 2.494500 -1.008058
-v -1.008058 2.494500 1.008058
-v -0.996219 2.498438 -0.996219
-v -0.996219 2.498438 0.996219
-v -0.995410 0.316800 -1.356353
-v -0.995410 0.316800 1.356353
-v -0.994000 2.400000 -0.994000
-v -0.994000 2.400000 0.994000
-v -0.987042 2.494500 -0.987042
-v -0.987042 2.494500 0.987042
-v -0.984007 2.435437 -0.984007
-v -0.984007 2.435437 0.984007
-v -0.981504 0.064800 0.981504
-v -0.981504 0.064800 -0.981504
-v -0.981380 2.482687 -0.981380
-v -0.981380 2.482687 0.981380
-v -0.980084 2.463000 -0.980084
-v -0.980084 2.463000 0.980084
-v -0.979002 2.502600 0.509349
-v -0.979002 2.502600 -0.509349
-v -0.978780 2.085600 -1.333693
-v -0.978780 2.085600 1.333693
-v -0.975021 2.474400 -0.715555
-v -0.975021 2.474400 0.715555
-v -0.970400 2.527200 0.000000
-v -0.970400 2.527200 0.000000
-v -0.957901 2.527200 -0.159223
-v -0.957901 2.527200 0.159223
-v -0.955023 0.260025 1.301322
-v -0.955023 0.260025 -1.301322
-v -0.952425 0.018225 -0.000000
-v -0.952425 0.018225 0.000000
-v -0.940158 0.018225 0.156274
-v -0.940158 0.018225 -0.156274
-v -0.935276 2.242575 -1.274414
-v -0.935276 2.242575 1.274414
-v -0.925920 0.900000 -1.779680
-v -0.925920 0.900000 1.779680
-v -0.925920 0.900000 1.779680
-v -0.925920 0.900000 -1.779680
-v -0.925493 0.031200 0.679207
-v -0.925493 0.031200 -0.679207
-v -0.923000 2.400000 -0.923000
-v -0.923000 2.400000 0.923000
-v -0.922564 1.037175 1.773229
-v -0.922564 1.037175 -1.773229
-v -0.921764 0.213600 1.256003
-v -0.921764 0.213600 -1.256003
-v -0.921647 2.527200 -0.309596
-v -0.921647 2.527200 0.309596
-v -0.919439 0.771675 -1.767222
-v -0.919439 0.771675 1.767222
-v -0.912957 1.178400 -1.754764
-v -0.912957 1.178400 1.754764
-v -0.911906 0.046875 -0.911906
-v -0.911906 0.046875 0.911906
-v -0.904966 2.440800 0.904966
-v -0.904966 2.440800 -0.904966
-v -0.904575 0.018225 0.303862
-v -0.904575 0.018225 -0.303862
-v -0.901846 0.656400 -1.733408
-v -0.901846 0.656400 1.733408
-v -0.899195 0.177075 1.225250
-v -0.899195 0.177075 -1.225250
-v -0.897795 1.323225 -1.725622
-v -0.897795 1.323225 1.725622
-v -0.890880 0.150000 -1.213920
-v -0.890880 0.150000 1.213920
-v -0.890880 2.400000 -1.213920
-v -0.890880 0.150000 -1.213920
-v -0.890880 0.150000 1.213920
-v -0.890880 2.400000 1.213920
-v -0.890370 2.502600 -0.653431
-v -0.890370 2.502600 0.653431
-v -0.888786 0.127575 1.211067
-v -0.888786 0.127575 -1.211067
-v -0.879477 0.105600 -1.198382
-v -0.879477 0.105600 1.198382
-v -0.879195 2.435437 -1.197997
-v -0.879195 2.435437 1.197997
-v -0.877772 1.471200 -1.687137
-v -0.877772 1.471200 1.687137
-v -0.875920 0.553725 -1.683577
-v -0.875920 0.553725 1.683577
-v -0.866886 2.463000 -1.181225
-v -0.866886 2.463000 1.181225
-v -0.863501 2.527200 -0.449256
-v -0.863501 2.527200 0.449256
-v -0.858407 0.084525 -1.169673
-v -0.858407 0.084525 1.169673
-v -0.855408 2.474400 -0.855408
-v -0.855408 2.474400 0.855408
-v -0.854666 2.482687 -1.164574
-v -0.854666 2.482687 1.164574
-v -0.853583 1.621875 -1.640643
-v -0.853583 1.621875 1.640643
-v -0.847506 0.018225 -0.440935
-v -0.847506 0.018225 0.440935
-v -0.844439 0.463200 1.623068
-v -0.844439 0.463200 -1.623068
-v -0.843248 2.494500 -1.149016
-v -0.843248 2.494500 1.149016
-v -0.833344 2.498438 -1.135521
-v -0.833344 2.498438 1.135521
-v -0.831488 2.400000 -1.132992
-v -0.831488 2.400000 1.132992
-v -0.825921 1.774800 1.587475
-v -0.825921 1.774800 -1.587475
-v -0.825668 2.494500 -1.125061
-v -0.825668 2.494500 1.125061
-v -0.825000 2.550000 0.000000
-v -0.825000 2.550000 0.000000
-v -0.823129 2.435437 -1.121601
-v -0.823129 2.435437 1.121601
-v -0.821035 0.064800 1.118749
-v -0.821035 0.064800 -1.118749
-v -0.820931 2.482687 1.118607
-v -0.820931 2.482687 -1.118607
-v -0.819847 2.463000 -1.117130
-v -0.819847 2.463000 1.117130
-v -0.814374 2.550000 -0.135366
-v -0.814374 2.550000 0.135366
-v -0.811956 0.031200 0.811956
-v -0.811956 0.031200 -0.811956
-v -0.810180 0.384375 1.557220
-v -0.810180 0.384375 -1.557220
-v -0.795481 1.929525 1.528968
-v -0.795481 1.929525 -1.528968
-v -0.785325 2.527200 -0.576340
-v -0.785325 2.527200 0.576340
-v -0.783552 2.550000 -0.263208
-v -0.783552 2.550000 0.263208
-v -0.781142 2.502600 -0.781142
-v -0.781142 2.502600 0.781142
-v -0.775921 0.316800 -1.491372
-v -0.775921 0.316800 1.491372
-v -0.772096 2.400000 -1.052064
-v -0.772096 2.400000 1.052064
-v -0.770779 0.018225 0.565664
-v -0.770779 0.018225 -0.565664
-v -0.762958 2.085600 -1.466456
-v -0.762958 2.085600 1.466456
-v -0.762816 0.046875 -1.039419
-v -0.762816 0.046875 1.039419
-v -0.757010 2.440800 1.031508
-v -0.757010 2.440800 -1.031508
-v -0.744440 0.260025 1.430863
-v -0.744440 0.260025 -1.430863
-v -0.734118 2.550000 -0.381942
-v -0.734118 2.550000 0.381942
-v -0.729046 2.242575 -1.401276
-v -0.729046 2.242575 1.401276
-v -0.718514 0.213600 1.381032
-v -0.718514 0.213600 -1.381032
-v -0.715555 2.474400 -0.975021
-v -0.715555 2.474400 0.975021
-v -0.703200 0.008400 0.000000
-v -0.700921 0.177075 1.347218
-v -0.700921 0.177075 -1.347218
-v -0.694440 0.150000 -1.334760
-v -0.694440 0.150000 1.334760
-v -0.694440 2.400000 1.334760
-v -0.694440 0.150000 1.334760
-v -0.694440 2.400000 -1.334760
-v -0.694440 0.150000 -1.334760
-v -0.694143 0.008400 -0.115381
-v -0.694143 0.008400 0.115381
-v -0.692808 0.127575 1.331623
-v -0.692808 0.127575 -1.331623
-v -0.688984 2.527200 -0.688984
-v -0.688984 2.527200 0.688984
-v -0.685551 0.105600 -1.317675
-v -0.685551 0.105600 1.317675
-v -0.685331 2.435437 -1.317252
-v -0.685331 2.435437 1.317252
-v -0.679207 0.031200 -0.925493
-v -0.679207 0.031200 0.925493
-v -0.676222 0.018225 0.676222
-v -0.676222 0.018225 -0.676222
-v -0.675736 2.463000 -1.298810
-v -0.675736 2.463000 1.298810
-v -0.673600 2.572800 0.000000
-v -0.673600 2.572800 0.000000
-v -0.669128 0.084525 -1.286108
-v -0.669128 0.084525 1.286108
-v -0.667871 0.008400 -0.224349
-v -0.667871 0.008400 0.224349
-v -0.667656 2.550000 -0.489984
-v -0.667656 2.550000 0.489984
-v -0.666211 2.482687 1.280502
-v -0.666211 2.482687 -1.280502
-v -0.664924 2.572800 -0.110524
-v -0.664924 2.572800 0.110524
-v -0.657311 2.494500 -1.263395
-v -0.657311 2.494500 1.263395
-v -0.653431 2.502600 -0.890370
-v -0.653431 2.502600 0.890370
-v -0.649591 2.498438 -1.248557
-v -0.649591 2.498438 1.248557
-v -0.648144 2.400000 -1.245776
-v -0.648144 2.400000 1.245776
-v -0.643607 2.494500 -1.237056
-v -0.643607 2.494500 1.237056
-v -0.641628 2.435437 -1.233252
-v -0.641628 2.435437 1.233252
-v -0.639996 0.064800 -1.230115
-v -0.639996 0.064800 1.230115
-v -0.639915 2.482687 1.229959
-v -0.639915 2.482687 -1.229959
-v -0.639758 2.572800 -0.214905
-v -0.639758 2.572800 0.214905
-v -0.639070 2.463000 -1.228335
-v -0.639070 2.463000 1.228335
-v -0.638080 0.900000 -1.899520
-v -0.638080 0.900000 -1.899520
-v -0.638080 0.900000 1.899520
-v -0.638080 0.900000 1.899520
-v -0.635767 1.037175 -1.892634
-v -0.635767 1.037175 1.892634
-v -0.633613 0.771675 -1.886223
-v -0.633613 0.771675 1.886223
-v -0.629147 1.178400 -1.872927
-v -0.629147 1.178400 1.872927
-v -0.625735 0.008400 0.325553
-v -0.625735 0.008400 -0.325553
-v -0.621490 0.656400 -1.850132
-v -0.621490 0.656400 1.850132
-v -0.618698 1.323225 -1.841822
-v -0.618698 1.323225 1.841822
-v -0.604900 1.471200 -1.800745
-v -0.604900 1.471200 1.800745
-v -0.603624 0.553725 -1.796946
-v -0.603624 0.553725 1.796946
-v -0.601848 2.400000 -1.156792
-v -0.601848 2.400000 1.156792
-v -0.599396 2.572800 -0.311850
-v -0.599396 2.572800 0.311850
-v -0.594614 0.046875 -1.142888
-v -0.594614 0.046875 1.142888
-v -0.590089 2.440800 1.134190
-v -0.590089 2.440800 -1.134190
-v -0.588230 1.621875 -1.751120
-v -0.588230 1.621875 1.751120
-v -0.585750 2.550000 -0.585750
-v -0.585750 2.550000 0.585750
-v -0.581929 0.463200 -1.732362
-v -0.581929 0.463200 1.732362
-v -0.576340 2.527200 -0.785325
-v -0.576340 2.527200 0.785325
-v -0.569167 1.774800 -1.694372
-v -0.569167 1.774800 1.694372
-v -0.569086 0.008400 -0.417645
-v -0.569086 0.008400 0.417645
-v -0.565664 0.018225 0.770779
-v -0.565664 0.018225 -0.770779
-v -0.558320 0.384375 -1.662080
-v -0.558320 0.384375 1.662080
-v -0.557774 2.474400 -1.072079
-v -0.557774 2.474400 1.072079
-v -0.548190 1.929525 -1.631925
-v -0.548190 1.929525 1.631925
-v -0.545131 2.572800 -0.400065
-v -0.545131 2.572800 0.400065
-v -0.534711 0.316800 -1.591798
-v -0.534711 0.316800 1.591798
-v -0.529441 0.031200 -1.017621
-v -0.529441 0.031200 1.017621
-v -0.525800 2.597400 0.000000
-v -0.525800 2.597400 0.000000
-v -0.525778 2.085600 -1.565204
-v -0.525778 2.085600 1.565204
-v -0.519028 2.597400 0.086273
-v -0.519028 2.597400 -0.086273
-v -0.513016 0.260025 -1.527214
-v -0.513016 0.260025 1.527214
-v -0.509349 2.502600 0.979002
-v -0.509349 2.502600 -0.979002
-v -0.502408 2.242575 -1.495635
-v -0.502408 2.242575 1.495635
-v -0.499384 2.597400 -0.167751
-v -0.499384 2.597400 0.167751
-v -0.499272 0.008400 -0.499272
-v -0.499272 0.008400 0.499272
-v -0.495150 0.213600 -1.474028
-v -0.495150 0.213600 1.474028
-v -0.489984 2.550000 -0.667656
-v -0.489984 2.550000 0.667656
-v -0.483027 0.177075 -1.437937
-v -0.483027 0.177075 1.437937
-v -0.478560 0.150000 1.424640
-v -0.478560 2.400000 -1.424640
-v -0.478560 0.150000 -1.424640
-v -0.478560 0.150000 -1.424640
-v -0.478560 0.150000 1.424640
-v -0.478560 2.400000 1.424640
-v -0.478256 2.572800 -0.478256
-v -0.478256 2.572800 0.478256
-v -0.477435 0.127575 1.421292
-v -0.477435 0.127575 -1.421292
-v -0.472434 0.105600 1.406405
-v -0.472434 0.105600 -1.406405
-v -0.472283 2.435437 -1.405953
-v -0.472283 2.435437 1.405953
-v -0.467878 2.597400 -0.243424
-v -0.467878 2.597400 0.243424
-v -0.465671 2.463000 -1.386270
-v -0.465671 2.463000 1.386270
-v -0.461116 0.084525 1.372712
-v -0.461116 0.084525 -1.372712
-v -0.459107 2.482687 -1.366728
-v -0.459107 2.482687 1.366728
-v -0.452973 2.494500 -1.348469
-v -0.452973 2.494500 1.348469
-v -0.449256 2.527200 -0.863501
-v -0.449256 2.527200 0.863501
-v -0.447653 2.498438 -1.332632
-v -0.447653 2.498438 1.332632
-v -0.446656 2.400000 -1.329664
-v -0.446656 2.400000 1.329664
-v -0.443529 2.494500 -1.320356
-v -0.443529 2.494500 1.320356
-v -0.442166 2.435437 -1.316296
-v -0.442166 2.435437 1.316296
-v -0.441041 0.064800 1.312948
-v -0.441041 0.064800 -1.312948
-v -0.440985 2.482687 -1.312782
-v -0.440985 2.482687 1.312782
-v -0.440935 0.018225 0.847506
-v -0.440935 0.018225 -0.847506
-v -0.440403 2.463000 -1.311049
-v -0.440403 2.463000 1.311049
-v -0.425519 2.597400 0.312283
-v -0.425519 2.597400 -0.312283
-v -0.417645 0.008400 -0.569086
-v -0.417645 0.008400 0.569086
-v -0.414752 2.400000 -1.234688
-v -0.414752 2.400000 1.234688
-v -0.409767 0.046875 1.219848
-v -0.409767 0.046875 -1.219848
-v -0.406648 2.440800 -1.210564
-v -0.406648 2.440800 1.210564
-v -0.400065 2.572800 -0.545131
-v -0.400065 2.572800 0.545131
-v -0.391200 2.625600 0.000000
-v -0.391200 2.625600 0.000000
-v -0.388275 0.002175 -0.000000
-v -0.388275 0.002175 0.000000
-v -0.386161 2.625600 -0.064188
-v -0.386161 2.625600 0.064188
-v -0.384379 2.474400 -1.144271
-v -0.384379 2.474400 1.144271
-v -0.383274 0.002175 -0.063708
-v -0.383274 0.002175 0.063708
-v -0.381942 2.550000 -0.734118
-v -0.381942 2.550000 0.734118
-v -0.373318 2.597400 -0.373318
-v -0.373318 2.597400 0.373318
-v -0.371546 2.625600 -0.124808
-v -0.371546 2.625600 0.124808
-v -0.368768 0.002175 -0.123875
-v -0.368768 0.002175 0.123875
-v -0.364854 0.031200 1.086146
-v -0.364854 0.031200 -1.086146
-v -0.358400 3.034800 0.000000
-v -0.358400 3.034800 0.000000
-v -0.358200 3.081150 0.000000
-v -0.358200 3.081150 0.000000
-v -0.353807 3.034800 -0.059016
-v -0.353807 3.034800 0.059016
-v -0.353610 3.081150 -0.058988
-v -0.353610 3.081150 0.058988
-v -0.351008 2.502600 -1.044926
-v -0.351008 2.502600 1.044926
-v -0.348105 2.625600 -0.181110
-v -0.348105 2.625600 0.181110
-v -0.345503 0.002175 -0.179756
-v -0.345503 0.002175 0.179756
-v -0.340477 3.034800 -0.114676
-v -0.340477 3.034800 0.114676
-v -0.340289 3.081150 -0.114619
-v -0.340289 3.081150 0.114619
-v -0.328160 0.900000 -1.974240
-v -0.328160 0.900000 1.974240
-v -0.328160 0.900000 1.974240
-v -0.326970 1.037175 -1.967083
-v -0.326970 1.037175 1.967083
-v -0.325863 0.771675 -1.960420
-v -0.325863 0.771675 1.960420
-v -0.325553 0.008400 -0.625735
-v -0.325553 0.008400 0.625735
-v -0.325000 2.981250 0.000000
-v -0.325000 2.981250 0.000000
-v -0.323566 1.178400 -1.946601
-v -0.323566 1.178400 1.946601
-v -0.320834 2.981250 -0.053508
-v -0.320834 2.981250 0.053508
-v -0.319628 0.656400 -1.922910
-v -0.319628 0.656400 1.922910
-v -0.319082 3.034800 -0.166306
-v -0.319082 3.034800 0.166306
-v -0.318907 3.081150 -0.166221
-v -0.318907 3.081150 0.166221
-v -0.318192 1.323225 -1.914272
-v -0.318192 1.323225 1.914272
-v -0.316590 2.625600 -0.232342
-v -0.316590 2.625600 0.232342
-v -0.314223 0.002175 -0.230604
-v -0.314223 0.002175 0.230604
-v -0.312283 2.597400 -0.425519
-v -0.312283 2.597400 0.425519
-v -0.311850 2.572800 -0.599396
-v -0.311850 2.572800 0.599396
-v -0.311096 1.471200 -1.871580
-v -0.311096 1.471200 1.871580
-v -0.310439 0.553725 -1.867631
-v -0.310439 0.553725 1.867631
-v -0.309596 2.527200 -0.921647
-v -0.309596 2.527200 0.921647
-v -0.308800 3.117600 0.000000
-v -0.308800 3.117600 0.000000
-v -0.308744 2.981250 -0.103976
-v -0.308744 2.981250 0.103976
-v -0.304843 3.117600 -0.050855
-v -0.304843 3.117600 0.050855
-v -0.303862 0.018225 0.904575
-v -0.303862 0.018225 -0.904575
-v -0.302523 1.621875 -1.820003
-v -0.302522 1.621875 1.820003
-v -0.299282 0.463200 -1.800507
-v -0.299282 0.463200 1.800507
-v -0.293360 3.117600 -0.098814
-v -0.293360 3.117600 0.098814
-v -0.292719 1.774800 -1.761022
-v -0.292719 1.774800 1.761022
-v -0.290295 3.034800 -0.213234
-v -0.290295 3.034800 0.213234
-v -0.290138 3.081150 -0.213123
-v -0.290138 3.081150 0.213123
-v -0.289340 2.981250 -0.150793
-v -0.289340 2.981250 0.150793
-v -0.287140 0.384375 -1.727460
-v -0.287140 0.384375 1.727460
-v -0.281930 1.929525 1.696119
-v -0.281930 1.929525 -1.696119
-v -0.279400 2.659200 0.000000
-v -0.277752 2.625600 -0.277752
-v -0.277752 2.625600 0.277752
-v -0.275801 2.659200 -0.045844
-v -0.275801 2.659200 0.045844
-v -0.275675 0.002175 -0.275675
-v -0.275675 0.002175 0.275675
-v -0.274998 0.316800 -1.654413
-v -0.274998 0.316800 1.654413
-v -0.274928 3.117600 -0.143301
-v -0.274928 3.117600 0.143301
-v -0.273600 2.923200 0.000000
-v -0.273600 2.923200 0.000000
-v -0.270404 2.085600 -1.626774
-v -0.270404 2.085600 1.626774
-v -0.270092 2.923200 -0.045032
-v -0.270092 2.923200 0.045032
-v -0.265363 2.659200 -0.089140
-v -0.265363 2.659200 0.089140
-v -0.263841 0.260025 1.587289
-v -0.263841 0.260025 -1.587289
-v -0.263232 2.981250 -0.193348
-v -0.263232 2.981250 0.193348
-v -0.263208 2.550000 -0.783552
-v -0.263208 2.550000 0.783552
-v -0.259910 2.923200 -0.087511
-v -0.259910 2.923200 0.087511
-v -0.258385 2.242575 -1.554467
-v -0.258385 2.242575 1.554467
-v -0.254788 3.034800 -0.254788
-v -0.254788 3.034800 0.254788
-v -0.254653 3.081150 -0.254653
-v -0.254653 3.081150 0.254653
-v -0.254652 0.213600 -1.532010
-v -0.254652 0.213600 1.532010
-v -0.250127 3.117600 -0.183734
-v -0.250127 3.117600 0.183734
-v -0.248621 2.659200 0.129351
-v -0.248621 2.659200 -0.129351
-v -0.248417 0.177075 -1.494500
-v -0.248417 0.177075 1.494500
-v -0.246120 0.150000 1.480680
-v -0.246120 2.400000 -1.480680
-v -0.246120 0.150000 -1.480680
-v -0.246120 0.150000 -1.480680
-v -0.246120 0.150000 1.480680
-v -0.246120 2.400000 1.480680
-v -0.245542 0.127575 1.477200
-v -0.245542 0.127575 -1.477200
-v -0.243569 2.923200 -0.126920
-v -0.243569 2.923200 0.126920
-v -0.243424 2.597400 0.467878
-v -0.243424 2.597400 -0.467878
-v -0.242970 0.105600 1.461727
-v -0.242970 0.105600 -1.461727
-v -0.242892 2.435437 -1.461258
-v -0.242892 2.435437 1.461258
-v -0.239491 2.463000 -1.440800
-v -0.239491 2.463000 1.440800
-v -0.237149 0.084525 1.426709
-v -0.237149 0.084525 -1.426709
-v -0.236115 2.482687 -1.420490
-v -0.236115 2.482687 1.420490
-v -0.232961 2.494500 -1.401513
-v -0.232961 2.494500 1.401513
-v -0.232342 2.625600 -0.316590
-v -0.232342 2.625600 0.316590
-v -0.231031 2.981250 -0.231031
-v -0.231031 2.981250 0.231031
-v -0.230604 0.002175 -0.314223
-v -0.230604 0.002175 0.314223
-v -0.230225 2.498438 -1.385053
-v -0.230225 2.498438 1.385053
-v -0.229712 2.400000 -1.381968
-v -0.229712 2.400000 1.381968
-v -0.228104 2.494500 -1.372294
-v -0.228104 2.494500 1.372294
-v -0.227403 2.435437 -1.368074
-v -0.227403 2.435437 1.368074
-v -0.226824 0.064800 1.364595
-v -0.226824 0.064800 -1.364595
-v -0.226795 2.482687 1.364422
-v -0.226795 2.482687 -1.364422
-v -0.226496 2.463000 -1.362620
-v -0.226496 2.463000 1.362620
-v -0.226113 2.659200 -0.165941
-v -0.226113 2.659200 0.165941
-v -0.224349 0.008400 0.667871
-v -0.224349 0.008400 -0.667871
-v -0.221585 2.923200 -0.162745
-v -0.221585 2.923200 0.162745
-v -0.219800 2.863350 0.000000
-v -0.219800 2.863350 0.000000
-v -0.219536 3.117600 -0.219536
-v -0.219536 3.117600 0.219536
-v -0.216979 2.863350 0.036157
-v -0.216979 2.863350 -0.036157
-v -0.214905 2.572800 -0.639758
-v -0.214905 2.572800 0.639758
-v -0.213304 2.400000 -1.283256
-v -0.213304 2.400000 1.283256
-v -0.213234 3.034800 -0.290295
-v -0.213234 3.034800 0.290295
-v -0.213123 3.081150 -0.290138
-v -0.213123 3.081150 0.290138
-v -0.210740 0.046875 -1.267832
-v -0.210740 0.046875 1.267832
-v -0.209136 2.440800 -1.258183
-v -0.209136 2.440800 1.258183
-v -0.208794 2.863350 0.070270
-v -0.208794 2.863350 -0.070270
-v -0.200000 2.700000 0.000000
-v -0.200000 2.700000 0.000000
-v -0.200000 2.700000 0.000000
-v -0.200000 2.700000 0.000000
-v -0.198374 2.659200 -0.198374
-v -0.198374 2.659200 0.198374
-v -0.197684 2.474400 -1.189282
-v -0.197684 2.474400 1.189282
-v -0.197424 2.700000 -0.032816
-v -0.197424 2.700000 0.032816
-v -0.197424 2.700000 0.032816
-v -0.197424 2.700000 -0.032816
-v -0.195658 2.863350 -0.101925
-v -0.195658 2.863350 0.101925
-v -0.194600 3.141450 0.000000
-v -0.194600 3.141450 0.000000
-v -0.194472 2.923200 -0.194472
-v -0.194472 2.923200 0.194472
-v -0.193348 2.981250 -0.263232
-v -0.193348 2.981250 0.263232
-v -0.192107 3.141450 -0.032048
-v -0.192107 3.141450 0.032048
-v -0.189952 2.700000 -0.063808
-v -0.189952 2.700000 0.063808
-v -0.189952 2.700000 0.063808
-v -0.189952 2.700000 -0.063808
-v -0.187642 0.031200 1.128870
-v -0.187642 0.031200 -1.128870
-v -0.184870 3.141450 -0.062272
-v -0.184870 3.141450 0.062272
-v -0.183734 3.117600 -0.250127
-v -0.183734 3.117600 0.250127
-v -0.181110 2.625600 0.348105
-v -0.181110 2.625600 -0.348105
-v -0.180521 2.502600 -1.086029
-v -0.180521 2.502600 1.086029
-v -0.179756 0.002175 -0.345503
-v -0.179756 0.002175 0.345503
-v -0.179200 2.804400 0.000000
-v -0.179200 2.804400 0.000000
-v -0.177989 2.863350 -0.130707
-v -0.177989 2.863350 0.130707
-v -0.177968 2.700000 -0.092592
-v -0.177968 2.700000 0.092592
-v -0.177968 2.700000 0.092592
-v -0.177968 2.700000 -0.092592
-v -0.176897 2.804400 0.029450
-v -0.176897 2.804400 -0.029450
-v -0.173255 3.141450 -0.090306
-v -0.173255 3.141450 0.090306
-v -0.170215 2.804400 0.057246
-v -0.170215 2.804400 -0.057246
-v -0.167751 2.597400 -0.499384
-v -0.167751 2.597400 0.499384
-v -0.167400 2.749050 0.000000
-v -0.167400 2.749050 0.000000
-v -0.166306 3.034800 -0.319082
-v -0.166306 3.034800 0.319082
-v -0.166221 3.081150 0.318907
-v -0.166221 3.081150 -0.318907
-v -0.165941 2.659200 -0.226113
-v -0.165941 2.659200 0.226113
-v -0.165245 2.749050 0.027480
-v -0.165245 2.749050 -0.027480
-v -0.162745 2.923200 -0.221585
-v -0.162745 2.923200 0.221585
-v -0.161856 2.700000 -0.118784
-v -0.161856 2.700000 0.118784
-v -0.161856 2.700000 0.118784
-v -0.161856 2.700000 -0.118784
-v -0.159496 2.804400 0.083047
-v -0.159496 2.804400 -0.083047
-v -0.159223 2.527200 -0.957901
-v -0.159223 2.527200 0.957901
-v -0.158995 2.749050 0.053428
-v -0.158995 2.749050 -0.053428
-v -0.157626 3.141450 -0.115787
-v -0.157626 3.141450 0.115787
-v -0.156274 0.018225 0.940158
-v -0.156274 0.018225 -0.940158
-v -0.156200 2.863350 -0.156200
-v -0.156200 2.863350 0.156200
-v -0.150793 2.981250 -0.289340
-v -0.150793 2.981250 0.289340
-v -0.148969 2.749050 0.077523
-v -0.148969 2.749050 -0.077523
-v -0.145078 2.804400 0.106513
-v -0.145078 2.804400 -0.106513
-v -0.143301 3.117600 -0.274928
-v -0.143301 3.117600 0.274928
-v -0.142000 2.700000 -0.142000
-v -0.142000 2.700000 0.142000
-v -0.142000 2.700000 0.142000
-v -0.142000 2.700000 -0.142000
-v -0.138348 3.141450 -0.138348
-v -0.138348 3.141450 0.138348
-v -0.135489 2.749050 0.099446
-v -0.135489 2.749050 -0.099446
-v -0.135366 2.550000 -0.814374
-v -0.135366 2.550000 0.814374
-v -0.130707 2.863350 -0.177989
-v -0.130707 2.863350 0.177989
-v -0.129351 2.659200 0.248621
-v -0.129351 2.659200 -0.248621
-v -0.127304 2.804400 0.127304
-v -0.127304 2.804400 -0.127304
-v -0.126920 2.923200 -0.243569
-v -0.126920 2.923200 0.243569
-v -0.124808 2.625600 -0.371546
-v -0.124808 2.625600 0.371546
-v -0.123875 0.002175 0.368768
-v -0.123875 0.002175 -0.368768
-v -0.118874 2.749050 0.118874
-v -0.118874 2.749050 -0.118874
-v -0.118784 2.700000 -0.161856
-v -0.118784 2.700000 0.161856
-v -0.118784 2.700000 0.161856
-v -0.118784 2.700000 -0.161856
-v -0.115787 3.141450 -0.157626
-v -0.115787 3.141450 0.157626
-v -0.115381 0.008400 0.694143
-v -0.115381 0.008400 -0.694143
-v -0.114676 3.034800 -0.340477
-v -0.114676 3.034800 0.340477
-v -0.114619 3.081150 -0.340289
-v -0.114619 3.081150 0.340289
-v -0.110524 2.572800 -0.664924
-v -0.110524 2.572800 0.664924
-v -0.106513 2.804400 -0.145078
-v -0.106513 2.804400 0.145078
-v -0.103976 2.981250 -0.308744
-v -0.103976 2.981250 0.308744
-v -0.101925 2.863350 -0.195658
-v -0.101925 2.863350 0.195658
-v -0.099446 2.749050 0.135489
-v -0.099446 2.749050 -0.135489
-v -0.098814 3.117600 -0.293360
-v -0.098814 3.117600 0.293360
-v -0.092592 2.700000 -0.177968
-v -0.092592 2.700000 0.177968
-v -0.092592 2.700000 -0.177968
-v -0.092592 2.700000 0.177968
-v -0.090306 3.141450 -0.173255
-v -0.090306 3.141450 0.173255
-v -0.089140 2.659200 -0.265363
-v -0.089140 2.659200 0.265363
-v -0.087511 2.923200 -0.259910
-v -0.087511 2.923200 0.259910
-v -0.086273 2.597400 -0.519028
-v -0.086273 2.597400 0.519028
-v -0.083047 2.804400 -0.159496
-v -0.083047 2.804400 0.159496
-v -0.077523 2.749050 -0.148969
-v -0.077523 2.749050 0.148969
-v -0.070270 2.863350 -0.208794
-v -0.070270 2.863350 0.208794
-v -0.064188 2.625600 -0.386161
-v -0.064188 2.625600 0.386161
-v -0.063808 2.700000 -0.189952
-v -0.063808 2.700000 0.189952
-v -0.063808 2.700000 -0.189952
-v -0.063808 2.700000 0.189952
-v -0.063708 0.002175 0.383274
-v -0.063708 0.002175 -0.383274
-v -0.062272 3.141450 -0.184870
-v -0.062272 3.141450 0.184870
-v -0.059016 3.034800 -0.353807
-v -0.059016 3.034800 0.353807
-v -0.058988 3.081150 -0.353610
-v -0.058988 3.081150 0.353610
-v -0.057246 2.804400 -0.170215
-v -0.057246 2.804400 0.170215
-v -0.053508 2.981250 -0.320834
-v -0.053508 2.981250 0.320834
-v -0.053428 2.749050 -0.158995
-v -0.053428 2.749050 0.158995
-v -0.050855 3.117600 -0.304843
-v -0.050855 3.117600 0.304843
-v -0.045844 2.659200 -0.275801
-v -0.045844 2.659200 0.275801
-v -0.045032 2.923200 -0.270092
-v -0.045032 2.923200 0.270092
-v -0.036157 2.863350 -0.216979
-v -0.036157 2.863350 0.216979
-v -0.032816 2.700000 -0.197424
-v -0.032816 2.700000 0.197424
-v -0.032816 2.700000 -0.197424
-v -0.032816 2.700000 0.197424
-v -0.032048 3.141450 -0.192107
-v -0.032048 3.141450 0.192107
-v -0.029450 2.804400 -0.176897
-v -0.029450 2.804400 0.176897
-v -0.027480 2.749050 -0.165245
-v -0.027480 2.749050 0.165245
-v -0.000000 0.260025 1.608000
-v -0.000000 1.929525 1.718250
-v -0.000000 2.085600 -1.648000
-v -0.000000 0.656400 -1.948000
-v -0.000000 0.771675 -1.986000
-v -0.000000 2.482687 1.382225
-v -0.000000 2.700000 -0.200000
-v -0.000000 0.127575 1.496475
-v -0.000000 2.474400 -1.204800
-v -0.000000 2.749050 -0.167400
-v -0.000000 0.018225 0.952425
-v -0.000000 0.046875 -1.284375
-v -0.000000 0.064800 1.382400
-v -0.000000 0.384375 1.750000
-v -0.000000 0.463200 1.824000
-v -0.000000 0.553725 -1.892000
-v -0.000000 1.037175 1.992750
-v -0.000000 1.178400 1.972000
-v -0.000000 1.323225 -1.939250
-v -0.000000 1.621875 -1.843750
-v -0.000000 1.774800 1.784000
-v -0.000000 2.400000 -1.300000
-v -0.000000 2.435437 -1.480325
-v -0.000000 2.435437 -1.385925
-v -0.000000 2.463000 -1.459600
-v -0.000000 2.463000 -1.380400
-v -0.000000 2.494500 -1.390200
-v -0.000000 2.502600 -1.100200
-v -0.000000 2.804400 -0.179200
-v -0.000000 2.863350 -0.219800
-v -0.000000 2.572800 -0.673600
-v -0.000000 0.105600 1.480800
-v -0.000000 0.177075 -1.514000
-v -0.000000 2.494500 -1.419800
-v -0.000000 2.527200 -0.970400
-v -0.000000 2.923200 -0.273600
-v -0.000000 3.117600 -0.308800
-v -0.000000 2.597400 -0.525800
-v -0.000000 2.700000 -0.200000
-v -0.000000 2.981250 -0.325000
-v -0.000000 3.141450 -0.194600
-v -0.000000 0.002175 0.388275
-v -0.000000 3.081150 -0.358200
-v 0.000000 0.000000 0.000000
-v 0.000000 0.002175 -0.388275
-v 0.000000 0.002175 0.388275
-v 0.000000 0.008400 -0.703200
-v 0.000000 0.008400 0.703200
-v 0.000000 0.018225 -0.952425
-v 0.000000 0.018225 0.952425
-v 0.000000 0.031200 -1.143600
-v 0.000000 0.031200 -1.143600
-v 0.000000 0.031200 1.143600
-v 0.000000 0.031200 1.143600
-v 0.000000 0.046875 -1.284375
-v 0.000000 0.046875 1.284375
-v 0.000000 0.064800 -1.382400
-v 0.000000 0.064800 1.382400
-v 0.000000 0.084525 -1.445325
-v 0.000000 0.084525 -1.445325
-v 0.000000 0.084525 1.445325
-v 0.000000 0.084525 1.445325
-v 0.000000 0.105600 -1.480800
-v 0.000000 0.105600 1.480800
-v 0.000000 0.127575 -1.496475
-v 0.000000 0.127575 1.496475
-v 0.000000 0.150000 -1.500000
-v 0.000000 0.150000 -1.500000
-v 0.000000 0.150000 1.500000
-v 0.000000 0.150000 1.500000
-v 0.000000 0.177075 -1.514000
-v 0.000000 0.177075 1.514000
-v 0.000000 0.213600 -1.552000
-v 0.000000 0.213600 -1.552000
-v 0.000000 0.213600 1.552000
-v 0.000000 0.213600 1.552000
-v 0.000000 0.260025 -1.608000
-v 0.000000 0.260025 1.608000
-v 0.000000 0.316800 -1.676000
-v 0.000000 0.316800 -1.676000
-v 0.000000 0.316800 1.676000
-v 0.000000 0.316800 1.676000
-v 0.000000 0.384375 -1.750000
-v 0.000000 0.384375 1.750000
-v 0.000000 0.463200 -1.824000
-v 0.000000 0.463200 1.824000
-v 0.000000 0.553725 -1.892000
-v 0.000000 0.553725 1.892000
-v 0.000000 0.656400 -1.948000
-v 0.000000 0.656400 1.948000
-v 0.000000 0.771675 -1.986000
-v 0.000000 0.771675 1.986000
-v 0.000000 0.900000 -2.000000
-v 0.000000 0.900000 -2.000000
-v 0.000000 0.900000 2.000000
-v 0.000000 0.900000 2.000000
-v 0.000000 1.037175 -1.992750
-v 0.000000 1.037175 1.992750
-v 0.000000 1.178400 -1.972000
-v 0.000000 1.178400 1.972000
-v 0.000000 1.323225 -1.939250
-v 0.000000 1.323225 1.939250
-v 0.000000 1.471200 -1.896000
-v 0.000000 1.471200 -1.896000
-v 0.000000 1.471200 1.896000
-v 0.000000 1.471200 1.896000
-v 0.000000 1.621875 -1.843750
-v 0.000000 1.621875 1.843750
-v 0.000000 1.774800 -1.784000
-v 0.000000 1.774800 1.784000
-v 0.000000 1.929525 -1.718250
-v 0.000000 1.929525 1.718250
-v 0.000000 2.085600 -1.648000
-v 0.000000 2.085600 1.648000
-v 0.000000 2.242575 -1.574750
-v 0.000000 2.242575 -1.574750
-v 0.000000 2.242575 1.574750
-v 0.000000 2.242575 1.574750
-v 0.000000 2.400000 -1.500000
-v 0.000000 2.400000 -1.500000
-v 0.000000 2.400000 -1.400000
-v 0.000000 2.400000 -1.400000
-v 0.000000 2.400000 -1.300000
-v 0.000000 2.400000 1.300000
-v 0.000000 2.400000 1.400000
-v 0.000000 2.400000 1.400000
-v 0.000000 2.400000 1.500000
-v 0.000000 2.400000 1.500000
-v 0.000000 2.435437 -1.480325
-v 0.000000 2.435437 -1.385925
-v 0.000000 2.435437 1.385925
-v 0.000000 2.435437 1.480325
-v 0.000000 2.440800 -1.274600
-v 0.000000 2.440800 -1.274600
-v 0.000000 2.440800 1.274600
-v 0.000000 2.440800 1.274600
-v 0.000000 2.463000 -1.459600
-v 0.000000 2.463000 -1.380400
-v 0.000000 2.463000 1.380400
-v 0.000000 2.463000 1.459600
-v 0.000000 2.474400 -1.204800
-v 0.000000 2.474400 1.204800
-v 0.000000 2.482687 -1.439025
-v 0.000000 2.482687 -1.382225
-v 0.000000 2.482687 1.382225
-v 0.000000 2.482687 1.439025
-v 0.000000 2.494500 -1.419800
-v 0.000000 2.494500 -1.390200
-v 0.000000 2.494500 1.390200
-v 0.000000 2.494500 1.419800
-v 0.000000 2.498438 -1.403125
-v 0.000000 2.498438 -1.403125
-v 0.000000 2.498438 1.403125
-v 0.000000 2.498438 1.403125
-v 0.000000 2.502600 -1.100200
-v 0.000000 2.502600 1.100200
-v 0.000000 2.527200 -0.970400
-v 0.000000 2.527200 0.970400
-v 0.000000 2.550000 -0.825000
-v 0.000000 2.550000 -0.825000
-v 0.000000 2.550000 0.825000
-v 0.000000 2.550000 0.825000
-v 0.000000 2.572800 -0.673600
-v 0.000000 2.572800 0.673600
-v 0.000000 2.597400 -0.525800
-v 0.000000 2.597400 0.525800
-v 0.000000 2.625600 -0.391200
-v 0.000000 2.625600 -0.391200
-v 0.000000 2.625600 0.391200
-v 0.000000 2.625600 0.391200
-v 0.000000 2.659200 -0.279400
-v 0.000000 2.659200 0.279400
-v 0.000000 2.700000 -0.200000
-v 0.000000 2.700000 -0.200000
-v 0.000000 2.700000 0.200000
-v 0.000000 2.700000 0.200000
-v 0.000000 2.749050 -0.167400
-v 0.000000 2.749050 0.167400
-v 0.000000 2.804400 -0.179200
-v 0.000000 2.804400 0.179200
-v 0.000000 2.863350 -0.219800
-v 0.000000 2.863350 0.219800
-v 0.000000 2.923200 -0.273600
-v 0.000000 2.923200 0.273600
-v 0.000000 2.981250 -0.325000
-v 0.000000 2.981250 0.325000
-v 0.000000 3.034800 -0.358400
-v 0.000000 3.034800 -0.358400
-v 0.000000 3.034800 0.358400
-v 0.000000 3.034800 0.358400
-v 0.000000 3.081150 -0.358200
-v 0.000000 3.081150 0.358200
-v 0.000000 3.117600 -0.308800
-v 0.000000 3.117600 0.308800
-v 0.000000 3.141450 -0.194600
-v 0.000000 3.141450 0.194600
-v 0.000000 3.150000 0.000000
-v 0.000000 0.002175 -0.388275
-v 0.000000 3.081150 0.358200
-v 0.000000 2.597400 0.525800
-v 0.000000 2.700000 0.200000
-v 0.000000 2.981250 0.325000
-v 0.000000 3.141450 0.194600
-v 0.000000 3.117600 0.308800
-v 0.000000 0.105600 -1.480800
-v 0.000000 0.177075 1.514000
-v 0.000000 2.494500 1.419800
-v 0.000000 2.527200 0.970400
-v 0.000000 2.923200 0.273600
-v 0.000000 2.572800 0.673600
-v 0.000000 2.863350 0.219800
-v 0.000000 0.018225 -0.952425
-v 0.000000 0.046875 1.284375
-v 0.000000 0.064800 -1.382400
-v 0.000000 0.384375 -1.750000
-v 0.000000 0.463200 -1.824000
-v 0.000000 0.553725 1.892000
-v 0.000000 1.037175 -1.992750
-v 0.000000 1.178400 -1.972000
-v 0.000000 1.323225 1.939250
-v 0.000000 1.621875 1.843750
-v 0.000000 1.774800 -1.784000
-v 0.000000 2.400000 1.300000
-v 0.000000 2.435437 1.385925
-v 0.000000 2.435437 1.480325
-v 0.000000 2.463000 1.380400
-v 0.000000 2.463000 1.459600
-v 0.000000 2.494500 1.390200
-v 0.000000 2.502600 1.100200
-v 0.000000 2.804400 0.179200
-v 0.000000 2.749050 0.167400
-v 0.000000 0.127575 -1.496475
-v 0.000000 2.474400 1.204800
-v 0.000000 0.656400 1.948000
-v 0.000000 0.771675 1.986000
-v 0.000000 2.482687 -1.382225
-v 0.000000 2.700000 0.200000
-v 0.000000 0.260025 -1.608000
-v 0.000000 1.929525 -1.718250
-v 0.000000 2.085600 1.648000
-v 0.027480 2.749050 -0.165245
-v 0.027480 2.749050 0.165245
-v 0.029450 2.804400 -0.176897
-v 0.029450 2.804400 0.176897
-v 0.032048 3.141450 -0.192107
-v 0.032048 3.141450 0.192107
-v 0.032816 2.700000 -0.197424
-v 0.032816 2.700000 0.197424
-v 0.032816 2.700000 -0.197424
-v 0.032816 2.700000 0.197424
-v 0.036157 2.863350 -0.216979
-v 0.036157 2.863350 0.216979
-v 0.045032 2.923200 -0.270092
-v 0.045032 2.923200 0.270092
-v 0.045844 2.659200 -0.275801
-v 0.045844 2.659200 0.275801
-v 0.050855 3.117600 -0.304843
-v 0.050855 3.117600 0.304843
-v 0.053428 2.749050 -0.158995
-v 0.053428 2.749050 0.158995
-v 0.053508 2.981250 -0.320834
-v 0.053508 2.981250 0.320834
-v 0.057246 2.804400 -0.170215
-v 0.057246 2.804400 0.170215
-v 0.058988 3.081150 -0.353610
-v 0.058988 3.081150 0.353610
-v 0.059016 3.034800 -0.353807
-v 0.059016 3.034800 0.353807
-v 0.062272 3.141450 -0.184870
-v 0.062272 3.141450 0.184870
-v 0.063708 0.002175 0.383274
-v 0.063708 0.002175 -0.383274
-v 0.063808 2.700000 -0.189952
-v 0.063808 2.700000 0.189952
-v 0.063808 2.700000 -0.189952
-v 0.063808 2.700000 0.189952
-v 0.064188 2.625600 -0.386161
-v 0.064188 2.625600 0.386161
-v 0.070270 2.863350 -0.208794
-v 0.070270 2.863350 0.208794
-v 0.077523 2.749050 -0.148969
-v 0.077523 2.749050 0.148969
-v 0.083047 2.804400 -0.159496
-v 0.083047 2.804400 0.159496
-v 0.086273 2.597400 -0.519028
-v 0.086273 2.597400 0.519028
-v 0.087511 2.923200 -0.259910
-v 0.087511 2.923200 0.259910
-v 0.089140 2.659200 -0.265363
-v 0.089140 2.659200 0.265363
-v 0.090306 3.141450 -0.173255
-v 0.090306 3.141450 0.173255
-v 0.092592 2.700000 -0.177968
-v 0.092592 2.700000 0.177968
-v 0.092592 2.700000 -0.177968
-v 0.092592 2.700000 0.177968
-v 0.098814 3.117600 -0.293360
-v 0.098814 3.117600 0.293360
-v 0.099446 2.749050 0.135489
-v 0.099446 2.749050 -0.135489
-v 0.101925 2.863350 -0.195658
-v 0.101925 2.863350 0.195658
-v 0.103976 2.981250 -0.308744
-v 0.103976 2.981250 0.308744
-v 0.106513 2.804400 -0.145078
-v 0.106513 2.804400 0.145078
-v 0.110524 2.572800 -0.664924
-v 0.110524 2.572800 0.664924
-v 0.114619 3.081150 -0.340289
-v 0.114619 3.081150 0.340289
-v 0.114676 3.034800 -0.340477
-v 0.114676 3.034800 0.340477
-v 0.115381 0.008400 0.694143
-v 0.115381 0.008400 -0.694143
-v 0.115787 3.141450 -0.157626
-v 0.115787 3.141450 0.157626
-v 0.118784 2.700000 0.161856
-v 0.118784 2.700000 -0.161856
-v 0.118784 2.700000 -0.161856
-v 0.118784 2.700000 0.161856
-v 0.118874 2.749050 0.118874
-v 0.118874 2.749050 -0.118874
-v 0.123875 0.002175 0.368768
-v 0.123875 0.002175 -0.368768
-v 0.124808 2.625600 -0.371546
-v 0.124808 2.625600 0.371546
-v 0.126920 2.923200 -0.243569
-v 0.126920 2.923200 0.243569
-v 0.127304 2.804400 0.127304
-v 0.127304 2.804400 -0.127304
-v 0.129351 2.659200 0.248621
-v 0.129351 2.659200 -0.248621
-v 0.130707 2.863350 -0.177989
-v 0.130707 2.863350 0.177989
-v 0.135366 2.550000 -0.814374
-v 0.135366 2.550000 0.814374
-v 0.135489 2.749050 0.099446
-v 0.135489 2.749050 -0.099446
-v 0.138348 3.141450 -0.138348
-v 0.138348 3.141450 0.138348
-v 0.142000 2.700000 0.142000
-v 0.142000 2.700000 -0.142000
-v 0.142000 2.700000 -0.142000
-v 0.142000 2.700000 0.142000
-v 0.143301 3.117600 -0.274928
-v 0.143301 3.117600 0.274928
-v 0.145078 2.804400 0.106513
-v 0.145078 2.804400 -0.106513
-v 0.148969 2.749050 0.077523
-v 0.148969 2.749050 -0.077523
-v 0.150793 2.981250 -0.289340
-v 0.150793 2.981250 0.289340
-v 0.156200 2.863350 -0.156200
-v 0.156200 2.863350 0.156200
-v 0.156274 0.018225 0.940158
-v 0.156274 0.018225 -0.940158
-v 0.157626 3.141450 -0.115787
-v 0.157626 3.141450 0.115787
-v 0.158995 2.749050 0.053428
-v 0.158995 2.749050 -0.053428
-v 0.159223 2.527200 -0.957901
-v 0.159223 2.527200 0.957901
-v 0.159496 2.804400 0.083047
-v 0.159496 2.804400 -0.083047
-v 0.161856 2.700000 0.118784
-v 0.161856 2.700000 -0.118784
-v 0.161856 2.700000 -0.118784
-v 0.161856 2.700000 0.118784
-v 0.162745 2.923200 -0.221585
-v 0.162745 2.923200 0.221585
-v 0.165245 2.749050 0.027480
-v 0.165245 2.749050 -0.027480
-v 0.165941 2.659200 -0.226113
-v 0.165941 2.659200 0.226113
-v 0.166221 3.081150 0.318907
-v 0.166221 3.081150 -0.318907
-v 0.166306 3.034800 -0.319082
-v 0.166306 3.034800 0.319082
-v 0.167400 2.749050 -0.000000
-v 0.167400 2.749050 0.000000
-v 0.167751 2.597400 -0.499384
-v 0.167751 2.597400 0.499384
-v 0.170215 2.804400 0.057246
-v 0.170215 2.804400 -0.057246
-v 0.173255 3.141450 -0.090306
-v 0.173255 3.141450 0.090306
-v 0.176897 2.804400 0.029450
-v 0.176897 2.804400 -0.029450
-v 0.177968 2.700000 0.092592
-v 0.177968 2.700000 -0.092592
-v 0.177968 2.700000 -0.092592
-v 0.177968 2.700000 0.092592
-v 0.177989 2.863350 -0.130707
-v 0.177989 2.863350 0.130707
-v 0.179200 2.804400 -0.000000
-v 0.179200 2.804400 0.000000
-v 0.179756 0.002175 -0.345503
-v 0.179756 0.002175 0.345503
-v 0.180521 2.502600 -1.086029
-v 0.180521 2.502600 1.086029
-v 0.181110 2.625600 0.348105
-v 0.181110 2.625600 -0.348105
-v 0.183734 3.117600 -0.250127
-v 0.183734 3.117600 0.250127
-v 0.184870 3.141450 -0.062272
-v 0.184870 3.141450 0.062272
-v 0.187642 0.031200 1.128870
-v 0.187642 0.031200 -1.128870
-v 0.189952 2.700000 0.063808
-v 0.189952 2.700000 -0.063808
-v 0.189952 2.700000 -0.063808
-v 0.189952 2.700000 0.063808
-v 0.192107 3.141450 -0.032048
-v 0.192107 3.141450 0.032048
-v 0.193348 2.981250 -0.263232
-v 0.193348 2.981250 0.263232
-v 0.194472 2.923200 -0.194472
-v 0.194472 2.923200 0.194472
-v 0.194600 3.141450 0.000000
-v 0.194600 3.141450 -0.000000
-v 0.195658 2.863350 -0.101925
-v 0.195658 2.863350 0.101925
-v 0.197424 2.700000 0.032816
-v 0.197424 2.700000 -0.032816
-v 0.197424 2.700000 -0.032816
-v 0.197424 2.700000 0.032816
-v 0.197684 2.474400 -1.189282
-v 0.197684 2.474400 1.189282
-v 0.198374 2.659200 -0.198374
-v 0.198374 2.659200 0.198374
-v 0.200000 2.700000 -0.000000
-v 0.200000 2.700000 0.000000
-v 0.200000 2.700000 0.000000
-v 0.200000 2.700000 -0.000000
-v 0.208794 2.863350 0.070270
-v 0.208794 2.863350 -0.070270
-v 0.209136 2.440800 -1.258183
-v 0.209136 2.440800 1.258183
-v 0.210740 0.046875 -1.267832
-v 0.210740 0.046875 1.267832
-v 0.213123 3.081150 -0.290138
-v 0.213123 3.081150 0.290138
-v 0.213234 3.034800 -0.290295
-v 0.213234 3.034800 0.290295
-v 0.213304 2.400000 -1.283256
-v 0.213304 2.400000 1.283256
-v 0.214905 2.572800 -0.639758
-v 0.214905 2.572800 0.639758
-v 0.216979 2.863350 0.036157
-v 0.216979 2.863350 -0.036157
-v 0.219536 3.117600 -0.219536
-v 0.219536 3.117600 0.219536
-v 0.219800 2.863350 -0.000000
-v 0.219800 2.863350 0.000000
-v 0.221585 2.923200 -0.162745
-v 0.221585 2.923200 0.162745
-v 0.224349 0.008400 0.667871
-v 0.224349 0.008400 -0.667871
-v 0.226113 2.659200 -0.165941
-v 0.226113 2.659200 0.165941
-v 0.226496 2.463000 -1.362620
-v 0.226496 2.463000 1.362620
-v 0.226795 2.482687 1.364422
-v 0.226795 2.482687 -1.364422
-v 0.226824 0.064800 1.364595
-v 0.226824 0.064800 -1.364595
-v 0.227403 2.435437 -1.368074
-v 0.227403 2.435437 1.368074
-v 0.228104 2.494500 -1.372294
-v 0.228104 2.494500 1.372294
-v 0.229712 2.400000 -1.381968
-v 0.229712 2.400000 1.381968
-v 0.230225 2.498438 -1.385053
-v 0.230225 2.498438 1.385053
-v 0.230604 0.002175 -0.314223
-v 0.230604 0.002175 0.314223
-v 0.231031 2.981250 -0.231031
-v 0.231031 2.981250 0.231031
-v 0.232342 2.625600 -0.316590
-v 0.232342 2.625600 0.316590
-v 0.232961 2.494500 -1.401513
-v 0.232961 2.494500 1.401513
-v 0.236115 2.482687 -1.420490
-v 0.236115 2.482687 1.420490
-v 0.237149 0.084525 1.426709
-v 0.237149 0.084525 -1.426709
-v 0.239491 2.463000 -1.440800
-v 0.239491 2.463000 1.440800
-v 0.242892 2.435437 -1.461258
-v 0.242892 2.435437 1.461258
-v 0.242970 0.105600 1.461727
-v 0.242970 0.105600 -1.461727
-v 0.243424 2.597400 0.467878
-v 0.243424 2.597400 -0.467878
-v 0.243569 2.923200 -0.126920
-v 0.243569 2.923200 0.126920
-v 0.245542 0.127575 1.477200
-v 0.245542 0.127575 -1.477200
-v 0.246120 0.150000 -1.480680
-v 0.246120 2.400000 -1.480680
-v 0.246120 0.150000 1.480680
-v 0.246120 0.150000 1.480680
-v 0.246120 2.400000 1.480680
-v 0.246120 0.150000 -1.480680
-v 0.248417 0.177075 -1.494500
-v 0.248417 0.177075 1.494500
-v 0.248621 2.659200 0.129351
-v 0.248621 2.659200 -0.129351
-v 0.250127 3.117600 -0.183734
-v 0.250127 3.117600 0.183734
-v 0.254652 0.213600 -1.532010
-v 0.254652 0.213600 1.532010
-v 0.254653 3.081150 -0.254653
-v 0.254653 3.081150 0.254653
-v 0.254788 3.034800 -0.254788
-v 0.254788 3.034800 0.254788
-v 0.258385 2.242575 -1.554467
-v 0.258385 2.242575 1.554467
-v 0.259910 2.923200 -0.087511
-v 0.259910 2.923200 0.087511
-v 0.263208 2.550000 -0.783552
-v 0.263208 2.550000 0.783552
-v 0.263232 2.981250 -0.193348
-v 0.263232 2.981250 0.193348
-v 0.263841 0.260025 1.587289
-v 0.263841 0.260025 -1.587289
-v 0.265363 2.659200 -0.089140
-v 0.265363 2.659200 0.089140
-v 0.270092 2.923200 -0.045032
-v 0.270092 2.923200 0.045032
-v 0.270404 2.085600 -1.626774
-v 0.270404 2.085600 1.626774
-v 0.273600 2.923200 -0.000000
-v 0.273600 2.923200 0.000000
-v 0.274928 3.117600 -0.143301
-v 0.274928 3.117600 0.143301
-v 0.274998 0.316800 -1.654413
-v 0.274998 0.316800 1.654413
-v 0.275675 0.002175 -0.275675
-v 0.275675 0.002175 0.275675
-v 0.275801 2.659200 -0.045844
-v 0.275801 2.659200 0.045844
-v 0.277752 2.625600 -0.277752
-v 0.277752 2.625600 0.277752
-v 0.279400 2.659200 0.000000
-v 0.281930 1.929525 1.696119
-v 0.281930 1.929525 -1.696119
-v 0.287140 0.384375 -1.727460
-v 0.287140 0.384375 1.727460
-v 0.289340 2.981250 -0.150793
-v 0.289340 2.981250 0.150793
-v 0.290138 3.081150 -0.213123
-v 0.290138 3.081150 0.213123
-v 0.290295 3.034800 -0.213234
-v 0.290295 3.034800 0.213234
-v 0.292719 1.774800 -1.761022
-v 0.292719 1.774800 1.761022
-v 0.293360 3.117600 -0.098814
-v 0.293360 3.117600 0.098814
-v 0.299282 0.463200 -1.800507
-v 0.299282 0.463200 1.800507
-v 0.302522 1.621875 -1.820003
-v 0.302523 1.621875 1.820003
-v 0.303862 0.018225 0.904575
-v 0.303862 0.018225 -0.904575
-v 0.304843 3.117600 -0.050855
-v 0.304843 3.117600 0.050855
-v 0.308744 2.981250 -0.103976
-v 0.308744 2.981250 0.103976
-v 0.308800 3.117600 0.000000
-v 0.308800 3.117600 -0.000000
-v 0.309596 2.527200 -0.921647
-v 0.309596 2.527200 0.921647
-v 0.310439 0.553725 -1.867631
-v 0.310439 0.553725 1.867631
-v 0.311096 1.471200 -1.871580
-v 0.311096 1.471200 1.871580
-v 0.311850 2.572800 -0.599396
-v 0.311850 2.572800 0.599396
-v 0.312283 2.597400 -0.425519
-v 0.312283 2.597400 0.425519
-v 0.314223 0.002175 -0.230604
-v 0.314223 0.002175 0.230604
-v 0.316590 2.625600 -0.232342
-v 0.316590 2.625600 0.232342
-v 0.318192 1.323225 -1.914272
-v 0.318192 1.323225 1.914272
-v 0.318907 3.081150 -0.166221
-v 0.318907 3.081150 0.166221
-v 0.319082 3.034800 -0.166306
-v 0.319082 3.034800 0.166306
-v 0.319628 0.656400 -1.922910
-v 0.319628 0.656400 1.922910
-v 0.320834 2.981250 -0.053508
-v 0.320834 2.981250 0.053508
-v 0.323566 1.178400 -1.946601
-v 0.323566 1.178400 1.946601
-v 0.325000 2.981250 0.000000
-v 0.325000 2.981250 -0.000000
-v 0.325553 0.008400 -0.625735
-v 0.325553 0.008400 0.625735
-v 0.325863 0.771675 -1.960420
-v 0.325863 0.771675 1.960420
-v 0.326970 1.037175 -1.967083
-v 0.326970 1.037175 1.967083
-v 0.328160 0.900000 -1.974240
-v 0.328160 0.900000 -1.974240
-v 0.328160 0.900000 1.974240
-v 0.340289 3.081150 -0.114619
-v 0.340289 3.081150 0.114619
-v 0.340477 3.034800 -0.114676
-v 0.340477 3.034800 0.114676
-v 0.345503 0.002175 -0.179756
-v 0.345503 0.002175 0.179756
-v 0.348105 2.625600 -0.181110
-v 0.348105 2.625600 0.181110
-v 0.351008 2.502600 -1.044926
-v 0.351008 2.502600 1.044926
-v 0.353610 3.081150 -0.058988
-v 0.353610 3.081150 0.058988
-v 0.353807 3.034800 -0.059016
-v 0.353807 3.034800 0.059016
-v 0.358200 3.081150 -0.000000
-v 0.358200 3.081150 0.000000
-v 0.358400 3.034800 0.000000
-v 0.358400 3.034800 0.000000
-v 0.364854 0.031200 1.086146
-v 0.364854 0.031200 -1.086146
-v 0.368768 0.002175 -0.123875
-v 0.368768 0.002175 0.123875
-v 0.371546 2.625600 -0.124808
-v 0.371546 2.625600 0.124808
-v 0.373318 2.597400 -0.373318
-v 0.373318 2.597400 0.373318
-v 0.381942 2.550000 -0.734118
-v 0.381942 2.550000 0.734118
-v 0.383274 0.002175 -0.063708
-v 0.383274 0.002175 0.063708
-v 0.384379 2.474400 -1.144271
-v 0.384379 2.474400 1.144271
-v 0.386161 2.625600 -0.064188
-v 0.386161 2.625600 0.064188
-v 0.388275 0.002175 0.000000
-v 0.388275 0.002175 0.000000
-v 0.391200 2.625600 0.000000
-v 0.391200 2.625600 0.000000
-v 0.400065 2.572800 -0.545131
-v 0.400065 2.572800 0.545131
-v 0.406648 2.440800 -1.210564
-v 0.406648 2.440800 1.210564
-v 0.409767 0.046875 1.219848
-v 0.409767 0.046875 -1.219848
-v 0.414752 2.400000 -1.234688
-v 0.414752 2.400000 1.234688
-v 0.417645 0.008400 -0.569086
-v 0.417645 0.008400 0.569086
-v 0.425519 2.597400 0.312283
-v 0.425519 2.597400 -0.312283
-v 0.440403 2.463000 -1.311049
-v 0.440403 2.463000 1.311049
-v 0.440935 0.018225 0.847506
-v 0.440935 0.018225 -0.847506
-v 0.440985 2.482687 -1.312782
-v 0.440985 2.482687 1.312782
-v 0.441041 0.064800 1.312948
-v 0.441041 0.064800 -1.312948
-v 0.442166 2.435437 -1.316296
-v 0.442166 2.435437 1.316296
-v 0.443529 2.494500 -1.320356
-v 0.443529 2.494500 1.320356
-v 0.446656 2.400000 -1.329664
-v 0.446656 2.400000 1.329664
-v 0.447653 2.498438 -1.332632
-v 0.447653 2.498438 1.332632
-v 0.449256 2.527200 -0.863501
-v 0.449256 2.527200 0.863501
-v 0.452973 2.494500 -1.348469
-v 0.452973 2.494500 1.348469
-v 0.459107 2.482687 -1.366728
-v 0.459107 2.482687 1.366728
-v 0.461116 0.084525 1.372712
-v 0.461116 0.084525 -1.372712
-v 0.465671 2.463000 -1.386270
-v 0.465671 2.463000 1.386270
-v 0.467878 2.597400 -0.243424
-v 0.467878 2.597400 0.243424
-v 0.472283 2.435437 -1.405953
-v 0.472283 2.435437 1.405953
-v 0.472434 0.105600 1.406405
-v 0.472434 0.105600 -1.406405
-v 0.477435 0.127575 1.421292
-v 0.477435 0.127575 -1.421292
-v 0.478256 2.572800 -0.478256
-v 0.478256 2.572800 0.478256
-v 0.478560 0.150000 -1.424640
-v 0.478560 2.400000 -1.424640
-v 0.478560 0.150000 1.424640
-v 0.478560 0.150000 1.424640
-v 0.478560 0.150000 -1.424640
-v 0.478560 2.400000 1.424640
-v 0.483027 0.177075 -1.437937
-v 0.483027 0.177075 1.437937
-v 0.489984 2.550000 -0.667656
-v 0.489984 2.550000 0.667656
-v 0.495150 0.213600 -1.474028
-v 0.495150 0.213600 1.474028
-v 0.499272 0.008400 -0.499272
-v 0.499272 0.008400 0.499272
-v 0.499384 2.597400 -0.167751
-v 0.499384 2.597400 0.167751
-v 0.502408 2.242575 -1.495635
-v 0.502408 2.242575 1.495635
-v 0.509349 2.502600 0.979002
-v 0.509349 2.502600 -0.979002
-v 0.513016 0.260025 -1.527214
-v 0.513016 0.260025 1.527214
-v 0.519028 2.597400 0.086273
-v 0.519028 2.597400 -0.086273
-v 0.525778 2.085600 -1.565204
-v 0.525778 2.085600 1.565204
-v 0.525800 2.597400 -0.000000
-v 0.525800 2.597400 0.000000
-v 0.529441 0.031200 -1.017621
-v 0.529441 0.031200 1.017621
-v 0.534711 0.316800 -1.591798
-v 0.534711 0.316800 1.591798
-v 0.545131 2.572800 -0.400065
-v 0.545131 2.572800 0.400065
-v 0.548190 1.929525 -1.631925
-v 0.548190 1.929525 1.631925
-v 0.557774 2.474400 -1.072079
-v 0.557774 2.474400 1.072079
-v 0.558320 0.384375 -1.662080
-v 0.558320 0.384375 1.662080
-v 0.565664 0.018225 0.770779
-v 0.565664 0.018225 -0.770779
-v 0.569086 0.008400 -0.417645
-v 0.569086 0.008400 0.417645
-v 0.569167 1.774800 -1.694372
-v 0.569167 1.774800 1.694372
-v 0.576340 2.527200 -0.785325
-v 0.576340 2.527200 0.785325
-v 0.581929 0.463200 -1.732362
-v 0.581929 0.463200 1.732362
-v 0.585750 2.550000 -0.585750
-v 0.585750 2.550000 0.585750
-v 0.588230 1.621875 -1.751120
-v 0.588230 1.621875 1.751120
-v 0.590089 2.440800 1.134190
-v 0.590089 2.440800 -1.134190
-v 0.594614 0.046875 -1.142888
-v 0.594614 0.046875 1.142888
-v 0.599396 2.572800 -0.311850
-v 0.599396 2.572800 0.311850
-v 0.601848 2.400000 -1.156792
-v 0.601848 2.400000 1.156792
-v 0.603624 0.553725 -1.796946
-v 0.603624 0.553725 1.796946
-v 0.604900 1.471200 -1.800745
-v 0.604900 1.471200 1.800745
-v 0.618698 1.323225 -1.841822
-v 0.618698 1.323225 1.841822
-v 0.621490 0.656400 -1.850132
-v 0.621490 0.656400 1.850132
-v 0.625735 0.008400 0.325553
-v 0.625735 0.008400 -0.325553
-v 0.629147 1.178400 -1.872927
-v 0.629147 1.178400 1.872927
-v 0.633613 0.771675 -1.886223
-v 0.633613 0.771675 1.886223
-v 0.635767 1.037175 -1.892634
-v 0.635767 1.037175 1.892634
-v 0.638080 0.900000 -1.899520
-v 0.638080 0.900000 -1.899520
-v 0.638080 0.900000 1.899520
-v 0.638080 0.900000 1.899520
-v 0.639070 2.463000 -1.228335
-v 0.639070 2.463000 1.228335
-v 0.639758 2.572800 -0.214905
-v 0.639758 2.572800 0.214905
-v 0.639915 2.482687 1.229959
-v 0.639915 2.482687 -1.229959
-v 0.639996 0.064800 -1.230115
-v 0.639996 0.064800 1.230115
-v 0.641628 2.435437 -1.233252
-v 0.641628 2.435437 1.233252
-v 0.643607 2.494500 -1.237056
-v 0.643607 2.494500 1.237056
-v 0.648144 2.400000 -1.245776
-v 0.648144 2.400000 1.245776
-v 0.649591 2.498438 -1.248557
-v 0.649591 2.498438 1.248557
-v 0.653431 2.502600 -0.890370
-v 0.653431 2.502600 0.890370
-v 0.657311 2.494500 -1.263395
-v 0.657311 2.494500 1.263395
-v 0.664924 2.572800 -0.110524
-v 0.664924 2.572800 0.110524
-v 0.666211 2.482687 1.280502
-v 0.666211 2.482687 -1.280502
-v 0.667656 2.550000 -0.489984
-v 0.667656 2.550000 0.489984
-v 0.667871 0.008400 -0.224349
-v 0.667871 0.008400 0.224349
-v 0.669128 0.084525 -1.286108
-v 0.669128 0.084525 1.286108
-v 0.673600 2.572800 0.000000
-v 0.673600 2.572800 -0.000000
-v 0.675736 2.463000 -1.298810
-v 0.675736 2.463000 1.298810
-v 0.676222 0.018225 0.676222
-v 0.676222 0.018225 -0.676222
-v 0.679207 0.031200 -0.925493
-v 0.679207 0.031200 0.925493
-v 0.685331 2.435437 -1.317252
-v 0.685331 2.435437 1.317252
-v 0.685551 0.105600 -1.317675
-v 0.685551 0.105600 1.317675
-v 0.688984 2.527200 -0.688984
-v 0.688984 2.527200 0.688984
-v 0.692808 0.127575 1.331623
-v 0.692808 0.127575 -1.331623
-v 0.694143 0.008400 -0.115381
-v 0.694143 0.008400 0.115381
-v 0.694440 0.150000 1.334760
-v 0.694440 0.150000 -1.334760
-v 0.694440 2.400000 1.334760
-v 0.694440 0.150000 -1.334760
-v 0.694440 0.150000 1.334760
-v 0.694440 2.400000 -1.334760
-v 0.700921 0.177075 1.347218
-v 0.700921 0.177075 -1.347218
-v 0.703200 0.008400 0.000000
-v 0.715555 2.474400 -0.975021
-v 0.715555 2.474400 0.975021
-v 0.718514 0.213600 1.381032
-v 0.718514 0.213600 -1.381032
-v 0.729046 2.242575 -1.401276
-v 0.729046 2.242575 1.401276
-v 0.734118 2.550000 -0.381942
-v 0.734118 2.550000 0.381942
-v 0.744440 0.260025 1.430863
-v 0.744440 0.260025 -1.430863
-v 0.757010 2.440800 1.031508
-v 0.757010 2.440800 -1.031508
-v 0.762816 0.046875 -1.039419
-v 0.762816 0.046875 1.039419
-v 0.762958 2.085600 -1.466456
-v 0.762958 2.085600 1.466456
-v 0.770779 0.018225 0.565664
-v 0.770779 0.018225 -0.565664
-v 0.772096 2.400000 -1.052064
-v 0.772096 2.400000 1.052064
-v 0.775921 0.316800 -1.491372
-v 0.775921 0.316800 1.491372
-v 0.781142 2.502600 -0.781142
-v 0.781142 2.502600 0.781142
-v 0.783552 2.550000 -0.263208
-v 0.783552 2.550000 0.263208
-v 0.785325 2.527200 -0.576340
-v 0.785325 2.527200 0.576340
-v 0.795481 1.929525 1.528968
-v 0.795481 1.929525 -1.528968
-v 0.810180 0.384375 1.557220
-v 0.810180 0.384375 -1.557220
-v 0.811956 0.031200 0.811956
-v 0.811956 0.031200 -0.811956
-v 0.814374 2.550000 -0.135366
-v 0.814374 2.550000 0.135366
-v 0.819847 2.463000 -1.117130
-v 0.819847 2.463000 1.117130
-v 0.820931 2.482687 1.118607
-v 0.820931 2.482687 -1.118607
-v 0.821035 0.064800 1.118749
-v 0.821035 0.064800 -1.118749
-v 0.823129 2.435437 -1.121601
-v 0.823129 2.435437 1.121601
-v 0.825000 2.550000 0.000000
-v 0.825000 2.550000 0.000000
-v 0.825668 2.494500 -1.125061
-v 0.825668 2.494500 1.125061
-v 0.825921 1.774800 1.587475
-v 0.825921 1.774800 -1.587475
-v 0.831488 2.400000 -1.132992
-v 0.831488 2.400000 1.132992
-v 0.833344 2.498438 -1.135521
-v 0.833344 2.498438 1.135521
-v 0.843248 2.494500 -1.149016
-v 0.843248 2.494500 1.149016
-v 0.844439 0.463200 1.623068
-v 0.844439 0.463200 -1.623068
-v 0.847506 0.018225 -0.440935
-v 0.847506 0.018225 0.440935
-v 0.853583 1.621875 -1.640643
-v 0.853583 1.621875 1.640643
-v 0.854666 2.482687 -1.164574
-v 0.854666 2.482687 1.164574
-v 0.855408 2.474400 -0.855408
-v 0.855408 2.474400 0.855408
-v 0.858407 0.084525 -1.169673
-v 0.858407 0.084525 1.169673
-v 0.863501 2.527200 -0.449256
-v 0.863501 2.527200 0.449256
-v 0.866886 2.463000 -1.181225
-v 0.866886 2.463000 1.181225
-v 0.875920 0.553725 -1.683577
-v 0.875920 0.553725 1.683577
-v 0.877772 1.471200 -1.687137
-v 0.877772 1.471200 1.687137
-v 0.879195 2.435437 -1.197997
-v 0.879195 2.435437 1.197997
-v 0.879477 0.105600 -1.198382
-v 0.879477 0.105600 1.198382
-v 0.888786 0.127575 1.211067
-v 0.888786 0.127575 -1.211067
-v 0.890370 2.502600 -0.653431
-v 0.890370 2.502600 0.653431
-v 0.890880 0.150000 -1.213920
-v 0.890880 0.150000 1.213920
-v 0.890880 2.400000 -1.213920
-v 0.890880 0.150000 -1.213920
-v 0.890880 0.150000 1.213920
-v 0.890880 2.400000 1.213920
-v 0.897795 1.323225 -1.725622
-v 0.897795 1.323225 1.725622
-v 0.899195 0.177075 1.225250
-v 0.899195 0.177075 -1.225250
-v 0.901846 0.656400 -1.733408
-v 0.901846 0.656400 1.733408
-v 0.904575 0.018225 0.303862
-v 0.904575 0.018225 -0.303862
-v 0.904966 2.440800 0.904966
-v 0.904966 2.440800 -0.904966
-v 0.911906 0.046875 -0.911906
-v 0.911906 0.046875 0.911906
-v 0.912957 1.178400 -1.754764
-v 0.912957 1.178400 1.754764
-v 0.919439 0.771675 -1.767222
-v 0.919439 0.771675 1.767222
-v 0.921647 2.527200 -0.309596
-v 0.921647 2.527200 0.309596
-v 0.921764 0.213600 1.256003
-v 0.921764 0.213600 -1.256003
-v 0.922564 1.037175 1.773229
-v 0.922564 1.037175 -1.773229
-v 0.923000 2.400000 -0.923000
-v 0.923000 2.400000 0.923000
-v 0.925493 0.031200 0.679207
-v 0.925493 0.031200 -0.679207
-v 0.925920 0.900000 1.779680
-v 0.925920 0.900000 -1.779680
-v 0.925920 0.900000 -1.779680
-v 0.925920 0.900000 1.779680
-v 0.935276 2.242575 -1.274414
-v 0.935276 2.242575 1.274414
-v 0.940158 0.018225 0.156274
-v 0.940158 0.018225 -0.156274
-v 0.952425 0.018225 0.000000
-v 0.952425 0.018225 0.000000
-v 0.955023 0.260025 1.301322
-v 0.955023 0.260025 -1.301322
-v 0.957901 2.527200 -0.159223
-v 0.957901 2.527200 0.159223
-v 0.970400 2.527200 0.000000
-v 0.970400 2.527200 -0.000000
-v 0.975021 2.474400 -0.715555
-v 0.975021 2.474400 0.715555
-v 0.978780 2.085600 -1.333693
-v 0.978780 2.085600 1.333693
-v 0.979002 2.502600 0.509349
-v 0.979002 2.502600 -0.509349
-v 0.980084 2.463000 -0.980084
-v 0.980084 2.463000 0.980084
-v 0.981380 2.482687 -0.981380
-v 0.981380 2.482687 0.981380
-v 0.981504 0.064800 0.981504
-v 0.981504 0.064800 -0.981504
-v 0.984007 2.435437 -0.984007
-v 0.984007 2.435437 0.984007
-v 0.987042 2.494500 -0.987042
-v 0.987042 2.494500 0.987042
-v 0.994000 2.400000 -0.994000
-v 0.994000 2.400000 0.994000
-v 0.995410 0.316800 -1.356353
-v 0.995410 0.316800 1.356353
-v 0.996219 2.498438 -0.996219
-v 0.996219 2.498438 0.996219
-v 1.008058 2.494500 -1.008058
-v 1.008058 2.494500 1.008058
-v 1.017621 0.031200 0.529441
-v 1.017621 0.031200 -0.529441
-v 1.020503 1.929525 -1.390545
-v 1.020503 1.929525 1.390545
-v 1.021708 2.482687 -1.021708
-v 1.021708 2.482687 1.021708
-v 1.026181 0.084525 -1.026181
-v 1.026181 0.084525 1.026181
-v 1.031508 2.440800 0.757010
-v 1.031508 2.440800 -0.757010
-v 1.036316 2.463000 -1.036316
-v 1.036316 2.463000 1.036316
-v 1.039360 0.384375 -1.416240
-v 1.039360 0.384375 1.416240
-v 1.039419 0.046875 -0.762816
-v 1.039419 0.046875 0.762816
-v 1.044926 2.502600 -0.351008
-v 1.044926 2.502600 0.351008
-v 1.051031 2.435437 -1.051031
-v 1.051031 2.435437 1.051031
-v 1.051368 0.105600 -1.051368
-v 1.051368 0.105600 1.051368
-v 1.052064 2.400000 -0.772096
-v 1.052064 2.400000 0.772096
-v 1.059553 1.774800 -1.443756
-v 1.059553 1.774800 1.443756
-v 1.062497 0.127575 1.062497
-v 1.062497 0.127575 -1.062497
-v 1.065000 0.150000 -1.065000
-v 1.065000 0.150000 1.065000
-v 1.065000 2.400000 -1.065000
-v 1.065000 2.400000 1.065000
-v 1.072079 2.474400 -0.557774
-v 1.072079 2.474400 0.557774
-v 1.074940 0.177075 -1.074940
-v 1.074940 0.177075 1.074940
-v 1.083310 0.463200 -1.476127
-v 1.083310 0.463200 1.476127
-v 1.086029 2.502600 0.180521
-v 1.086029 2.502600 -0.180521
-v 1.086146 0.031200 0.364854
-v 1.086146 0.031200 -0.364854
-v 1.095040 1.621875 -1.492110
-v 1.095040 1.621875 1.492110
-v 1.100200 2.502600 -0.000000
-v 1.100200 2.502600 0.000000
-v 1.101920 0.213600 1.101920
-v 1.101920 0.213600 -1.101920
-v 1.117130 2.463000 -0.819847
-v 1.117130 2.463000 0.819847
-v 1.118073 2.242575 -1.118073
-v 1.118073 2.242575 1.118073
-v 1.118607 2.482687 -0.820931
-v 1.118607 2.482687 0.820931
-v 1.118749 0.064800 -0.821035
-v 1.118749 0.064800 0.821035
-v 1.121601 2.435437 -0.823129
-v 1.121601 2.435437 0.823129
-v 1.123697 0.553725 -1.531158
-v 1.123697 0.553725 1.531158
-v 1.125061 2.494500 -0.825668
-v 1.125061 2.494500 0.825668
-v 1.126072 1.471200 -1.534395
-v 1.126072 1.471200 1.534395
-v 1.128870 0.031200 -0.187642
-v 1.128870 0.031200 0.187642
-v 1.132992 2.400000 -0.831488
-v 1.132992 2.400000 0.831488
-v 1.134190 2.440800 0.590089
-v 1.134190 2.440800 -0.590089
-v 1.135521 2.498438 -0.833344
-v 1.135521 2.498438 0.833344
-v 1.141680 0.260025 1.141680
-v 1.141680 0.260025 -1.141680
-v 1.142888 0.046875 -0.594614
-v 1.142888 0.046875 0.594614
-v 1.143600 0.031200 0.000000
-v 1.143600 0.031200 0.000000
-v 1.144271 2.474400 -0.384379
-v 1.144271 2.474400 0.384379
-v 1.149016 2.494500 -0.843248
-v 1.149016 2.494500 0.843248
-v 1.151759 1.323225 -1.569396
-v 1.151759 1.323225 1.569396
-v 1.156792 2.400000 -0.601848
-v 1.156792 2.400000 0.601848
-v 1.156956 0.656400 -1.576477
-v 1.156956 0.656400 1.576477
-v 1.164574 2.482687 -0.854666
-v 1.164574 2.482687 0.854666
-v 1.169673 0.084525 -0.858407
-v 1.169673 0.084525 0.858407
-v 1.170080 2.085600 -1.170080
-v 1.170080 2.085600 1.170080
-v 1.171210 1.178400 -1.595900
-v 1.171210 1.178400 1.595900
-v 1.179525 0.771675 -1.607230
-v 1.179525 0.771675 1.607230
-v 1.181225 2.463000 -0.866886
-v 1.181225 2.463000 0.866886
-v 1.183534 1.037175 -1.612693
-v 1.183534 1.037175 1.612693
-v 1.187840 0.900000 -1.618560
-v 1.187840 0.900000 -1.618560
-v 1.187840 0.900000 1.618560
-v 1.187840 0.900000 1.618560
-v 1.189282 2.474400 -0.197684
-v 1.189282 2.474400 0.197684
-v 1.189960 0.316800 -1.189960
-v 1.189960 0.316800 1.189960
-v 1.197997 2.435437 -0.879195
-v 1.197997 2.435437 0.879195
-v 1.198382 0.105600 -0.879477
-v 1.198382 0.105600 0.879477
-v 1.204800 2.474400 0.000000
-v 1.204800 2.474400 -0.000000
-v 1.210564 2.440800 0.406648
-v 1.210564 2.440800 -0.406648
-v 1.211067 0.127575 0.888786
-v 1.211067 0.127575 -0.888786
-v 1.213920 0.150000 -0.890880
-v 1.213920 0.150000 -0.890880
-v 1.213920 0.150000 0.890880
-v 1.213920 0.150000 0.890880
-v 1.213920 2.400000 -0.890880
-v 1.213920 2.400000 0.890880
-v 1.219848 0.046875 -0.409767
-v 1.219848 0.046875 0.409767
-v 1.219958 1.929525 1.219958
-v 1.219958 1.929525 -1.219958
-v 1.225250 0.177075 0.899195
-v 1.225250 0.177075 -0.899195
-v 1.228335 2.463000 -0.639070
-v 1.228335 2.463000 0.639070
-v 1.229959 2.482687 -0.639915
-v 1.229959 2.482687 0.639915
-v 1.230115 0.064800 -0.639996
-v 1.230115 0.064800 0.639996
-v 1.233252 2.435437 -0.641628
-v 1.233252 2.435437 0.641628
-v 1.234688 2.400000 -0.414752
-v 1.234688 2.400000 0.414752
-v 1.237056 2.494500 -0.643607
-v 1.237056 2.494500 0.643607
-v 1.242500 0.384375 -1.242500
-v 1.242500 0.384375 1.242500
-v 1.245776 2.400000 -0.648144
-v 1.245776 2.400000 0.648144
-v 1.248557 2.498438 -0.649591
-v 1.248557 2.498438 0.649591
-v 1.256003 0.213600 0.921764
-v 1.256003 0.213600 -0.921764
-v 1.258183 2.440800 0.209136
-v 1.258183 2.440800 -0.209136
-v 1.263395 2.494500 -0.657311
-v 1.263395 2.494500 0.657311
-v 1.266640 1.774800 -1.266640
-v 1.266640 1.774800 1.266640
-v 1.267832 0.046875 -0.210740
-v 1.267832 0.046875 0.210740
-v 1.274414 2.242575 -0.935276
-v 1.274414 2.242575 0.935276
-v 1.274600 2.440800 0.000000
-v 1.274600 2.440800 0.000000
-v 1.280502 2.482687 -0.666211
-v 1.280502 2.482687 0.666211
-v 1.283256 2.400000 -0.213304
-v 1.283256 2.400000 0.213304
-v 1.284375 0.046875 0.000000
-v 1.284375 0.046875 -0.000000
-v 1.286108 0.084525 -0.669128
-v 1.286108 0.084525 0.669128
-v 1.295040 0.463200 -1.295040
-v 1.295040 0.463200 1.295040
-v 1.298810 2.463000 -0.675736
-v 1.298810 2.463000 0.675736
-v 1.300000 2.400000 0.000000
-v 1.300000 2.400000 -0.000000
-v 1.301322 0.260025 0.955023
-v 1.301322 0.260025 -0.955023
-v 1.309063 1.621875 -1.309063
-v 1.309063 1.621875 1.309063
-v 1.311049 2.463000 -0.440403
-v 1.311049 2.463000 0.440403
-v 1.312782 2.482687 -0.440985
-v 1.312782 2.482687 0.440985
-v 1.312948 0.064800 0.441041
-v 1.312948 0.064800 -0.441041
-v 1.316296 2.435437 -0.442166
-v 1.316296 2.435437 0.442166
-v 1.317252 2.435437 -0.685331
-v 1.317252 2.435437 0.685331
-v 1.317675 0.105600 -0.685551
-v 1.317675 0.105600 0.685551
-v 1.320356 2.494500 -0.443529
-v 1.320356 2.494500 0.443529
-v 1.329664 2.400000 -0.446656
-v 1.329664 2.400000 0.446656
-v 1.331623 0.127575 0.692808
-v 1.331623 0.127575 -0.692808
-v 1.332632 2.498438 -0.447653
-v 1.332632 2.498438 0.447653
-v 1.333693 2.085600 -0.978780
-v 1.333693 2.085600 0.978780
-v 1.334760 0.150000 0.694440
-v 1.334760 0.150000 -0.694440
-v 1.334760 0.150000 -0.694440
-v 1.334760 0.150000 0.694440
-v 1.334760 2.400000 -0.694440
-v 1.334760 2.400000 0.694440
-v 1.343320 0.553725 -1.343320
-v 1.343320 0.553725 1.343320
-v 1.346160 1.471200 -1.346160
-v 1.346160 1.471200 1.346160
-v 1.347218 0.177075 0.700921
-v 1.347218 0.177075 -0.700921
-v 1.348469 2.494500 -0.452973
-v 1.348469 2.494500 0.452973
-v 1.356353 0.316800 -0.995410
-v 1.356353 0.316800 0.995410
-v 1.362620 2.463000 -0.226496
-v 1.362620 2.463000 0.226496
-v 1.364422 2.482687 -0.226795
-v 1.364422 2.482687 0.226795
-v 1.364595 0.064800 -0.226824
-v 1.364595 0.064800 0.226824
-v 1.366728 2.482687 -0.459107
-v 1.366728 2.482687 0.459107
-v 1.368074 2.435437 -0.227403
-v 1.368074 2.435437 0.227403
-v 1.372294 2.494500 -0.228104
-v 1.372294 2.494500 0.228104
-v 1.372712 0.084525 -0.461116
-v 1.372712 0.084525 0.461116
-v 1.376867 1.323225 -1.376868
-v 1.376868 1.323225 1.376867
-v 1.380400 2.463000 0.000000
-v 1.380400 2.463000 -0.000000
-v 1.381032 0.213600 0.718514
-v 1.381032 0.213600 -0.718514
-v 1.381968 2.400000 -0.229712
-v 1.381968 2.400000 0.229712
-v 1.382225 2.482687 0.000000
-v 1.382225 2.482687 0.000000
-v 1.382400 0.064800 0.000000
-v 1.382400 0.064800 0.000000
-v 1.383080 0.656400 -1.383080
-v 1.383080 0.656400 1.383080
-v 1.385053 2.498438 -0.230225
-v 1.385053 2.498438 0.230225
-v 1.385925 2.435437 0.000000
-v 1.385925 2.435437 -0.000000
-v 1.386270 2.463000 -0.465671
-v 1.386270 2.463000 0.465671
-v 1.390200 2.494500 0.000000
-v 1.390200 2.494500 -0.000000
-v 1.390545 1.929525 -1.020503
-v 1.390545 1.929525 1.020503
-v 1.400000 2.400000 0.000000
-v 1.400000 2.400000 0.000000
-v 1.400120 1.178400 -1.400120
-v 1.400120 1.178400 1.400120
-v 1.401276 2.242575 -0.729046
-v 1.401276 2.242575 0.729046
-v 1.401513 2.494500 -0.232961
-v 1.401513 2.494500 0.232961
-v 1.403125 2.498438 0.000000
-v 1.403125 2.498438 0.000000
-v 1.405953 2.435437 -0.472283
-v 1.405953 2.435437 0.472283
-v 1.406405 0.105600 -0.472434
-v 1.406405 0.105600 0.472434
-v 1.410060 0.771675 -1.410060
-v 1.410060 0.771675 1.410060
-v 1.414853 1.037175 -1.414853
-v 1.414853 1.037175 1.414853
-v 1.416240 0.384375 -1.039360
-v 1.416240 0.384375 1.039360
-v 1.419800 2.494500 0.000000
-v 1.419800 2.494500 -0.000000
-v 1.420000 0.900000 -1.420000
-v 1.420000 0.900000 -1.420000
-v 1.420000 0.900000 1.420000
-v 1.420000 0.900000 1.420000
-v 1.420490 2.482687 -0.236115
-v 1.420490 2.482687 0.236115
-v 1.421292 0.127575 0.477435
-v 1.421292 0.127575 -0.477435
-v 1.424640 0.150000 -0.478560
-v 1.424640 0.150000 -0.478560
-v 1.424640 0.150000 0.478560
-v 1.424640 0.150000 0.478560
-v 1.424640 2.400000 -0.478560
-v 1.424640 2.400000 0.478560
-v 1.426709 0.084525 -0.237149
-v 1.426709 0.084525 0.237149
-v 1.430863 0.260025 0.744440
-v 1.430863 0.260025 -0.744440
-v 1.437937 0.177075 0.483027
-v 1.437937 0.177075 -0.483027
-v 1.439025 2.482687 0.000000
-v 1.440800 2.463000 -0.239491
-v 1.440800 2.463000 0.239491
-v 1.443756 1.774800 -1.059553
-v 1.443756 1.774800 1.059553
-v 1.445325 0.084525 0.000000
-v 1.445325 0.084525 0.000000
-v 1.459600 2.463000 0.000000
-v 1.459600 2.463000 -0.000000
-v 1.461258 2.435437 -0.242892
-v 1.461258 2.435437 0.242892
-v 1.461727 0.105600 -0.242970
-v 1.461727 0.105600 0.242970
-v 1.466456 2.085600 -0.762958
-v 1.466456 2.085600 0.762958
-v 1.474028 0.213600 0.495150
-v 1.474028 0.213600 -0.495150
-v 1.476127 0.463200 -1.083310
-v 1.476127 0.463200 1.083310
-v 1.477200 0.127575 0.245542
-v 1.477200 0.127575 -0.245542
-v 1.480325 2.435437 0.000000
-v 1.480325 2.435437 -0.000000
-v 1.480680 0.150000 -0.246120
-v 1.480680 0.150000 0.246120
-v 1.480680 0.150000 0.246120
-v 1.480680 0.150000 -0.246120
-v 1.480680 2.400000 -0.246120
-v 1.480680 2.400000 0.246120
-v 1.480800 0.105600 0.000000
-v 1.480800 0.105600 0.000000
-v 1.491372 0.316800 -0.775921
-v 1.491372 0.316800 0.775921
-v 1.492110 1.621875 -1.095040
-v 1.492110 1.621875 1.095040
-v 1.494500 0.177075 0.248417
-v 1.494500 0.177075 -0.248417
-v 1.495635 2.242575 -0.502408
-v 1.495635 2.242575 0.502408
-v 1.496475 0.127575 0.000000
-v 1.496475 0.127575 0.000000
-v 1.500000 0.150000 0.000000
-v 1.500000 0.150000 0.000000
-v 1.500000 2.400000 0.000000
-v 1.500000 2.400000 0.000000
-v 1.514000 0.177075 -0.000000
-v 1.514000 0.177075 0.000000
-v 1.527214 0.260025 -0.513016
-v 1.527214 0.260025 0.513016
-v 1.528968 1.929525 -0.795481
-v 1.528968 1.929525 0.795481
-v 1.531158 0.553725 -1.123697
-v 1.531158 0.553725 1.123697
-v 1.532010 0.213600 0.254652
-v 1.532010 0.213600 -0.254652
-v 1.534395 1.471200 -1.126072
-v 1.534395 1.471200 1.126072
-v 1.552000 0.213600 0.000000
-v 1.552000 0.213600 0.000000
-v 1.554467 2.242575 -0.258385
-v 1.554467 2.242575 0.258385
-v 1.557220 0.384375 -0.810180
-v 1.557220 0.384375 0.810180
-v 1.565204 2.085600 -0.525778
-v 1.565204 2.085600 0.525778
-v 1.569396 1.323225 -1.151759
-v 1.569396 1.323225 1.151759
-v 1.574750 2.242575 0.000000
-v 1.574750 2.242575 0.000000
-v 1.576477 0.656400 -1.156956
-v 1.576477 0.656400 1.156956
-v 1.587289 0.260025 0.263841
-v 1.587289 0.260025 -0.263841
-v 1.587475 1.774800 -0.825921
-v 1.587475 1.774800 0.825921
-v 1.591798 0.316800 -0.534711
-v 1.591798 0.316800 0.534711
-v 1.595900 1.178400 -1.171210
-v 1.595900 1.178400 1.171210
-v 1.607230 0.771675 -1.179525
-v 1.607230 0.771675 1.179525
-v 1.608000 0.260025 0.000000
-v 1.608000 0.260025 0.000000
-v 1.612693 1.037175 -1.183534
-v 1.612693 1.037175 1.183534
-v 1.618560 0.900000 -1.187840
-v 1.618560 0.900000 -1.187840
-v 1.618560 0.900000 1.187840
-v 1.618560 0.900000 1.187840
-v 1.623068 0.463200 -0.844439
-v 1.623068 0.463200 0.844439
-v 1.626774 2.085600 -0.270404
-v 1.626774 2.085600 0.270404
-v 1.631925 1.929525 -0.548190
-v 1.631925 1.929525 0.548190
-v 1.640643 1.621875 -0.853583
-v 1.640643 1.621875 0.853583
-v 1.648000 2.085600 0.000000
-v 1.648000 2.085600 -0.000000
-v 1.654413 0.316800 -0.274998
-v 1.654413 0.316800 0.274998
-v 1.662080 0.384375 -0.558320
-v 1.662080 0.384375 0.558320
-v 1.676000 0.316800 0.000000
-v 1.676000 0.316800 0.000000
-v 1.683577 0.553725 -0.875920
-v 1.683577 0.553725 0.875920
-v 1.687137 1.471200 -0.877772
-v 1.687137 1.471200 0.877772
-v 1.694372 1.774800 -0.569167
-v 1.694372 1.774800 0.569167
-v 1.696119 1.929525 -0.281930
-v 1.696119 1.929525 0.281930
-v 1.700000 0.600000 0.000000
-v 1.700000 0.600000 0.000000
-v 1.700000 0.623100 0.178200
-v 1.700000 0.623100 -0.178200
-v 1.700000 0.685800 -0.316800
-v 1.700000 0.685800 0.316800
-v 1.700000 0.778200 0.415800
-v 1.700000 0.778200 -0.415800
-v 1.700000 0.890400 -0.475200
-v 1.700000 0.890400 0.475200
-v 1.700000 1.012500 -0.495000
-v 1.700000 1.012500 0.495000
-v 1.700000 1.134600 -0.475200
-v 1.700000 1.134600 0.475200
-v 1.700000 1.246800 0.415800
-v 1.700000 1.246800 -0.415800
-v 1.700000 1.339200 -0.316800
-v 1.700000 1.339200 0.316800
-v 1.700000 1.401900 0.178200
-v 1.700000 1.401900 -0.178200
-v 1.700000 1.425000 0.000000
-v 1.700000 1.425000 0.000000
-v 1.718250 1.929525 0.000000
-v 1.718250 1.929525 0.000000
-v 1.725622 1.323225 -0.897795
-v 1.725622 1.323225 0.897795
-v 1.727460 0.384375 -0.287140
-v 1.727460 0.384375 0.287140
-v 1.732362 0.463200 -0.581929
-v 1.732362 0.463200 0.581929
-v 1.733408 0.656400 -0.901846
-v 1.733408 0.656400 0.901846
-v 1.750000 0.384375 0.000000
-v 1.750000 0.384375 0.000000
-v 1.751120 1.621875 -0.588230
-v 1.751120 1.621875 0.588230
-v 1.754764 1.178400 -0.912957
-v 1.754764 1.178400 0.912957
-v 1.761022 1.774800 -0.292719
-v 1.761022 1.774800 0.292719
-v 1.767222 0.771675 -0.919439
-v 1.767222 0.771675 0.919439
-v 1.773229 1.037175 -0.922564
-v 1.773229 1.037175 0.922564
-v 1.779680 0.900000 -0.925920
-v 1.779680 0.900000 -0.925920
-v 1.779680 0.900000 0.925920
-v 1.779680 0.900000 0.925920
-v 1.784000 1.774800 0.000000
-v 1.784000 1.774800 0.000000
-v 1.796946 0.553725 -0.603624
-v 1.796946 0.553725 0.603624
-v 1.800507 0.463200 -0.299282
-v 1.800507 0.463200 0.299282
-v 1.800745 1.471200 -0.604900
-v 1.800745 1.471200 0.604900
-v 1.820003 1.621875 -0.302523
-v 1.820003 1.621875 0.302522
-v 1.824000 0.463200 0.000000
-v 1.824000 0.463200 0.000000
-v 1.841822 1.323225 -0.618698
-v 1.841822 1.323225 0.618698
-v 1.843750 1.621875 0.000000
-v 1.843750 1.621875 -0.000000
-v 1.850132 0.656400 -0.621490
-v 1.850132 0.656400 0.621490
-v 1.867631 0.553725 -0.310439
-v 1.867631 0.553725 0.310439
-v 1.871580 1.471200 -0.311096
-v 1.871580 1.471200 0.311096
-v 1.872927 1.178400 -0.629147
-v 1.872927 1.178400 0.629147
-v 1.886223 0.771675 -0.633613
-v 1.886223 0.771675 0.633613
-v 1.892000 0.553725 0.000000
-v 1.892000 0.553725 -0.000000
-v 1.892634 1.037175 -0.635767
-v 1.892634 1.037175 0.635767
-v 1.896000 1.471200 0.000000
-v 1.896000 1.471200 0.000000
-v 1.899520 0.900000 -0.638080
-v 1.899520 0.900000 -0.638080
-v 1.899520 0.900000 0.638080
-v 1.899520 0.900000 0.638080
-v 1.914272 1.323225 -0.318192
-v 1.914272 1.323225 0.318192
-v 1.922910 0.656400 -0.319628
-v 1.922910 0.656400 0.319628
-v 1.935900 1.444200 0.000000
-v 1.935900 1.444200 0.000000
-v 1.939250 1.323225 0.000000
-v 1.939250 1.323225 -0.000000
-v 1.939394 1.423221 -0.175100
-v 1.939394 1.423221 0.175100
-v 1.946601 1.178400 -0.323566
-v 1.946601 1.178400 0.323566
-v 1.948000 0.656400 0.000000
-v 1.948000 0.656400 -0.000000
-v 1.948879 1.366278 -0.311290
-v 1.948879 1.366278 0.311290
-v 1.960420 0.771675 -0.325863
-v 1.960420 0.771675 0.325863
-v 1.962857 1.282362 -0.408568
-v 1.962857 1.282362 0.408568
-v 1.967083 1.037175 -0.326970
-v 1.967083 1.037175 0.326970
-v 1.972000 1.178400 0.000000
-v 1.972000 1.178400 0.000000
-v 1.974240 0.900000 -0.328160
-v 1.974240 0.900000 0.328160
-v 1.974240 0.900000 0.328160
-v 1.979830 1.180464 -0.466934
-v 1.979830 1.180464 0.466934
-v 1.986000 0.771675 0.000000
-v 1.986000 0.771675 -0.000000
-v 1.992750 1.037175 0.000000
-v 1.992750 1.037175 0.000000
-v 1.998300 1.069575 -0.486390
-v 1.998300 1.069575 0.486390
-v 2.000000 0.900000 0.000000
-v 2.000000 0.900000 0.000000
-v 2.016770 0.958686 -0.466934
-v 2.016770 0.958686 0.466934
-v 2.033743 0.856788 -0.408568
-v 2.033743 0.856788 0.408568
-v 2.047721 0.772872 0.311290
-v 2.047721 0.772872 -0.311290
-v 2.057206 0.715929 0.175100
-v 2.057206 0.715929 -0.175100
-v 2.060700 0.694950 0.000000
-v 2.060700 0.694950 0.000000
-v 2.111200 1.497600 0.000000
-v 2.111200 1.497600 0.000000
-v 2.116979 1.479120 -0.166687
-v 2.116979 1.479120 0.166687
-v 2.132666 1.428960 -0.296333
-v 2.132666 1.428960 0.296333
-v 2.155782 1.355040 -0.388937
-v 2.155782 1.355040 0.388937
-v 2.183853 1.265280 -0.444499
-v 2.183853 1.265280 0.444499
-v 2.214400 1.167600 -0.463020
-v 2.214400 1.167600 0.463020
-v 2.237300 1.578900 0.000000
-v 2.237300 1.578900 0.000000
-v 2.244457 1.563171 -0.154289
-v 2.244457 1.563171 0.154289
-v 2.244947 1.069920 -0.444499
-v 2.244947 1.069920 0.444499
-v 2.263882 1.520478 -0.274291
-v 2.263882 1.520478 0.274291
-v 2.273018 0.980160 -0.388937
-v 2.273018 0.980160 0.388937
-v 2.292510 1.457562 -0.360007
-v 2.292510 1.457562 0.360007
-v 2.296134 0.906240 -0.296333
-v 2.296134 0.906240 0.296333
-v 2.311821 0.856080 -0.166687
-v 2.311821 0.856080 0.166687
-v 2.317600 0.837600 0.000000
-v 2.317600 0.837600 0.000000
-v 2.325600 1.681800 0.000000
-v 2.325600 1.681800 0.000000
-v 2.327271 1.381164 -0.411437
-v 2.327271 1.381164 0.411437
-v 2.333530 1.668948 -0.139234
-v 2.333530 1.668948 0.139234
-v 2.355053 1.634064 -0.247526
-v 2.355053 1.634064 0.247526
-v 2.365100 1.298025 -0.428580
-v 2.365100 1.298025 0.428580
-v 2.386771 1.582656 -0.324878
-v 2.386771 1.582656 0.324878
-v 2.387500 1.800000 0.000000
-v 2.387500 1.800000 0.000000
-v 2.395900 1.790025 0.122850
-v 2.395900 1.790025 -0.122850
-v 2.402929 1.214886 -0.411437
-v 2.402929 1.214886 0.411437
-v 2.418700 1.762950 -0.218400
-v 2.418700 1.762950 0.218400
-v 2.425286 1.520232 -0.371290
-v 2.425286 1.520232 0.371290
-v 2.434400 1.927200 0.000000
-v 2.434400 1.927200 0.000000
-v 2.437690 1.138488 -0.360007
-v 2.437690 1.138488 0.360007
-v 2.443270 1.919976 0.106466
-v 2.443270 1.919976 -0.106466
-v 2.452300 1.723050 -0.286650
-v 2.452300 1.723050 0.286650
-v 2.466318 1.075572 -0.274291
-v 2.466318 1.075572 0.274291
-v 2.467200 1.452300 -0.386760
-v 2.467200 1.452300 0.386760
-v 2.467347 1.900368 0.189274
-v 2.467347 1.900368 -0.189274
-v 2.477700 2.057100 0.000000
-v 2.477700 2.057100 0.000000
-v 2.485743 1.032879 -0.154289
-v 2.485743 1.032879 0.154289
-v 2.487343 2.052375 -0.091411
-v 2.487343 2.052375 0.091411
-v 2.492900 1.017150 0.000000
-v 2.492900 1.017150 0.000000
-v 2.493100 1.674600 -0.327600
-v 2.493100 1.674600 0.327600
-v 2.502829 1.871472 0.248422
-v 2.502829 1.871472 -0.248422
-v 2.509114 1.384368 -0.371290
-v 2.509114 1.384368 0.371290
-v 2.513518 2.039550 0.162509
-v 2.513518 2.039550 -0.162509
-v 2.528800 2.183400 0.000000
-v 2.537500 1.621875 -0.341250
-v 2.537500 1.621875 0.341250
-v 2.539821 2.180796 -0.079013
-v 2.539821 2.180796 0.079013
-v 2.545914 1.836384 -0.283910
-v 2.545914 1.836384 0.283910
-v 2.547629 1.321944 -0.324878
-v 2.547629 1.321944 0.324878
-v 2.552090 2.020650 -0.213293
-v 2.552090 2.020650 0.213293
-v 2.569734 2.173728 -0.140467
-v 2.569734 2.173728 0.140467
-v 2.579347 1.270536 -0.247526
-v 2.579347 1.270536 0.247526
-v 2.581900 1.569150 -0.327600
-v 2.581900 1.569150 0.327600
-v 2.592800 1.798200 -0.295740
-v 2.592800 1.798200 0.295740
-v 2.598929 1.997700 -0.243763
-v 2.598929 1.997700 0.243763
-v 2.599100 2.299800 0.000000
-v 2.599100 2.299800 0.000000
-v 2.600870 1.235652 -0.139234
-v 2.600870 1.235652 0.139234
-v 2.608800 1.222800 0.000000
-v 2.608800 1.222800 0.000000
-v 2.612406 2.298813 0.070600
-v 2.612406 2.298813 -0.070600
-v 2.613818 2.163312 -0.184363
-v 2.613818 2.163312 0.184363
-v 2.622700 1.520700 -0.286650
-v 2.622700 1.520700 0.286650
-v 2.639686 1.760016 -0.283910
-v 2.639686 1.760016 0.283910
-v 2.648521 2.296134 0.125510
-v 2.648521 2.296134 -0.125510
-v 2.649900 1.972725 0.253920
-v 2.649900 1.972725 -0.253920
-v 2.656300 1.480800 -0.218400
-v 2.656300 1.480800 0.218400
-v 2.667347 2.150664 -0.210701
-v 2.667347 2.150664 0.210701
-v 2.679100 1.453725 0.122850
-v 2.679100 1.453725 -0.122850
-v 2.682771 1.724928 0.248422
-v 2.682771 1.724928 -0.248422
-v 2.687500 1.443750 0.000000
-v 2.687500 1.443750 0.000000
-v 2.700000 2.400000 0.000000
-v 2.700000 2.400000 0.000000
-v 2.700000 2.400000 0.000000
-v 2.700871 1.947750 -0.243763
-v 2.700871 1.947750 0.243763
-v 2.701743 2.292186 0.164732
-v 2.701743 2.292186 -0.164732
-v 2.716800 2.400000 0.067500
-v 2.716800 2.400000 -0.067500
-v 2.716800 2.400000 -0.067500
-v 2.716800 2.400000 0.067500
-v 2.718253 1.696032 0.189274
-v 2.718253 1.696032 -0.189274
-v 2.725600 2.136900 -0.219480
-v 2.725600 2.136900 0.219480
-v 2.729800 2.420250 0.000000
-v 2.742330 1.676424 0.106466
-v 2.742330 1.676424 -0.106466
-v 2.747407 2.420406 -0.066744
-v 2.747407 2.420406 0.066744
-v 2.747710 1.924800 -0.213293
-v 2.747710 1.924800 0.213293
-v 2.751200 1.669200 0.000000
-v 2.751200 1.669200 0.000000
-v 2.758400 2.436000 0.000000
-v 2.762400 2.400000 0.120000
-v 2.762400 2.400000 -0.120000
-v 2.762400 2.400000 -0.120000
-v 2.762400 2.400000 0.120000
-v 2.766370 2.287392 0.188266
-v 2.766370 2.287392 -0.188266
-v 2.776365 2.436302 -0.064692
-v 2.776365 2.436302 0.064692
-v 2.783853 2.123136 -0.210701
-v 2.783853 2.123136 0.210701
-v 2.784600 2.447250 0.000000
-v 2.784600 2.447250 0.000000
-v 2.786282 1.905900 0.162509
-v 2.786282 1.905900 -0.162509
-v 2.795198 2.420829 -0.118656
-v 2.795198 2.420829 0.118656
-v 2.800000 2.400000 0.000000
-v 2.802528 2.447680 -0.061668
-v 2.802528 2.447680 0.061668
-v 2.807200 2.454000 0.000000
-v 2.811200 2.400000 -0.040500
-v 2.811200 2.400000 0.040500
-v 2.812457 1.893075 0.091411
-v 2.812457 1.893075 -0.091411
-v 2.822100 1.888350 0.000000
-v 2.822100 1.888350 0.000000
-v 2.824200 2.420250 0.000000
-v 2.824200 2.420250 0.000000
-v 2.824750 2.454529 -0.057996
-v 2.824750 2.454529 0.057996
-v 2.825000 2.456250 0.000000
-v 2.825000 2.456250 0.000000
-v 2.825126 2.437123 -0.115008
-v 2.825126 2.437123 0.115008
-v 2.829600 2.400000 0.157500
-v 2.829600 2.400000 -0.157500
-v 2.829600 2.400000 -0.157500
-v 2.829600 2.400000 0.157500
-v 2.836672 2.420519 -0.041256
-v 2.836672 2.420519 0.041256
-v 2.836700 2.282175 0.196110
-v 2.836700 2.282175 -0.196110
-v 2.836800 2.454000 0.000000
-v 2.836800 2.454000 0.000000
-v 2.837382 2.110488 -0.184363
-v 2.837382 2.110488 0.184363
-v 2.837600 2.436000 0.000000
-v 2.837600 2.436000 0.000000
-v 2.841400 2.447250 0.000000
-v 2.841400 2.447250 0.000000
-v 2.841600 2.400000 -0.072000
-v 2.841600 2.400000 0.072000
-v 2.841887 2.456841 -0.054000
-v 2.841887 2.456841 0.054000
-v 2.851189 2.448847 -0.109632
-v 2.851189 2.448847 0.109632
-v 2.851331 2.436454 -0.043308
-v 2.851331 2.436454 0.043308
-v 2.852794 2.454605 -0.050004
-v 2.852794 2.454605 0.050004
-v 2.856323 2.447812 -0.046332
-v 2.856323 2.447812 0.046332
-v 2.865626 2.421453 -0.155736
-v 2.865626 2.421453 0.155736
-v 2.870524 2.421250 -0.073344
-v 2.870524 2.421250 0.073344
-v 2.872387 2.455966 -0.103104
-v 2.872387 2.455966 0.103104
-v 2.881466 2.100072 -0.140467
-v 2.881466 2.100072 0.140467
-v 2.886400 2.400000 -0.094500
-v 2.886400 2.400000 0.094500
-v 2.887725 2.458444 -0.096000
-v 2.887725 2.458444 0.096000
-v 2.888602 2.437685 -0.076992
-v 2.888602 2.437685 0.076992
-v 2.896205 2.456246 0.088896
-v 2.896205 2.456246 -0.088896
-v 2.896829 2.449338 -0.082368
-v 2.896829 2.449338 0.082368
-v 2.896986 2.438333 -0.150948
-v 2.896986 2.438333 0.150948
-v 2.907030 2.276958 0.188266
-v 2.907030 2.276958 -0.188266
-v 2.911200 2.400000 -0.180000
-v 2.911200 2.400000 -0.180000
-v 2.911200 2.400000 0.180000
-v 2.911379 2.093004 -0.079013
-v 2.911379 2.093004 0.079013
-v 2.920412 2.422328 -0.096264
-v 2.920412 2.422328 0.096264
-v 2.922400 2.090400 0.000000
-v 2.922899 2.450567 -0.143892
-v 2.922899 2.450567 0.143892
-v 2.940800 2.400000 -0.108000
-v 2.940800 2.400000 0.108000
-v 2.942589 2.458082 -0.135324
-v 2.942589 2.458082 0.135324
-v 2.943526 2.439499 -0.101052
-v 2.943526 2.439499 0.101052
-v 2.951146 2.422210 -0.177984
-v 2.951146 2.422210 0.177984
-v 2.955275 2.460806 -0.126000
-v 2.955275 2.460806 0.126000
-v 2.956523 2.451588 -0.108108
-v 2.956523 2.451588 0.108108
-v 2.960179 2.458666 -0.116676
-v 2.960179 2.458666 0.116676
-v 2.971657 2.272164 0.164732
-v 2.971657 2.272164 -0.164732
-v 2.980990 2.423636 0.110016
-v 2.980990 2.423636 -0.110016
-v 2.984243 2.439802 -0.172512
-v 2.984243 2.439802 0.172512
-v 3.000000 2.400000 -0.187500
-v 3.000000 2.400000 -0.187500
-v 3.000000 2.400000 -0.112500
-v 3.000000 2.400000 0.112500
-v 3.000000 2.400000 0.187500
-v 3.009977 2.452655 -0.164448
-v 3.009977 2.452655 0.164448
-v 3.010221 2.441702 -0.115488
-v 3.010221 2.441702 0.115488
-v 3.024879 2.268216 0.125510
-v 3.024879 2.268216 -0.125510
-v 3.027834 2.460653 -0.154656
-v 3.027834 2.460653 0.154656
-v 3.029007 2.454319 -0.123552
-v 3.029007 2.454319 0.123552
-v 3.037300 2.463675 -0.144000
-v 3.037300 2.463675 0.144000
-v 3.037862 2.461603 0.133344
-v 3.037862 2.461603 -0.133344
-v 3.044212 2.423034 -0.185400
-v 3.044212 2.423034 0.185400
-v 3.046912 2.425059 0.114600
-v 3.046912 2.425059 -0.114600
-v 3.059200 2.400000 -0.108000
-v 3.059200 2.400000 0.108000
-v 3.060994 2.265537 0.070600
-v 3.060994 2.265537 -0.070600
-v 3.074300 2.264550 0.000000
-v 3.074300 2.264550 0.000000
-v 3.079200 2.441400 -0.179700
-v 3.079200 2.441400 0.179700
-v 3.082800 2.444100 -0.120300
-v 3.082800 2.444100 0.120300
-v 3.088800 2.400000 -0.180000
-v 3.088800 2.400000 -0.180000
-v 3.088800 2.400000 0.180000
-v 3.104737 2.454928 -0.171300
-v 3.104738 2.454928 0.171300
-v 3.107887 2.457291 -0.128700
-v 3.107887 2.457291 0.128700
-v 3.112835 2.426483 0.110016
-v 3.112835 2.426483 -0.110016
-v 3.113600 2.400000 -0.094500
-v 3.113600 2.400000 0.094500
-v 3.120600 2.463450 0.161100
-v 3.120600 2.463450 -0.161100
-v 3.122400 2.464800 0.138900
-v 3.122400 2.464800 -0.138900
-v 3.126562 2.466797 -0.150000
-v 3.126562 2.466797 0.150000
-v 3.137279 2.423859 -0.177984
-v 3.137279 2.423859 0.177984
-v 3.155379 2.446498 -0.115488
-v 3.155379 2.446498 0.115488
-v 3.158400 2.400000 -0.072000
-v 3.158400 2.400000 0.072000
-v 3.170400 2.400000 -0.157500
-v 3.170400 2.400000 0.157500
-v 3.170400 2.400000 -0.157500
-v 3.173413 2.427791 -0.096264
-v 3.173413 2.427791 0.096264
-v 3.174157 2.442998 -0.172512
-v 3.174157 2.442998 0.172512
-v 3.186768 2.460263 -0.123552
-v 3.186768 2.460263 0.123552
-v 3.188800 2.400000 -0.040500
-v 3.188800 2.400000 0.040500
-v 3.199498 2.457201 -0.164448
-v 3.199498 2.457201 0.164448
-v 3.200000 2.400000 0.000000
-v 3.206938 2.467997 0.133344
-v 3.206938 2.467997 -0.133344
-v 3.213366 2.466247 -0.154656
-v 3.213366 2.466247 0.154656
-v 3.215825 2.469919 -0.144000
-v 3.215825 2.469919 0.144000
-v 3.222074 2.448701 -0.101052
-v 3.222074 2.448701 0.101052
-v 3.222799 2.424616 -0.155736
-v 3.222799 2.424616 0.155736
-v 3.223301 2.428868 -0.073344
-v 3.223301 2.428868 0.073344
-v 3.237600 2.400000 -0.120000
-v 3.237600 2.400000 0.120000
-v 3.237600 2.400000 -0.120000
-v 3.257153 2.429599 -0.041256
-v 3.257153 2.429599 0.041256
-v 3.259252 2.462994 -0.108108
-v 3.259252 2.462994 0.108108
-v 3.261414 2.444467 -0.150948
-v 3.261414 2.444467 0.150948
-v 3.269625 2.429869 0.000000
-v 3.269625 2.429869 0.000000
-v 3.276998 2.450515 -0.076992
-v 3.276998 2.450515 0.076992
-v 3.283200 2.400000 -0.067500
-v 3.283200 2.400000 0.067500
-v 3.283200 2.400000 -0.067500
-v 3.284621 2.470934 -0.116676
-v 3.284621 2.470934 0.116676
-v 3.286576 2.459289 -0.143892
-v 3.286576 2.459289 0.143892
-v 3.293227 2.425240 -0.118656
-v 3.293227 2.425240 0.118656
-v 3.297850 2.472787 -0.126000
-v 3.297850 2.472788 0.126000
-v 3.298611 2.468818 -0.135324
-v 3.298611 2.468818 0.135324
-v 3.300000 2.400000 0.000000
-v 3.300000 2.400000 0.000000
-v 3.314269 2.451746 -0.043308
-v 3.314269 2.451746 0.043308
-v 3.318946 2.465243 -0.082368
-v 3.318946 2.465243 0.082368
-v 3.328000 2.452200 0.000000
-v 3.328000 2.452200 0.000000
-v 3.333274 2.445677 -0.115008
-v 3.333274 2.445677 0.115008
-v 3.341018 2.425663 -0.066744
-v 3.341018 2.425663 0.066744
-v 3.348595 2.473354 0.088896
-v 3.348595 2.473354 -0.088896
-v 3.358286 2.461009 -0.109632
-v 3.358286 2.461009 0.109632
-v 3.358625 2.425819 0.000000
-v 3.359452 2.466769 -0.046332
-v 3.359452 2.466769 0.046332
-v 3.365400 2.475150 -0.096000
-v 3.365400 2.475150 0.096000
-v 3.368813 2.470934 -0.103104
-v 3.368813 2.470934 0.103104
-v 3.374375 2.467331 0.000000
-v 3.374375 2.467331 0.000000
-v 3.382035 2.446498 -0.064692
-v 3.382035 2.446498 0.064692
-v 3.392006 2.474995 -0.050004
-v 3.392006 2.474995 0.050004
-v 3.400000 2.446800 0.000000
-v 3.406947 2.462176 -0.061668
-v 3.406947 2.462176 0.061668
-v 3.408000 2.475600 0.000000
-v 3.408000 2.475600 0.000000
-v 3.411237 2.476753 -0.054000
-v 3.411237 2.476753 0.054000
-v 3.416450 2.472371 -0.057996
-v 3.416450 2.472371 0.057996
-v 3.424875 2.462606 0.000000
-v 3.428125 2.477344 0.000000
-v 3.428125 2.477344 0.000000
-v 3.434000 2.472900 0.000000
-
-f 2909 2921 2939
-f 2939 2931 2909
-f 2869 2877 2921
-f 2921 2909 2869
-f 2819 2827 2877
-f 2877 2869 2819
-f 2737 2747 2827
-f 2827 2819 2737
-f 2669 2673 2747
-f 2747 2737 2669
-f 2567 2575 2673
-f 2673 2669 2567
-f 2476 2480 2575
-f 2575 2567 2476
-f 2358 2362 2480
-f 2480 2476 2358
-f 2158 2162 2362
-f 2362 2358 2158
-f 1715 1812 2162
-f 2162 2158 1715
-f 2901 2909 2931
-f 2931 2917 2901
-f 2863 2869 2909
-f 2909 2901 2863
-f 2813 2819 2869
-f 2869 2863 2813
-f 2729 2737 2819
-f 2819 2813 2729
-f 2663 2669 2737
-f 2737 2729 2663
-f 2561 2567 2669
-f 2669 2663 2561
-f 2468 2476 2567
-f 2567 2561 2468
-f 2350 2358 2476
-f 2476 2468 2350
-f 2152 2158 2358
-f 2358 2350 2152
-f 1717 1715 2158
-f 2158 2152 1717
-f 2903 2901 2917
-f 2917 2923 2903
-f 2865 2863 2901
-f 2901 2903 2865
-f 2815 2813 2863
-f 2863 2865 2815
-f 2733 2729 2813
-f 2813 2815 2733
-f 2665 2663 2729
-f 2729 2733 2665
-f 2564 2561 2663
-f 2663 2665 2564
-f 2473 2468 2561
-f 2561 2564 2473
-f 2354 2350 2468
-f 2468 2473 2354
-f 2155 2152 2350
-f 2350 2354 2155
-f 1927 1717 2152
-f 2152 2155 1927
-f 2911 2903 2923
-f 2923 2935 2911
-f 2875 2865 2903
-f 2903 2911 2875
-f 2823 2815 2865
-f 2865 2875 2823
-f 2741 2733 2815
-f 2815 2823 2741
-f 2671 2665 2733
-f 2733 2741 2671
-f 2571 2564 2665
-f 2665 2671 2571
-f 2478 2473 2564
-f 2564 2571 2478
-f 2360 2354 2473
-f 2473 2478 2360
-f 2160 2155 2354
-f 2354 2360 2160
-f 1718 1927 2155
-f 2155 2160 1718
-f 2929 2911 2935
-f 2935 2947 2929
-f 2881 2875 2911
-f 2911 2929 2881
-f 2829 2823 2875
-f 2875 2881 2829
-f 2751 2741 2823
-f 2823 2829 2751
-f 2677 2671 2741
-f 2741 2751 2677
-f 2577 2571 2671
-f 2671 2677 2577
-f 2482 2478 2571
-f 2571 2577 2482
-f 2364 2360 2478
-f 2478 2482 2364
-f 2164 2160 2360
-f 2360 2364 2164
-f 1842 1718 2160
-f 2160 2164 1842
-f 2945 2929 2947
-f 2947 2959 2945
-f 2897 2881 2929
-f 2929 2945 2897
-f 2835 2829 2881
-f 2881 2897 2835
-f 2761 2751 2829
-f 2829 2835 2761
-f 2679 2677 2751
-f 2751 2761 2679
-f 2579 2577 2677
-f 2677 2679 2579
-f 2486 2482 2577
-f 2577 2579 2486
-f 2368 2364 2482
-f 2482 2486 2368
-f 2172 2164 2364
-f 2364 2368 2172
-f 1725 1842 2164
-f 2164 2172 1725
-f 2965 2945 2959
-f 2959 2981 2965
-f 2907 2897 2945
-f 2945 2965 2907
-f 2845 2835 2897
-f 2897 2907 2845
-f 2769 2761 2835
-f 2835 2845 2769
-f 2685 2679 2761
-f 2761 2769 2685
-f 2587 2579 2679
-f 2679 2685 2587
-f 2491 2486 2579
-f 2579 2587 2491
-f 2370 2368 2486
-f 2486 2491 2370
-f 2174 2172 2368
-f 2368 2370 2174
-f 1834 1725 2172
-f 2172 2174 1834
-f 2982 2965 2981
-f 2981 2988 2982
-f 2933 2907 2965
-f 2965 2982 2933
-f 2855 2845 2907
-f 2907 2933 2855
-f 2779 2769 2845
-f 2845 2855 2779
-f 2691 2685 2769
-f 2769 2779 2691
-f 2595 2587 2685
-f 2685 2691 2595
-f 2500 2491 2587
-f 2587 2595 2500
-f 2374 2370 2491
-f 2491 2500 2374
-f 2178 2174 2370
-f 2370 2374 2178
-f 1716 1834 2174
-f 2174 2178 1716
-f 2990 2982 2988
-f 2988 3002 2990
-f 2949 2933 2982
-f 2982 2990 2949
-f 2871 2855 2933
-f 2933 2949 2871
-f 2791 2779 2855
-f 2855 2871 2791
-f 2699 2691 2779
-f 2779 2791 2699
-f 2601 2595 2691
-f 2691 2699 2601
-f 2506 2500 2595
-f 2595 2601 2506
-f 2378 2374 2500
-f 2500 2506 2378
-f 2180 2178 2374
-f 2374 2378 2180
-f 1714 1716 2178
-f 2178 2180 1714
-f 3008 2990 3002
-f 3002 3024 3008
-f 2973 2949 2990
-f 2990 3008 2973
-f 2889 2871 2949
-f 2949 2973 2889
-f 2805 2791 2871
-f 2871 2889 2805
-f 2711 2699 2791
-f 2791 2805 2711
-f 2611 2601 2699
-f 2699 2711 2611
-f 2521 2506 2601
-f 2601 2611 2521
-f 2387 2378 2506
-f 2506 2521 2387
-f 2191 2180 2378
-f 2378 2387 2191
-f 1810 1714 2180
-f 2180 2191 1810
-f 1464 1460 1813
-f 1813 1821 1464
-f 1264 1260 1460
-f 1460 1464 1264
-f 1146 1142 1260
-f 1260 1264 1146
-f 1055 1047 1142
-f 1142 1146 1055
-f 953 949 1047
-f 1047 1055 953
-f 885 875 949
-f 949 953 885
-f 803 795 875
-f 875 885 803
-f 753 745 795
-f 795 803 753
-f 713 701 745
-f 745 753 713
-f 691 683 701
-f 701 713 691
-f 1470 1464 1821
-f 1821 1829 1470
-f 1272 1264 1464
-f 1464 1470 1272
-f 1154 1146 1264
-f 1264 1272 1154
-f 1061 1055 1146
-f 1146 1154 1061
-f 959 953 1055
-f 1055 1061 959
-f 893 885 953
-f 953 959 893
-f 809 803 885
-f 885 893 809
-f 759 753 803
-f 803 809 759
-f 721 713 753
-f 753 759 721
-f 705 691 713
-f 713 721 705
-f 1469 1470 1829
-f 1829 1835 1469
-f 1268 1272 1470
-f 1470 1469 1268
-f 1151 1154 1272
-f 1272 1268 1151
-f 1060 1061 1154
-f 1154 1151 1060
-f 957 959 1061
-f 1061 1060 957
-f 889 893 959
-f 959 957 889
-f 807 809 893
-f 893 889 807
-f 757 759 809
-f 809 807 757
-f 719 721 759
-f 759 757 719
-f 699 705 721
-f 721 719 699
-f 1462 1469 1835
-f 1835 1839 1462
-f 1262 1268 1469
-f 1469 1462 1262
-f 1144 1151 1268
-f 1268 1262 1144
-f 1051 1060 1151
-f 1151 1144 1051
-f 951 957 1060
-f 1060 1051 951
-f 881 889 957
-f 957 951 881
-f 799 807 889
-f 889 881 799
-f 747 757 807
-f 807 799 747
-f 711 719 757
-f 757 747 711
-f 687 699 719
-f 719 711 687
-f 1458 1462 1839
-f 1839 1843 1458
-f 1258 1262 1462
-f 1462 1458 1258
-f 1140 1144 1262
-f 1262 1258 1140
-f 1045 1051 1144
-f 1144 1140 1045
-f 945 951 1051
-f 1051 1045 945
-f 871 881 951
-f 951 945 871
-f 793 799 881
-f 881 871 793
-f 741 747 799
-f 799 793 741
-f 693 711 747
-f 747 741 693
-f 675 687 711
-f 711 693 675
-f 1450 1458 1843
-f 1843 1838 1450
-f 1254 1258 1458
-f 1458 1450 1254
-f 1136 1140 1258
-f 1258 1254 1136
-f 1043 1045 1140
-f 1140 1136 1043
-f 943 945 1045
-f 1045 1043 943
-f 861 871 945
-f 945 943 861
-f 787 793 871
-f 871 861 787
-f 725 741 793
-f 793 787 725
-f 677 693 741
-f 741 725 677
-f 663 675 693
-f 693 677 663
-f 1448 1450 1838
-f 1838 1834 1448
-f 1252 1254 1450
-f 1450 1448 1252
-f 1133 1136 1254
-f 1254 1252 1133
-f 1035 1043 1136
-f 1136 1133 1035
-f 937 943 1043
-f 1043 1035 937
-f 853 861 943
-f 943 937 853
-f 777 787 861
-f 861 853 777
-f 715 725 787
-f 787 777 715
-f 657 677 725
-f 725 715 657
-f 642 663 677
-f 677 657 642
-f 1444 1448 1834
-f 1834 1828 1444
-f 1248 1252 1448
-f 1448 1444 1248
-f 1122 1133 1252
-f 1252 1248 1122
-f 1027 1035 1133
-f 1133 1122 1027
-f 931 937 1035
-f 1035 1027 931
-f 843 853 937
-f 937 931 843
-f 767 777 853
-f 853 843 767
-f 689 715 777
-f 777 767 689
-f 640 657 715
-f 715 689 640
-f 634 642 657
-f 657 640 634
-f 1442 1444 1828
-f 1828 1820 1442
-f 1244 1248 1444
-f 1444 1442 1244
-f 1116 1122 1248
-f 1248 1244 1116
-f 1021 1027 1122
-f 1122 1116 1021
-f 923 931 1027
-f 1027 1021 923
-f 831 843 931
-f 931 923 831
-f 751 767 843
-f 843 831 751
-f 673 689 767
-f 767 751 673
-f 632 640 689
-f 689 673 632
-f 620 634 640
-f 640 632 620
-f 1429 1442 1820
-f 1820 1811 1429
-f 1233 1244 1442
-f 1442 1429 1233
-f 1106 1116 1244
-f 1244 1233 1106
-f 1011 1021 1116
-f 1116 1106 1011
-f 911 923 1021
-f 1021 1011 911
-f 817 831 923
-f 923 911 817
-f 733 751 831
-f 831 817 733
-f 649 673 751
-f 751 733 649
-f 614 632 673
-f 673 649 614
-f 597 620 632
-f 632 614 597
-f 714 702 684
-f 684 692 714
-f 754 746 702
-f 702 714 754
-f 804 796 746
-f 746 754 804
-f 886 876 796
-f 796 804 886
-f 954 950 876
-f 876 886 954
-f 1056 1048 950
-f 950 954 1056
-f 1147 1143 1048
-f 1048 1056 1147
-f 1265 1261 1143
-f 1143 1147 1265
-f 1465 1461 1261
-f 1261 1265 1465
-f 1915 1817 1461
-f 1461 1465 1915
-f 722 714 692
-f 692 706 722
-f 760 754 714
-f 714 722 760
-f 810 804 754
-f 754 760 810
-f 894 886 804
-f 804 810 894
-f 960 954 886
-f 886 894 960
-f 1062 1056 954
-f 954 960 1062
-f 1155 1147 1056
-f 1056 1062 1155
-f 1273 1265 1147
-f 1147 1155 1273
-f 1471 1465 1265
-f 1265 1273 1471
-f 1917 1915 1465
-f 1465 1471 1917
-f 720 722 706
-f 706 700 720
-f 758 760 722
-f 722 720 758
-f 808 810 760
-f 760 758 808
-f 890 894 810
-f 810 808 890
-f 958 960 894
-f 894 890 958
-f 1059 1062 960
-f 960 958 1059
-f 1150 1155 1062
-f 1062 1059 1150
-f 1269 1273 1155
-f 1155 1150 1269
-f 1468 1471 1273
-f 1273 1269 1468
-f 1697 1917 1471
-f 1471 1468 1697
-f 712 720 700
-f 700 688 712
-f 748 758 720
-f 720 712 748
-f 800 808 758
-f 758 748 800
-f 882 890 808
-f 808 800 882
-f 952 958 890
-f 890 882 952
-f 1052 1059 958
-f 958 952 1052
-f 1145 1150 1059
-f 1059 1052 1145
-f 1263 1269 1150
-f 1150 1145 1263
-f 1463 1468 1269
-f 1269 1263 1463
-f 1919 1697 1468
-f 1468 1463 1919
-f 694 712 688
-f 688 676 694
-f 742 748 712
-f 712 694 742
-f 794 800 748
-f 748 742 794
-f 872 882 800
-f 800 794 872
-f 946 952 882
-f 882 872 946
-f 1046 1052 952
-f 952 946 1046
-f 1141 1145 1052
-f 1052 1046 1141
-f 1259 1263 1145
-f 1145 1141 1259
-f 1459 1463 1263
-f 1263 1259 1459
-f 1845 1919 1463
-f 1463 1459 1845
-f 678 694 676
-f 676 664 678
-f 726 742 694
-f 694 678 726
-f 788 794 742
-f 742 726 788
-f 862 872 794
-f 794 788 862
-f 944 946 872
-f 872 862 944
-f 1044 1046 946
-f 946 944 1044
-f 1137 1141 1046
-f 1046 1044 1137
-f 1255 1259 1141
-f 1141 1137 1255
-f 1451 1459 1259
-f 1259 1255 1451
-f 1898 1845 1459
-f 1459 1451 1898
-f 658 678 664
-f 664 642 658
-f 716 726 678
-f 678 658 716
-f 778 788 726
-f 726 716 778
-f 854 862 788
-f 788 778 854
-f 938 944 862
-f 862 854 938
-f 1036 1044 944
-f 944 938 1036
-f 1132 1137 1044
-f 1044 1036 1132
-f 1253 1255 1137
-f 1137 1132 1253
-f 1449 1451 1255
-f 1255 1253 1449
-f 1837 1898 1451
-f 1451 1449 1837
-f 641 658 642
-f 642 635 641
-f 690 716 658
-f 658 641 690
-f 768 778 716
-f 716 690 768
-f 844 854 778
-f 778 768 844
-f 932 938 854
-f 854 844 932
-f 1028 1036 938
-f 938 932 1028
-f 1123 1132 1036
-f 1036 1028 1123
-f 1249 1253 1132
-f 1132 1123 1249
-f 1445 1449 1253
-f 1253 1249 1445
-f 1918 1837 1449
-f 1449 1445 1918
-f 633 641 635
-f 635 621 633
-f 674 690 641
-f 641 633 674
-f 752 768 690
-f 690 674 752
-f 832 844 768
-f 768 752 832
-f 924 932 844
-f 844 832 924
-f 1022 1028 932
-f 932 924 1022
-f 1117 1123 1028
-f 1028 1022 1117
-f 1245 1249 1123
-f 1123 1117 1245
-f 1443 1445 1249
-f 1249 1245 1443
-f 1916 1918 1445
-f 1445 1443 1916
-f 616 633 621
-f 621 600 616
-f 654 674 633
-f 633 616 654
-f 737 752 674
-f 674 654 737
-f 822 832 752
-f 752 737 822
-f 914 924 832
-f 832 822 914
-f 1014 1022 924
-f 924 914 1014
-f 1104 1117 1022
-f 1022 1014 1104
-f 1237 1245 1117
-f 1117 1104 1237
-f 1433 1443 1245
-f 1245 1237 1433
-f 1819 1916 1443
-f 1443 1433 1819
-f 2159 2163 1816
-f 1816 1822 2159
-f 2359 2363 2163
-f 2163 2159 2359
-f 2477 2481 2363
-f 2363 2359 2477
-f 2568 2576 2481
-f 2481 2477 2568
-f 2670 2674 2576
-f 2576 2568 2670
-f 2738 2748 2674
-f 2674 2670 2738
-f 2820 2828 2748
-f 2748 2738 2820
-f 2870 2878 2828
-f 2828 2820 2870
-f 2910 2922 2878
-f 2878 2870 2910
-f 2932 2940 2922
-f 2922 2910 2932
-f 2153 2159 1822
-f 1822 1830 2153
-f 2351 2359 2159
-f 2159 2153 2351
-f 2469 2477 2359
-f 2359 2351 2469
-f 2562 2568 2477
-f 2477 2469 2562
-f 2664 2670 2568
-f 2568 2562 2664
-f 2730 2738 2670
-f 2670 2664 2730
-f 2814 2820 2738
-f 2738 2730 2814
-f 2864 2870 2820
-f 2820 2814 2864
-f 2902 2910 2870
-f 2870 2864 2902
-f 2918 2932 2910
-f 2910 2902 2918
-f 2154 2153 1830
-f 1830 1836 2154
-f 2355 2351 2153
-f 2153 2154 2355
-f 2472 2469 2351
-f 2351 2355 2472
-f 2563 2562 2469
-f 2469 2472 2563
-f 2666 2664 2562
-f 2562 2563 2666
-f 2734 2730 2664
-f 2664 2666 2734
-f 2816 2814 2730
-f 2730 2734 2816
-f 2866 2864 2814
-f 2814 2816 2866
-f 2904 2902 2864
-f 2864 2866 2904
-f 2924 2918 2902
-f 2902 2904 2924
-f 2161 2154 1836
-f 1836 1840 2161
-f 2361 2355 2154
-f 2154 2161 2361
-f 2479 2472 2355
-f 2355 2361 2479
-f 2572 2563 2472
-f 2472 2479 2572
-f 2672 2666 2563
-f 2563 2572 2672
-f 2742 2734 2666
-f 2666 2672 2742
-f 2824 2816 2734
-f 2734 2742 2824
-f 2876 2866 2816
-f 2816 2824 2876
-f 2912 2904 2866
-f 2866 2876 2912
-f 2936 2924 2904
-f 2904 2912 2936
-f 2165 2161 1840
-f 1840 1844 2165
-f 2365 2361 2161
-f 2161 2165 2365
-f 2483 2479 2361
-f 2361 2365 2483
-f 2578 2572 2479
-f 2479 2483 2578
-f 2678 2672 2572
-f 2572 2578 2678
-f 2752 2742 2672
-f 2672 2678 2752
-f 2830 2824 2742
-f 2742 2752 2830
-f 2882 2876 2824
-f 2824 2830 2882
-f 2930 2912 2876
-f 2876 2882 2930
-f 2948 2936 2912
-f 2912 2930 2948
-f 2173 2165 1844
-f 1844 1841 2173
-f 2369 2365 2165
-f 2165 2173 2369
-f 2487 2483 2365
-f 2365 2369 2487
-f 2580 2578 2483
-f 2483 2487 2580
-f 2680 2678 2578
-f 2578 2580 2680
-f 2762 2752 2678
-f 2678 2680 2762
-f 2836 2830 2752
-f 2752 2762 2836
-f 2898 2882 2830
-f 2830 2836 2898
-f 2946 2930 2882
-f 2882 2898 2946
-f 2960 2948 2930
-f 2930 2946 2960
-f 2175 2173 1841
-f 1841 1837 2175
-f 2371 2369 2173
-f 2173 2175 2371
-f 2490 2487 2369
-f 2369 2371 2490
-f 2588 2580 2487
-f 2487 2490 2588
-f 2686 2680 2580
-f 2580 2588 2686
-f 2770 2762 2680
-f 2680 2686 2770
-f 2846 2836 2762
-f 2762 2770 2846
-f 2908 2898 2836
-f 2836 2846 2908
-f 2966 2946 2898
-f 2898 2908 2966
-f 2981 2960 2946
-f 2946 2966 2981
-f 2179 2175 1837
-f 1837 1831 2179
-f 2375 2371 2175
-f 2175 2179 2375
-f 2501 2490 2371
-f 2371 2375 2501
-f 2596 2588 2490
-f 2490 2501 2596
-f 2692 2686 2588
-f 2588 2596 2692
-f 2780 2770 2686
-f 2686 2692 2780
-f 2856 2846 2770
-f 2770 2780 2856
-f 2934 2908 2846
-f 2846 2856 2934
-f 2983 2966 2908
-f 2908 2934 2983
-f 2989 2981 2966
-f 2966 2983 2989
-f 2181 2179 1831
-f 1831 1823 2181
-f 2379 2375 2179
-f 2179 2181 2379
-f 2507 2501 2375
-f 2375 2379 2507
-f 2602 2596 2501
-f 2501 2507 2602
-f 2700 2692 2596
-f 2596 2602 2700
-f 2792 2780 2692
-f 2692 2700 2792
-f 2872 2856 2780
-f 2780 2792 2872
-f 2950 2934 2856
-f 2856 2872 2950
-f 2991 2983 2934
-f 2934 2950 2991
-f 3003 2989 2983
-f 2983 2991 3003
-f 2194 2181 1823
-f 1823 1818 2194
-f 2391 2379 2181
-f 2181 2194 2391
-f 2518 2507 2379
-f 2379 2391 2518
-f 2614 2602 2507
-f 2507 2518 2614
-f 2712 2700 2602
-f 2602 2614 2712
-f 2806 2792 2700
-f 2700 2712 2806
-f 2890 2872 2792
-f 2792 2806 2890
-f 2974 2950 2872
-f 2872 2890 2974
-f 3009 2991 2950
-f 2950 2974 3009
-f 3025 3003 2991
-f 2991 3009 3025
-f 3040 3008 3024
-f 3024 3048 3040
-f 3018 2973 3008
-f 3008 3040 3018
-f 2943 2889 2973
-f 2973 3018 2943
-f 2841 2805 2889
-f 2889 2943 2841
-f 2731 2711 2805
-f 2805 2841 2731
-f 2645 2611 2711
-f 2711 2731 2645
-f 2529 2521 2611
-f 2611 2645 2529
-f 2402 2387 2521
-f 2521 2529 2402
-f 2208 2191 2387
-f 2387 2402 2208
-f 1806 1810 2191
-f 2191 2208 1806
-f 3072 3040 3048
-f 3048 3078 3072
-f 3044 3018 3040
-f 3040 3072 3044
-f 2994 2943 3018
-f 3018 3044 2994
-f 2883 2841 2943
-f 2943 2994 2883
-f 2773 2731 2841
-f 2841 2883 2773
-f 2659 2645 2731
-f 2731 2773 2659
-f 2539 2529 2645
-f 2645 2659 2539
-f 2410 2402 2529
-f 2529 2539 2410
-f 2222 2208 2402
-f 2402 2410 2222
-f 1694 1806 2208
-f 2208 2222 1694
-f 3092 3072 3078
-f 3078 3116 3092
-f 3074 3044 3072
-f 3072 3092 3074
-f 3030 2994 3044
-f 3044 3074 3030
-f 2937 2883 2994
-f 2994 3030 2937
-f 2810 2773 2883
-f 2883 2937 2810
-f 2683 2659 2773
-f 2773 2810 2683
-f 2554 2539 2659
-f 2659 2683 2554
-f 2420 2410 2539
-f 2539 2554 2420
-f 2238 2222 2410
-f 2410 2420 2238
-f 1930 1694 2222
-f 2222 2238 1930
-f 3132 3092 3116
-f 3116 3142 3132
-f 3090 3074 3092
-f 3092 3132 3090
-f 3054 3030 3074
-f 3074 3090 3054
-f 2984 2937 3030
-f 3030 3054 2984
-f 2837 2810 2937
-f 2937 2984 2837
-f 2705 2683 2810
-f 2810 2837 2705
-f 2574 2554 2683
-f 2683 2705 2574
-f 2430 2420 2554
-f 2554 2574 2430
-f 2247 2238 2420
-f 2420 2430 2247
-f 1913 1930 2238
-f 2238 2247 1913
-f 3150 3132 3142
-f 3142 3156 3150
-f 3128 3090 3132
-f 3132 3150 3128
-f 3076 3054 3090
-f 3090 3128 3076
-f 3014 2984 3054
-f 3054 3076 3014
-f 2861 2837 2984
-f 2984 3014 2861
-f 2723 2705 2837
-f 2837 2861 2723
-f 2585 2574 2705
-f 2705 2723 2585
-f 2438 2430 2574
-f 2574 2585 2438
-f 2253 2247 2430
-f 2430 2438 2253
-f 1711 1913 2247
-f 2247 2253 1711
-f 3162 3150 3156
-f 3156 3172 3162
-f 3148 3128 3150
-f 3150 3162 3148
-f 3088 3076 3128
-f 3128 3148 3088
-f 3036 3014 3076
-f 3076 3088 3036
-f 2893 2861 3014
-f 3014 3036 2893
-f 2743 2723 2861
-f 2861 2893 2743
-f 2599 2585 2723
-f 2723 2743 2599
-f 2450 2438 2585
-f 2585 2599 2450
-f 2267 2253 2438
-f 2438 2450 2267
-f 1794 1711 2253
-f 2253 2267 1794
-f 3178 3162 3172
-f 3172 3184 3178
-f 3154 3148 3162
-f 3162 3178 3154
-f 3118 3088 3148
-f 3148 3154 3118
-f 3046 3036 3088
-f 3088 3118 3046
-f 2915 2893 3036
-f 3036 3046 2915
-f 2763 2743 2893
-f 2893 2915 2763
-f 2615 2599 2743
-f 2743 2763 2615
-f 2452 2450 2599
-f 2599 2615 2452
-f 2277 2267 2450
-f 2450 2452 2277
-f 1710 1794 2267
-f 2267 2277 1710
-f 3188 3178 3184
-f 3184 3200 3188
-f 3164 3154 3178
-f 3178 3188 3164
-f 3130 3118 3154
-f 3154 3164 3130
-f 3058 3046 3118
-f 3118 3130 3058
-f 2941 2915 3046
-f 3046 3058 2941
-f 2775 2763 2915
-f 2915 2941 2775
-f 2627 2615 2763
-f 2763 2775 2627
-f 2458 2452 2615
-f 2615 2627 2458
-f 2287 2277 2452
-f 2452 2458 2287
-f 1910 1710 2277
-f 2277 2287 1910
-f 3198 3188 3200
-f 3200 3209 3198
-f 3170 3164 3188
-f 3188 3198 3170
-f 3136 3130 3164
-f 3164 3170 3136
-f 3064 3058 3130
-f 3130 3136 3064
-f 2955 2941 3058
-f 3058 3064 2955
-f 2781 2775 2941
-f 2941 2955 2781
-f 2636 2627 2775
-f 2775 2781 2636
-f 2462 2458 2627
-f 2627 2636 2462
-f 2295 2287 2458
-f 2458 2462 2295
-f 1909 1910 2287
-f 2287 2295 1909
-f 3202 3198 3209
-f 3209 3213 3202
-f 3174 3170 3198
-f 3198 3202 3174
-f 3138 3136 3170
-f 3170 3174 3138
-f 3066 3064 3136
-f 3136 3138 3066
-f 2961 2955 3064
-f 3064 3066 2961
-f 2783 2781 2955
-f 2955 2961 2783
-f 2642 2636 2781
-f 2781 2783 2642
-f 2464 2462 2636
-f 2636 2642 2464
-f 2297 2295 2462
-f 2462 2464 2297
-f 1784 1909 2295
-f 2295 2297 1784
-f 1414 1429 1811
-f 1811 1807 1414
-f 1220 1233 1429
-f 1429 1414 1220
-f 1093 1106 1233
-f 1233 1220 1093
-f 977 1011 1106
-f 1106 1093 977
-f 891 911 1011
-f 1011 977 891
-f 781 817 911
-f 911 891 781
-f 679 733 817
-f 817 781 679
-f 604 649 733
-f 733 679 604
-f 571 614 649
-f 649 604 571
-f 561 597 614
-f 614 571 561
-f 1400 1414 1807
-f 1807 1804 1400
-f 1212 1220 1414
-f 1414 1400 1212
-f 1083 1093 1220
-f 1220 1212 1083
-f 963 977 1093
-f 1093 1083 963
-f 849 891 977
-f 977 963 849
-f 739 781 891
-f 891 849 739
-f 628 679 781
-f 781 739 628
-f 565 604 679
-f 679 628 565
-f 530 571 604
-f 604 565 530
-f 524 561 571
-f 571 530 524
-f 1386 1400 1804
-f 1804 1802 1386
-f 1202 1212 1400
-f 1400 1386 1202
-f 1070 1083 1212
-f 1212 1202 1070
-f 939 963 1083
-f 1083 1070 939
-f 814 849 963
-f 963 939 814
-f 685 739 849
-f 849 814 685
-f 585 628 739
-f 739 685 585
-f 528 565 628
-f 628 585 528
-f 510 530 565
-f 565 528 510
-f 508 524 530
-f 530 510 508
-f 1375 1386 1802
-f 1802 1800 1375
-f 1192 1202 1386
-f 1386 1375 1192
-f 1050 1070 1202
-f 1202 1192 1050
-f 917 939 1070
-f 1070 1050 917
-f 785 814 939
-f 939 917 785
-f 638 685 814
-f 814 785 638
-f 553 585 685
-f 685 638 553
-f 512 528 585
-f 585 553 512
-f 492 510 528
-f 528 512 492
-f 482 508 510
-f 510 492 482
-f 1369 1375 1800
-f 1800 1798 1369
-f 1184 1192 1375
-f 1375 1369 1184
-f 1037 1050 1192
-f 1192 1184 1037
-f 899 917 1050
-f 1050 1037 899
-f 761 785 917
-f 917 899 761
-f 608 638 785
-f 785 761 608
-f 526 553 638
-f 638 608 526
-f 496 512 553
-f 553 526 496
-f 454 492 512
-f 512 496 454
-f 448 482 492
-f 492 454 448
-f 1355 1369 1798
-f 1798 1795 1355
-f 1172 1184 1369
-f 1369 1355 1172
-f 1023 1037 1184
-f 1184 1172 1023
-f 879 899 1037
-f 1037 1023 879
-f 729 761 899
-f 899 879 729
-f 579 608 761
-f 761 729 579
-f 514 526 608
-f 608 579 514
-f 457 496 526
-f 526 514 457
-f 442 454 496
-f 496 457 442
-f 432 448 454
-f 454 442 432
-f 1345 1355 1795
-f 1795 1792 1345
-f 1170 1172 1355
-f 1355 1345 1170
-f 1007 1023 1172
-f 1172 1170 1007
-f 859 879 1023
-f 1023 1007 859
-f 707 729 879
-f 879 859 707
-f 563 579 729
-f 729 707 563
-f 506 514 579
-f 579 563 506
-f 450 457 514
-f 514 506 450
-f 420 442 457
-f 457 450 420
-f 412 432 442
-f 442 420 412
-f 1335 1345 1792
-f 1792 1790 1335
-f 1164 1170 1345
-f 1345 1335 1164
-f 995 1007 1170
-f 1170 1164 995
-f 847 859 1007
-f 1007 995 847
-f 681 707 859
-f 859 847 681
-f 547 563 707
-f 707 681 547
-f 494 506 563
-f 563 547 494
-f 440 450 506
-f 506 494 440
-f 410 420 450
-f 450 440 410
-f 398 412 420
-f 420 410 398
-f 1327 1335 1790
-f 1790 1788 1327
-f 1160 1164 1335
-f 1335 1327 1160
-f 988 995 1164
-f 1164 1160 988
-f 841 847 995
-f 995 988 841
-f 667 681 847
-f 847 841 667
-f 538 547 681
-f 681 667 538
-f 488 494 547
-f 547 538 488
-f 434 440 494
-f 494 488 434
-f 400 410 440
-f 440 434 400
-f 381 398 410
-f 410 400 381
-f 1324 1327 1788
-f 1788 1785 1324
-f 1156 1160 1327
-f 1327 1324 1156
-f 979 988 1160
-f 1160 1156 979
-f 837 841 988
-f 988 979 837
-f 659 667 841
-f 841 837 659
-f 534 538 667
-f 667 659 534
-f 484 488 538
-f 538 534 484
-f 428 434 488
-f 488 484 428
-f 395 400 434
-f 434 428 395
-f 374 381 400
-f 400 395 374
-f 572 616 600
-f 600 562 572
-f 605 654 616
-f 616 572 605
-f 680 737 654
-f 654 605 680
-f 782 822 737
-f 737 680 782
-f 892 914 822
-f 822 782 892
-f 978 1014 914
-f 914 892 978
-f 1094 1104 1014
-f 1014 978 1094
-f 1221 1237 1104
-f 1104 1094 1221
-f 1415 1433 1237
-f 1237 1221 1415
-f 1809 1819 1433
-f 1433 1415 1809
-f 531 572 562
-f 562 525 531
-f 566 605 572
-f 572 531 566
-f 629 680 605
-f 605 566 629
-f 740 782 680
-f 680 629 740
-f 850 892 782
-f 782 740 850
-f 964 978 892
-f 892 850 964
-f 1084 1094 978
-f 978 964 1084
-f 1213 1221 1094
-f 1094 1084 1213
-f 1401 1415 1221
-f 1221 1213 1401
-f 1931 1809 1415
-f 1415 1401 1931
-f 511 531 525
-f 525 509 511
-f 529 566 531
-f 531 511 529
-f 586 629 566
-f 566 529 586
-f 686 740 629
-f 629 586 686
-f 813 850 740
-f 740 686 813
-f 940 964 850
-f 850 813 940
-f 1069 1084 964
-f 964 940 1069
-f 1203 1213 1084
-f 1084 1069 1203
-f 1385 1401 1213
-f 1213 1203 1385
-f 1693 1931 1401
-f 1401 1385 1693
-f 493 511 509
-f 509 483 493
-f 513 529 511
-f 511 493 513
-f 554 586 529
-f 529 513 554
-f 639 686 586
-f 586 554 639
-f 786 813 686
-f 686 639 786
-f 918 940 813
-f 813 786 918
-f 1049 1069 940
-f 940 918 1049
-f 1193 1203 1069
-f 1069 1049 1193
-f 1376 1385 1203
-f 1203 1193 1376
-f 1712 1693 1385
-f 1385 1376 1712
-f 455 493 483
-f 483 449 455
-f 497 513 493
-f 493 455 497
-f 527 554 513
-f 513 497 527
-f 609 639 554
-f 554 527 609
-f 762 786 639
-f 639 609 762
-f 900 918 786
-f 786 762 900
-f 1038 1049 918
-f 918 900 1038
-f 1185 1193 1049
-f 1049 1038 1185
-f 1370 1376 1193
-f 1193 1185 1370
-f 1912 1712 1376
-f 1376 1370 1912
-f 443 455 449
-f 449 433 443
-f 458 497 455
-f 455 443 458
-f 515 527 497
-f 497 458 515
-f 580 609 527
-f 527 515 580
-f 730 762 609
-f 609 580 730
-f 880 900 762
-f 762 730 880
-f 1024 1038 900
-f 900 880 1024
-f 1173 1185 1038
-f 1038 1024 1173
-f 1356 1370 1185
-f 1185 1173 1356
-f 1797 1912 1370
-f 1370 1356 1797
-f 421 443 433
-f 433 413 421
-f 451 458 443
-f 443 421 451
-f 507 515 458
-f 458 451 507
-f 564 580 515
-f 515 507 564
-f 708 730 580
-f 580 564 708
-f 860 880 730
-f 730 708 860
-f 1008 1024 880
-f 880 860 1008
-f 1171 1173 1024
-f 1024 1008 1171
-f 1346 1356 1173
-f 1173 1171 1346
-f 1911 1797 1356
-f 1356 1346 1911
-f 411 421 413
-f 413 399 411
-f 441 451 421
-f 421 411 441
-f 495 507 451
-f 451 441 495
-f 548 564 507
-f 507 495 548
-f 682 708 564
-f 564 548 682
-f 848 860 708
-f 708 682 848
-f 996 1008 860
-f 860 848 996
-f 1165 1171 1008
-f 1008 996 1165
-f 1336 1346 1171
-f 1171 1165 1336
-f 1709 1911 1346
-f 1346 1336 1709
-f 401 411 399
-f 399 382 401
-f 435 441 411
-f 411 401 435
-f 489 495 441
-f 441 435 489
-f 539 548 495
-f 495 489 539
-f 668 682 548
-f 548 539 668
-f 842 848 682
-f 682 668 842
-f 987 996 848
-f 848 842 987
-f 1161 1165 996
-f 996 987 1161
-f 1328 1336 1165
-f 1165 1161 1328
-f 1708 1709 1336
-f 1336 1328 1708
-f 397 401 382
-f 382 376 397
-f 431 435 401
-f 401 397 431
-f 487 489 435
-f 435 431 487
-f 537 539 489
-f 489 487 537
-f 662 668 539
-f 539 537 662
-f 840 842 668
-f 668 662 840
-f 981 987 842
-f 842 840 981
-f 1159 1161 987
-f 987 981 1159
-f 1326 1328 1161
-f 1161 1159 1326
-f 1787 1708 1328
-f 1328 1326 1787
-f 2209 2194 1818
-f 1818 1808 2209
-f 2403 2391 2194
-f 2194 2209 2403
-f 2530 2518 2391
-f 2391 2403 2530
-f 2646 2614 2518
-f 2518 2530 2646
-f 2732 2712 2614
-f 2614 2646 2732
-f 2842 2806 2712
-f 2712 2732 2842
-f 2944 2890 2806
-f 2806 2842 2944
-f 3019 2974 2890
-f 2890 2944 3019
-f 3041 3009 2974
-f 2974 3019 3041
-f 3049 3025 3009
-f 3009 3041 3049
-f 2223 2209 1808
-f 1808 1805 2223
-f 2411 2403 2209
-f 2209 2223 2411
-f 2540 2530 2403
-f 2403 2411 2540
-f 2660 2646 2530
-f 2530 2540 2660
-f 2774 2732 2646
-f 2646 2660 2774
-f 2884 2842 2732
-f 2732 2774 2884
-f 2995 2944 2842
-f 2842 2884 2995
-f 3045 3019 2944
-f 2944 2995 3045
-f 3073 3041 3019
-f 3019 3045 3073
-f 3079 3049 3041
-f 3041 3073 3079
-f 2237 2223 1805
-f 1805 1803 2237
-f 2421 2411 2223
-f 2223 2237 2421
-f 2553 2540 2411
-f 2411 2421 2553
-f 2684 2660 2540
-f 2540 2553 2684
-f 2809 2774 2660
-f 2660 2684 2809
-f 2938 2884 2774
-f 2774 2809 2938
-f 3031 2995 2884
-f 2884 2938 3031
-f 3075 3045 2995
-f 2995 3031 3075
-f 3093 3073 3045
-f 3045 3075 3093
-f 3117 3079 3073
-f 3073 3093 3117
-f 2248 2237 1803
-f 1803 1801 2248
-f 2431 2421 2237
-f 2237 2248 2431
-f 2573 2553 2421
-f 2421 2431 2573
-f 2706 2684 2553
-f 2553 2573 2706
-f 2838 2809 2684
-f 2684 2706 2838
-f 2985 2938 2809
-f 2809 2838 2985
-f 3055 3031 2938
-f 2938 2985 3055
-f 3091 3075 3031
-f 3031 3055 3091
-f 3133 3093 3075
-f 3075 3091 3133
-f 3143 3117 3093
-f 3093 3133 3143
-f 2254 2248 1801
-f 1801 1799 2254
-f 2439 2431 2248
-f 2248 2254 2439
-f 2586 2573 2431
-f 2431 2439 2586
-f 2724 2706 2573
-f 2573 2586 2724
-f 2862 2838 2706
-f 2706 2724 2862
-f 3015 2985 2838
-f 2838 2862 3015
-f 3077 3055 2985
-f 2985 3015 3077
-f 3129 3091 3055
-f 3055 3077 3129
-f 3151 3133 3091
-f 3091 3129 3151
-f 3157 3143 3133
-f 3133 3151 3157
-f 2268 2254 1799
-f 1799 1796 2268
-f 2451 2439 2254
-f 2254 2268 2451
-f 2600 2586 2439
-f 2439 2451 2600
-f 2744 2724 2586
-f 2586 2600 2744
-f 2894 2862 2724
-f 2724 2744 2894
-f 3037 3015 2862
-f 2862 2894 3037
-f 3089 3077 3015
-f 3015 3037 3089
-f 3149 3129 3077
-f 3077 3089 3149
-f 3163 3151 3129
-f 3129 3149 3163
-f 3173 3157 3151
-f 3151 3163 3173
-f 2278 2268 1796
-f 1796 1793 2278
-f 2453 2451 2268
-f 2268 2278 2453
-f 2616 2600 2451
-f 2451 2453 2616
-f 2764 2744 2600
-f 2600 2616 2764
-f 2916 2894 2744
-f 2744 2764 2916
-f 3047 3037 2894
-f 2894 2916 3047
-f 3119 3089 3037
-f 3037 3047 3119
-f 3155 3149 3089
-f 3089 3119 3155
-f 3179 3163 3149
-f 3149 3155 3179
-f 3185 3173 3163
-f 3163 3179 3185
-f 2288 2278 1793
-f 1793 1791 2288
-f 2459 2453 2278
-f 2278 2288 2459
-f 2628 2616 2453
-f 2453 2459 2628
-f 2776 2764 2616
-f 2616 2628 2776
-f 2942 2916 2764
-f 2764 2776 2942
-f 3059 3047 2916
-f 2916 2942 3059
-f 3131 3119 3047
-f 3047 3059 3131
-f 3165 3155 3119
-f 3119 3131 3165
-f 3189 3179 3155
-f 3155 3165 3189
-f 3201 3185 3179
-f 3179 3189 3201
-f 2296 2288 1791
-f 1791 1789 2296
-f 2463 2459 2288
-f 2288 2296 2463
-f 2635 2628 2459
-f 2459 2463 2635
-f 2782 2776 2628
-f 2628 2635 2782
-f 2956 2942 2776
-f 2776 2782 2956
-f 3065 3059 2942
-f 2942 2956 3065
-f 3137 3131 3059
-f 3059 3065 3137
-f 3171 3165 3131
-f 3131 3137 3171
-f 3199 3189 3165
-f 3165 3171 3199
-f 3210 3201 3189
-f 3189 3199 3210
-f 2299 2296 1789
-f 1789 1786 2299
-f 2467 2463 2296
-f 2296 2299 2467
-f 2644 2635 2463
-f 2463 2467 2644
-f 2786 2782 2635
-f 2635 2644 2786
-f 2964 2956 2782
-f 2782 2786 2964
-f 3069 3065 2956
-f 2956 2964 3069
-f 3141 3137 3065
-f 3065 3069 3141
-f 3177 3171 3137
-f 3137 3141 3177
-f 3204 3199 3171
-f 3171 3177 3204
-f 3214 3210 3199
-f 3199 3204 3214
-f 3194 3202 3213
-f 3213 3207 3194
-f 3166 3175 3202
-f 3202 3194 3166
-f 3134 3139 3175
-f 3175 3166 3134
-f 3060 3067 3139
-f 3139 3134 3060
-f 2953 2962 3067
-f 3067 3060 2953
-f 2777 2784 2962
-f 2962 2953 2777
-f 2629 2643 2784
-f 2784 2777 2629
-f 2460 2465 2643
-f 2643 2629 2460
-f 2293 2298 2465
-f 2465 2460 2293
-f 1696 1785 2298
-f 2298 2293 1696
-f 3180 3194 3207
-f 3207 3190 3180
-f 3158 3166 3194
-f 3194 3180 3158
-f 3124 3134 3166
-f 3166 3158 3124
-f 3050 3060 3134
-f 3134 3124 3050
-f 2927 2953 3060
-f 3060 3050 2927
-f 2767 2777 2953
-f 2953 2927 2767
-f 2619 2629 2777
-f 2777 2767 2619
-f 2454 2460 2629
-f 2629 2619 2454
-f 2283 2293 2460
-f 2460 2454 2283
-f 1695 1696 2293
-f 2293 2283 1695
-f 3160 3180 3190
-f 3190 3168 3160
-f 3144 3158 3180
-f 3180 3160 3144
-f 3086 3124 3158
-f 3158 3144 3086
-f 3032 3050 3124
-f 3124 3086 3032
-f 2891 2927 3050
-f 3050 3032 2891
-f 2739 2767 2927
-f 2927 2891 2739
-f 2597 2619 2767
-f 2767 2739 2597
-f 2448 2454 2619
-f 2619 2597 2448
-f 2265 2283 2454
-f 2454 2448 2265
-f 1707 1695 2283
-f 2283 2265 1707
-f 3146 3160 3168
-f 3168 3152 3146
-f 3122 3144 3160
-f 3160 3146 3122
-f 3070 3086 3144
-f 3144 3122 3070
-f 2998 3032 3086
-f 3086 3070 2998
-f 2853 2891 3032
-f 3032 2998 2853
-f 2717 2739 2891
-f 2891 2853 2717
-f 2582 2597 2739
-f 2739 2717 2582
-f 2434 2448 2597
-f 2597 2582 2434
-f 2251 2265 2448
-f 2448 2434 2251
-f 1907 1707 2265
-f 2265 2251 1907
-f 3120 3146 3152
-f 3152 3126 3120
-f 3082 3122 3146
-f 3146 3120 3082
-f 3042 3070 3122
-f 3122 3082 3042
-f 2957 2998 3070
-f 3070 3042 2957
-f 2825 2853 2998
-f 2998 2957 2825
-f 2693 2717 2853
-f 2853 2825 2693
-f 2556 2582 2717
-f 2717 2693 2556
-f 2424 2434 2582
-f 2582 2556 2424
-f 2239 2251 2434
-f 2434 2424 2239
-f 1906 1907 2251
-f 2251 2239 1906
-f 3080 3120 3126
-f 3126 3084 3080
-f 3056 3082 3120
-f 3120 3080 3056
-f 3012 3042 3082
-f 3082 3056 3012
-f 2899 2957 3042
-f 3042 3012 2899
-f 2789 2825 2957
-f 2957 2899 2789
-f 2675 2693 2825
-f 2825 2789 2675
-f 2545 2556 2693
-f 2693 2675 2545
-f 2416 2424 2556
-f 2556 2545 2416
-f 2228 2239 2424
-f 2424 2416 2228
-f 1770 1906 2239
-f 2239 2228 1770
-f 3053 3080 3084
-f 3084 3062 3053
-f 3028 3056 3080
-f 3080 3053 3028
-f 2978 3012 3056
-f 3056 3028 2978
-f 2860 2899 3012
-f 3012 2978 2860
-f 2754 2789 2899
-f 2899 2860 2754
-f 2652 2675 2789
-f 2789 2754 2652
-f 2534 2545 2675
-f 2675 2652 2534
-f 2406 2416 2545
-f 2545 2534 2406
-f 2217 2228 2416
-f 2416 2406 2217
-f 1929 1770 2228
-f 2228 2217 1929
-f 3035 3053 3062
-f 3062 3039 3035
-f 2997 3028 3053
-f 3053 3035 2997
-f 2920 2978 3028
-f 3028 2997 2920
-f 2832 2860 2978
-f 2978 2920 2832
-f 2728 2754 2860
-f 2860 2832 2728
-f 2634 2652 2754
-f 2754 2728 2634
-f 2528 2534 2652
-f 2652 2634 2528
-f 2396 2406 2534
-f 2534 2528 2396
-f 2202 2217 2406
-f 2406 2396 2202
-f 1765 1929 2217
-f 2217 2202 1765
-f 3017 3035 3039
-f 3039 3027 3017
-f 2980 2997 3035
-f 3035 3017 2980
-f 2896 2920 2997
-f 2997 2980 2896
-f 2812 2832 2920
-f 2920 2896 2812
-f 2715 2728 2832
-f 2832 2812 2715
-f 2618 2634 2728
-f 2728 2715 2618
-f 2523 2528 2634
-f 2634 2618 2523
-f 2392 2396 2528
-f 2528 2523 2392
-f 2196 2202 2396
-f 2396 2392 2196
-f 1724 1765 2202
-f 2202 2196 1724
-f 3007 3017 3027
-f 3027 3023 3007
-f 2969 2980 3017
-f 3017 3007 2969
-f 2887 2896 2980
-f 2980 2969 2887
-f 2802 2812 2896
-f 2896 2887 2802
-f 2709 2715 2812
-f 2812 2802 2709
-f 2609 2618 2715
-f 2715 2709 2609
-f 2519 2523 2618
-f 2618 2609 2519
-f 2386 2392 2523
-f 2523 2519 2386
-f 2190 2196 2392
-f 2392 2386 2190
-f 1759 1724 2196
-f 2196 2190 1759
-f 1329 1324 1785
-f 1785 1782 1329
-f 1162 1157 1324
-f 1324 1329 1162
-f 993 982 1157
-f 1157 1162 993
-f 845 838 982
-f 982 993 845
-f 669 660 838
-f 838 845 669
-f 542 535 660
-f 660 669 542
-f 490 485 535
-f 535 542 490
-f 438 429 485
-f 485 490 438
-f 404 396 429
-f 429 438 404
-f 387 376 396
-f 396 404 387
-f 1339 1329 1782
-f 1782 1780 1339
-f 1168 1162 1329
-f 1329 1339 1168
-f 1003 993 1162
-f 1162 1168 1003
-f 855 845 993
-f 993 1003 855
-f 695 669 845
-f 845 855 695
-f 559 542 669
-f 669 695 559
-f 500 490 542
-f 542 559 500
-f 446 438 490
-f 490 500 446
-f 416 404 438
-f 438 446 416
-f 408 387 404
-f 404 416 408
-f 1357 1339 1780
-f 1780 1778 1357
-f 1174 1168 1339
-f 1339 1357 1174
-f 1025 1003 1168
-f 1168 1174 1025
-f 883 855 1003
-f 1003 1025 883
-f 731 695 855
-f 855 883 731
-f 583 559 695
-f 695 731 583
-f 516 500 559
-f 559 583 516
-f 467 446 500
-f 500 516 467
-f 444 416 446
-f 446 467 444
-f 436 408 416
-f 416 444 436
-f 1371 1357 1778
-f 1778 1776 1371
-f 1188 1174 1357
-f 1357 1371 1188
-f 1042 1025 1174
-f 1174 1188 1042
-f 905 883 1025
-f 1025 1042 905
-f 769 731 883
-f 883 905 769
-f 624 583 731
-f 731 769 624
-f 532 516 583
-f 583 624 532
-f 502 467 516
-f 516 532 502
-f 459 444 467
-f 467 502 459
-f 452 436 444
-f 444 459 452
-f 1383 1371 1776
-f 1776 1774 1383
-f 1198 1188 1371
-f 1371 1383 1198
-f 1068 1042 1188
-f 1188 1198 1068
-f 929 905 1042
-f 1042 1068 929
-f 797 769 905
-f 905 929 797
-f 665 624 769
-f 769 797 665
-f 569 532 624
-f 624 665 569
-f 520 502 532
-f 532 569 520
-f 504 459 502
-f 502 520 504
-f 498 452 459
-f 459 504 498
-f 1394 1383 1774
-f 1774 1771 1394
-f 1206 1198 1383
-f 1383 1394 1206
-f 1077 1068 1198
-f 1198 1206 1077
-f 947 929 1068
-f 1068 1077 947
-f 833 797 929
-f 929 947 833
-f 723 665 797
-f 797 833 723
-f 610 569 665
-f 665 723 610
-f 549 520 569
-f 569 610 549
-f 522 504 520
-f 520 549 522
-f 518 498 504
-f 504 522 518
-f 1407 1394 1771
-f 1771 1768 1407
-f 1216 1206 1394
-f 1394 1407 1216
-f 1090 1077 1206
-f 1206 1216 1090
-f 972 947 1077
-f 1077 1090 972
-f 870 833 947
-f 947 972 870
-f 764 723 833
-f 833 870 764
-f 646 610 723
-f 723 764 646
-f 587 549 610
-f 610 646 587
-f 556 522 549
-f 549 587 556
-f 540 518 522
-f 522 556 540
-f 1420 1407 1768
-f 1768 1764 1420
-f 1226 1216 1407
-f 1407 1420 1226
-f 1096 1090 1216
-f 1216 1226 1096
-f 990 972 1090
-f 1090 1096 990
-f 896 870 972
-f 972 990 896
-f 792 764 870
-f 870 896 792
-f 704 646 764
-f 764 792 704
-f 627 587 646
-f 646 704 627
-f 582 556 587
-f 587 627 582
-f 574 540 556
-f 556 582 574
-f 1426 1420 1764
-f 1764 1762 1426
-f 1230 1226 1420
-f 1420 1426 1230
-f 1101 1096 1226
-f 1226 1230 1101
-f 1006 990 1096
-f 1096 1101 1006
-f 907 896 990
-f 990 1006 907
-f 812 792 896
-f 896 907 812
-f 728 704 792
-f 792 812 728
-f 644 627 704
-f 704 728 644
-f 607 582 627
-f 627 644 607
-f 592 574 582
-f 582 607 592
-f 1430 1426 1762
-f 1762 1758 1430
-f 1234 1230 1426
-f 1426 1430 1234
-f 1107 1101 1230
-f 1230 1234 1107
-f 1012 1006 1101
-f 1101 1107 1012
-f 912 907 1006
-f 1006 1012 912
-f 819 812 907
-f 907 912 819
-f 738 728 812
-f 812 819 738
-f 651 644 728
-f 728 738 651
-f 618 607 644
-f 644 651 618
-f 601 592 607
-f 607 618 601
-f 405 397 376
-f 376 388 405
-f 439 430 397
-f 397 405 439
-f 491 486 430
-f 430 439 491
-f 543 536 486
-f 486 491 543
-f 670 661 536
-f 536 543 670
-f 846 839 661
-f 661 670 846
-f 994 980 839
-f 839 846 994
-f 1163 1158 980
-f 980 994 1163
-f 1330 1325 1158
-f 1158 1163 1330
-f 1926 1786 1325
-f 1325 1330 1926
-f 417 405 388
-f 388 409 417
-f 447 439 405
-f 405 417 447
-f 501 491 439
-f 439 447 501
-f 560 543 491
-f 491 501 560
-f 696 670 543
-f 543 560 696
-f 856 846 670
-f 670 696 856
-f 1004 994 846
-f 846 856 1004
-f 1169 1163 994
-f 994 1004 1169
-f 1340 1330 1163
-f 1163 1169 1340
-f 1925 1926 1330
-f 1330 1340 1925
-f 445 417 409
-f 409 437 445
-f 468 447 417
-f 417 445 468
-f 517 501 447
-f 447 468 517
-f 584 560 501
-f 501 517 584
-f 732 696 560
-f 560 584 732
-f 884 856 696
-f 696 732 884
-f 1026 1004 856
-f 856 884 1026
-f 1175 1169 1004
-f 1004 1026 1175
-f 1358 1340 1169
-f 1169 1175 1358
-f 1908 1925 1340
-f 1340 1358 1908
-f 460 445 437
-f 437 453 460
-f 503 468 445
-f 445 460 503
-f 533 517 468
-f 468 503 533
-f 625 584 517
-f 517 533 625
-f 770 732 584
-f 584 625 770
-f 906 884 732
-f 732 770 906
-f 1041 1026 884
-f 884 906 1041
-f 1189 1175 1026
-f 1026 1041 1189
-f 1372 1358 1175
-f 1175 1189 1372
-f 1706 1908 1358
-f 1358 1372 1706
-f 505 460 453
-f 453 499 505
-f 521 503 460
-f 460 505 521
-f 570 533 503
-f 503 521 570
-f 666 625 533
-f 533 570 666
-f 798 770 625
-f 625 666 798
-f 930 906 770
-f 770 798 930
-f 1067 1041 906
-f 906 930 1067
-f 1199 1189 1041
-f 1041 1067 1199
-f 1384 1372 1189
-f 1189 1199 1384
-f 1705 1706 1372
-f 1372 1384 1705
-f 523 505 499
-f 499 519 523
-f 550 521 505
-f 505 523 550
-f 611 570 521
-f 521 550 611
-f 724 666 570
-f 570 611 724
-f 834 798 666
-f 666 724 834
-f 948 930 798
-f 798 834 948
-f 1078 1067 930
-f 930 948 1078
-f 1207 1199 1067
-f 1067 1078 1207
-f 1395 1384 1199
-f 1199 1207 1395
-f 1773 1705 1384
-f 1384 1395 1773
-f 555 523 519
-f 519 541 555
-f 588 550 523
-f 523 555 588
-f 645 611 550
-f 550 588 645
-f 763 724 611
-f 611 645 763
-f 869 834 724
-f 724 763 869
-f 971 948 834
-f 834 869 971
-f 1089 1078 948
-f 948 971 1089
-f 1217 1207 1078
-f 1078 1089 1217
-f 1406 1395 1207
-f 1207 1217 1406
-f 1692 1773 1395
-f 1395 1406 1692
-f 581 555 541
-f 541 573 581
-f 626 588 555
-f 555 581 626
-f 703 645 588
-f 588 626 703
-f 791 763 645
-f 645 703 791
-f 895 869 763
-f 763 791 895
-f 989 971 869
-f 869 895 989
-f 1095 1089 971
-f 971 989 1095
-f 1227 1217 1089
-f 1089 1095 1227
-f 1421 1406 1217
-f 1217 1227 1421
-f 1766 1692 1406
-f 1406 1421 1766
-f 606 581 573
-f 573 591 606
-f 643 626 581
-f 581 606 643
-f 727 703 626
-f 626 643 727
-f 811 791 703
-f 703 727 811
-f 908 895 791
-f 791 811 908
-f 1005 989 895
-f 895 908 1005
-f 1100 1095 989
-f 989 1005 1100
-f 1231 1227 1095
-f 1095 1100 1231
-f 1427 1421 1227
-f 1227 1231 1427
-f 1897 1766 1421
-f 1421 1427 1897
-f 615 606 591
-f 591 598 615
-f 653 643 606
-f 606 615 653
-f 735 727 643
-f 643 653 735
-f 820 811 727
-f 727 735 820
-f 913 908 811
-f 811 820 913
-f 1013 1005 908
-f 908 913 1013
-f 1103 1100 1005
-f 1005 1013 1103
-f 1236 1231 1100
-f 1100 1103 1236
-f 1432 1427 1231
-f 1231 1236 1432
-f 1760 1897 1427
-f 1427 1432 1760
-f 2294 2299 1786
-f 1786 1783 2294
-f 2461 2466 2299
-f 2299 2294 2461
-f 2630 2641 2466
-f 2466 2461 2630
-f 2778 2785 2641
-f 2641 2630 2778
-f 2954 2963 2785
-f 2785 2778 2954
-f 3061 3068 2963
-f 2963 2954 3061
-f 3135 3140 3068
-f 3068 3061 3135
-f 3167 3176 3140
-f 3140 3135 3167
-f 3195 3203 3176
-f 3176 3167 3195
-f 3208 3213 3203
-f 3203 3195 3208
-f 2284 2294 1783
-f 1783 1781 2284
-f 2455 2461 2294
-f 2294 2284 2455
-f 2620 2630 2461
-f 2461 2455 2620
-f 2768 2778 2630
-f 2630 2620 2768
-f 2928 2954 2778
-f 2778 2768 2928
-f 3051 3061 2954
-f 2954 2928 3051
-f 3125 3135 3061
-f 3061 3051 3125
-f 3159 3167 3135
-f 3135 3125 3159
-f 3181 3195 3167
-f 3167 3159 3181
-f 3191 3208 3195
-f 3195 3181 3191
-f 2266 2284 1781
-f 1781 1779 2266
-f 2449 2455 2284
-f 2284 2266 2449
-f 2598 2620 2455
-f 2455 2449 2598
-f 2740 2768 2620
-f 2620 2598 2740
-f 2892 2928 2768
-f 2768 2740 2892
-f 3033 3051 2928
-f 2928 2892 3033
-f 3087 3125 3051
-f 3051 3033 3087
-f 3145 3159 3125
-f 3125 3087 3145
-f 3161 3181 3159
-f 3159 3145 3161
-f 3169 3191 3181
-f 3181 3161 3169
-f 2252 2266 1779
-f 1779 1777 2252
-f 2435 2449 2266
-f 2266 2252 2435
-f 2581 2598 2449
-f 2449 2435 2581
-f 2718 2740 2598
-f 2598 2581 2718
-f 2854 2892 2740
-f 2740 2718 2854
-f 2999 3033 2892
-f 2892 2854 2999
-f 3071 3087 3033
-f 3033 2999 3071
-f 3123 3145 3087
-f 3087 3071 3123
-f 3147 3161 3145
-f 3145 3123 3147
-f 3153 3169 3161
-f 3161 3147 3153
-f 2240 2252 1777
-f 1777 1775 2240
-f 2425 2435 2252
-f 2252 2240 2425
-f 2555 2581 2435
-f 2435 2425 2555
-f 2694 2718 2581
-f 2581 2555 2694
-f 2826 2854 2718
-f 2718 2694 2826
-f 2958 2999 2854
-f 2854 2826 2958
-f 3043 3071 2999
-f 2999 2958 3043
-f 3083 3123 3071
-f 3071 3043 3083
-f 3121 3147 3123
-f 3123 3083 3121
-f 3127 3153 3147
-f 3147 3121 3127
-f 2229 2240 1775
-f 1775 1772 2229
-f 2417 2425 2240
-f 2240 2229 2417
-f 2546 2555 2425
-f 2425 2417 2546
-f 2676 2694 2555
-f 2555 2546 2676
-f 2790 2826 2694
-f 2694 2676 2790
-f 2900 2958 2826
-f 2826 2790 2900
-f 3013 3043 2958
-f 2958 2900 3013
-f 3057 3083 3043
-f 3043 3013 3057
-f 3081 3121 3083
-f 3083 3057 3081
-f 3085 3127 3121
-f 3121 3081 3085
-f 2216 2229 1772
-f 1772 1769 2216
-f 2407 2417 2229
-f 2229 2216 2407
-f 2533 2546 2417
-f 2417 2407 2533
-f 2651 2676 2546
-f 2546 2533 2651
-f 2753 2790 2676
-f 2676 2651 2753
-f 2859 2900 2790
-f 2790 2753 2859
-f 2977 3013 2900
-f 2900 2859 2977
-f 3029 3057 3013
-f 3013 2977 3029
-f 3052 3081 3057
-f 3057 3029 3052
-f 3063 3085 3081
-f 3081 3052 3063
-f 2203 2216 1769
-f 1769 1767 2203
-f 2397 2407 2216
-f 2216 2203 2397
-f 2527 2533 2407
-f 2407 2397 2527
-f 2633 2651 2533
-f 2533 2527 2633
-f 2727 2753 2651
-f 2651 2633 2727
-f 2831 2859 2753
-f 2753 2727 2831
-f 2919 2977 2859
-f 2859 2831 2919
-f 2996 3029 2977
-f 2977 2919 2996
-f 3034 3052 3029
-f 3029 2996 3034
-f 3038 3063 3052
-f 3052 3034 3038
-f 2197 2203 1767
-f 1767 1763 2197
-f 2393 2397 2203
-f 2203 2197 2393
-f 2522 2527 2397
-f 2397 2393 2522
-f 2617 2633 2527
-f 2527 2522 2617
-f 2716 2727 2633
-f 2633 2617 2716
-f 2811 2831 2727
-f 2727 2716 2811
-f 2895 2919 2831
-f 2831 2811 2895
-f 2979 2996 2919
-f 2919 2895 2979
-f 3016 3034 2996
-f 2996 2979 3016
-f 3026 3038 3034
-f 3034 3016 3026
-f 2193 2197 1763
-f 1763 1761 2193
-f 2389 2393 2197
-f 2197 2193 2389
-f 2516 2522 2393
-f 2393 2389 2516
-f 2610 2617 2522
-f 2522 2516 2610
-f 2710 2716 2617
-f 2617 2610 2710
-f 2803 2811 2716
-f 2716 2710 2803
-f 2885 2895 2811
-f 2811 2803 2885
-f 2971 2979 2895
-f 2895 2885 2971
-f 3005 3016 2979
-f 2979 2971 3005
-f 3022 3026 3016
-f 3016 3005 3022
-f 461 545 544
-f 544 456 461
-f 463 551 545
-f 545 461 463
-f 465 557 551
-f 551 463 465
-f 469 567 557
-f 557 465 469
-f 471 575 567
-f 567 469 471
-f 473 577 575
-f 575 471 473
-f 475 589 577
-f 577 473 475
-f 477 593 589
-f 589 475 477
-f 479 595 593
-f 593 477 479
-f 481 599 595
-f 595 479 481
-f 389 461 456
-f 456 392 389
-f 386 463 461
-f 461 389 386
-f 379 465 463
-f 463 386 379
-f 373 469 465
-f 465 379 373
-f 371 471 469
-f 469 373 371
-f 369 473 471
-f 471 371 369
-f 366 475 473
-f 473 369 366
-f 364 477 475
-f 475 366 364
-f 362 479 477
-f 477 364 362
-f 361 481 479
-f 479 362 361
-f 335 389 392
-f 392 337 335
-f 333 386 389
-f 389 335 333
-f 331 379 386
-f 386 333 331
-f 329 373 379
-f 379 331 329
-f 328 371 373
-f 373 329 328
-f 325 369 371
-f 371 328 325
-f 323 366 369
-f 369 325 323
-f 321 364 366
-f 366 323 321
-f 319 362 364
-f 364 321 319
-f 316 361 362
-f 362 319 316
-f 298 335 337
-f 337 302 298
-f 290 333 335
-f 335 298 290
-f 288 331 333
-f 333 290 288
-f 286 329 331
-f 331 288 286
-f 281 328 329
-f 329 286 281
-f 275 325 328
-f 328 281 275
-f 265 323 325
-f 325 275 265
-f 259 321 323
-f 323 265 259
-f 255 319 321
-f 321 259 255
-f 249 316 319
-f 319 255 249
-f 269 298 302
-f 302 271 269
-f 261 290 298
-f 298 269 261
-f 251 288 290
-f 290 261 251
-f 238 286 288
-f 288 251 238
-f 230 281 286
-f 286 238 230
-f 218 275 281
-f 281 230 218
-f 208 265 275
-f 275 218 208
-f 196 259 265
-f 265 208 196
-f 186 255 259
-f 259 196 186
-f 181 249 255
-f 255 186 181
-f 228 269 271
-f 271 234 228
-f 222 261 269
-f 269 228 222
-f 212 251 261
-f 261 222 212
-f 200 238 251
-f 251 212 200
-f 177 230 238
-f 238 200 177
-f 160 218 230
-f 230 177 160
-f 134 208 218
-f 218 160 134
-f 112 196 208
-f 208 134 112
-f 102 186 196
-f 196 112 102
-f 96 181 186
-f 186 102 96
-f 198 228 234
-f 234 205 198
-f 182 222 228
-f 228 198 182
-f 168 212 222
-f 222 182 168
-f 146 200 212
-f 212 168 146
-f 118 177 200
-f 200 146 118
-f 92 160 177
-f 177 118 92
-f 74 134 160
-f 160 92 74
-f 63 112 134
-f 134 74 63
-f 53 102 112
-f 112 63 53
-f 50 96 102
-f 102 53 50
-f 167 198 205
-f 205 170 167
-f 154 182 198
-f 198 167 154
-f 126 168 182
-f 182 154 126
-f 100 146 168
-f 168 126 100
-f 83 118 146
-f 146 100 83
-f 61 92 118
-f 118 83 61
-f 46 74 92
-f 92 61 46
-f 32 63 74
-f 74 46 32
-f 25 53 63
-f 63 32 25
-f 21 50 53
-f 53 25 21
-f 143 167 170
-f 170 150 143
-f 124 154 167
-f 167 143 124
-f 104 126 154
-f 154 124 104
-f 84 100 126
-f 126 104 84
-f 65 83 100
-f 100 84 65
-f 44 61 83
-f 83 65 44
-f 30 46 61
-f 61 44 30
-f 17 32 46
-f 46 30 17
-f 9 25 32
-f 32 17 9
-f 5 21 25
-f 25 9 5
-f 132 143 150
-f 150 140 132
-f 116 124 143
-f 143 132 116
-f 94 104 124
-f 124 116 94
-f 76 84 104
-f 104 94 76
-f 55 65 84
-f 84 76 55
-f 40 44 65
-f 65 55 40
-f 22 30 44
-f 44 40 22
-f 11 17 30
-f 30 22 11
-f 2 9 17
-f 17 11 2
-f 1 5 9
-f 9 2 1
-f 480 596 599
-f 599 481 480
-f 478 594 596
-f 596 480 478
-f 476 590 594
-f 594 478 476
-f 474 578 590
-f 590 476 474
-f 472 576 578
-f 578 474 472
-f 470 568 576
-f 576 472 470
-f 466 558 568
-f 568 470 466
-f 464 552 558
-f 558 466 464
-f 462 546 552
-f 552 464 462
-f 456 544 546
-f 546 462 456
-f 363 480 481
-f 481 360 363
-f 365 478 480
-f 480 363 365
-f 367 476 478
-f 478 365 367
-f 368 474 476
-f 476 367 368
-f 370 472 474
-f 474 368 370
-f 372 470 472
-f 472 370 372
-f 380 466 470
-f 470 372 380
-f 385 464 466
-f 466 380 385
-f 390 462 464
-f 464 385 390
-f 391 456 462
-f 462 390 391
-f 320 363 360
-f 360 316 320
-f 322 365 363
-f 363 320 322
-f 324 367 365
-f 365 322 324
-f 326 368 367
-f 367 324 326
-f 327 370 368
-f 368 326 327
-f 330 372 370
-f 370 327 330
-f 332 380 372
-f 372 330 332
-f 334 385 380
-f 380 332 334
-f 336 390 385
-f 385 334 336
-f 337 391 390
-f 390 336 337
-f 256 320 316
-f 316 250 256
-f 260 322 320
-f 320 256 260
-f 266 324 322
-f 322 260 266
-f 276 326 324
-f 324 266 276
-f 282 327 326
-f 326 276 282
-f 287 330 327
-f 327 282 287
-f 289 332 330
-f 330 287 289
-f 291 334 332
-f 332 289 291
-f 299 336 334
-f 334 291 299
-f 303 337 336
-f 336 299 303
-f 187 256 250
-f 250 181 187
-f 197 260 256
-f 256 187 197
-f 209 266 260
-f 260 197 209
-f 219 276 266
-f 266 209 219
-f 231 282 276
-f 276 219 231
-f 239 287 282
-f 282 231 239
-f 252 289 287
-f 287 239 252
-f 262 291 289
-f 289 252 262
-f 270 299 291
-f 291 262 270
-f 272 303 299
-f 299 270 272
-f 103 187 181
-f 181 97 103
-f 113 197 187
-f 187 103 113
-f 135 209 197
-f 197 113 135
-f 161 219 209
-f 209 135 161
-f 178 231 219
-f 219 161 178
-f 201 239 231
-f 231 178 201
-f 213 252 239
-f 239 201 213
-f 223 262 252
-f 252 213 223
-f 229 270 262
-f 262 223 229
-f 235 272 270
-f 270 229 235
-f 54 103 97
-f 97 50 54
-f 64 113 103
-f 103 54 64
-f 75 135 113
-f 113 64 75
-f 93 161 135
-f 135 75 93
-f 119 178 161
-f 161 93 119
-f 147 201 178
-f 178 119 147
-f 169 213 201
-f 201 147 169
-f 183 223 213
-f 213 169 183
-f 199 229 223
-f 223 183 199
-f 205 235 229
-f 229 199 205
-f 24 54 50
-f 50 21 24
-f 33 64 54
-f 54 24 33
-f 47 75 64
-f 64 33 47
-f 62 93 75
-f 75 47 62
-f 82 119 93
-f 93 62 82
-f 101 147 119
-f 119 82 101
-f 127 169 147
-f 147 101 127
-f 155 183 169
-f 169 127 155
-f 166 199 183
-f 183 155 166
-f 171 205 199
-f 199 166 171
-f 10 24 21
-f 21 6 10
-f 18 33 24
-f 24 10 18
-f 31 47 33
-f 33 18 31
-f 45 62 47
-f 47 31 45
-f 66 82 62
-f 62 45 66
-f 85 101 82
-f 82 66 85
-f 105 127 101
-f 101 85 105
-f 125 155 127
-f 127 105 125
-f 144 166 155
-f 155 125 144
-f 151 171 166
-f 166 144 151
-f 3 10 6
-f 6 1 3
-f 12 18 10
-f 10 3 12
-f 23 31 18
-f 18 12 23
-f 41 45 31
-f 31 23 41
-f 56 66 45
-f 45 41 56
-f 77 85 66
-f 66 56 77
-f 95 105 85
-f 85 77 95
-f 117 125 105
-f 105 95 117
-f 133 144 125
-f 125 117 133
-f 140 151 144
-f 144 133 140
-f 138 132 140
-f 140 145 138
-f 122 116 132
-f 132 138 122
-f 98 94 116
-f 116 122 98
-f 80 76 94
-f 94 98 80
-f 60 55 76
-f 76 80 60
-f 42 40 55
-f 55 60 42
-f 28 22 40
-f 40 42 28
-f 13 11 22
-f 22 28 13
-f 7 2 11
-f 11 13 7
-f 4 1 2
-f 2 7 4
-f 152 138 145
-f 145 158 152
-f 136 122 138
-f 138 152 136
-f 108 98 122
-f 122 136 108
-f 89 80 98
-f 98 108 89
-f 70 60 80
-f 80 89 70
-f 52 42 60
-f 60 70 52
-f 38 28 42
-f 42 52 38
-f 26 13 28
-f 28 38 26
-f 19 7 13
-f 13 26 19
-f 15 4 7
-f 7 19 15
-f 173 152 158
-f 158 176 173
-f 162 136 152
-f 152 173 162
-f 142 108 136
-f 136 162 142
-f 111 89 108
-f 108 142 111
-f 91 70 89
-f 89 111 91
-f 73 52 70
-f 70 91 73
-f 58 38 52
-f 52 73 58
-f 48 26 38
-f 38 58 48
-f 37 19 26
-f 26 48 37
-f 35 15 19
-f 19 37 35
-f 194 173 176
-f 176 202 194
-f 184 162 173
-f 173 194 184
-f 174 142 162
-f 162 184 174
-f 156 111 142
-f 142 174 156
-f 128 91 111
-f 111 156 128
-f 106 73 91
-f 91 128 106
-f 86 58 73
-f 73 106 86
-f 78 48 58
-f 58 86 78
-f 68 37 48
-f 48 78 68
-f 67 35 37
-f 37 68 67
-f 221 194 202
-f 202 225 221
-f 216 184 194
-f 194 221 216
-f 206 174 184
-f 184 216 206
-f 192 156 174
-f 174 206 192
-f 180 128 156
-f 156 192 180
-f 164 106 128
-f 128 180 164
-f 148 86 106
-f 106 164 148
-f 130 78 86
-f 86 148 130
-f 121 68 78
-f 78 130 121
-f 115 67 68
-f 68 121 115
-f 244 221 225
-f 225 247 244
-f 240 216 221
-f 221 244 240
-f 236 206 216
-f 216 240 236
-f 233 192 206
-f 206 236 233
-f 227 180 192
-f 192 233 227
-f 215 164 180
-f 180 227 215
-f 210 148 164
-f 164 215 210
-f 203 130 148
-f 148 210 203
-f 191 121 130
-f 130 203 191
-f 188 115 121
-f 121 191 188
-f 284 244 247
-f 247 285 284
-f 279 240 244
-f 244 284 279
-f 277 236 240
-f 240 279 277
-f 273 233 236
-f 236 277 273
-f 267 227 233
-f 233 273 267
-f 263 215 227
-f 227 267 263
-f 258 210 215
-f 215 263 258
-f 253 203 210
-f 210 258 253
-f 245 191 203
-f 203 253 245
-f 242 188 191
-f 191 245 242
-f 315 284 285
-f 285 318 315
-f 312 279 284
-f 284 315 312
-f 311 277 279
-f 279 312 311
-f 309 273 277
-f 277 311 309
-f 307 267 273
-f 273 309 307
-f 305 263 267
-f 267 307 305
-f 301 258 263
-f 263 305 301
-f 297 253 258
-f 258 301 297
-f 295 245 253
-f 253 297 295
-f 293 242 245
-f 245 295 293
-f 341 315 318
-f 318 339 341
-f 343 312 315
-f 315 341 343
-f 345 311 312
-f 312 343 345
-f 347 309 311
-f 311 345 347
-f 349 307 309
-f 309 347 349
-f 351 305 307
-f 307 349 351
-f 353 301 305
-f 305 351 353
-f 355 297 301
-f 301 353 355
-f 357 295 297
-f 297 355 357
-f 359 293 295
-f 295 357 359
-f 378 341 339
-f 339 376 378
-f 384 343 341
-f 341 378 384
-f 394 345 343
-f 343 384 394
-f 403 347 345
-f 345 394 403
-f 406 349 347
-f 347 403 406
-f 415 351 349
-f 349 406 415
-f 419 353 351
-f 351 415 419
-f 423 355 353
-f 353 419 423
-f 425 357 355
-f 355 423 425
-f 427 359 357
-f 357 425 427
-f 8 3 1
-f 1 4 8
-f 14 12 3
-f 3 8 14
-f 29 23 12
-f 12 14 29
-f 43 41 23
-f 23 29 43
-f 59 56 41
-f 41 43 59
-f 81 77 56
-f 56 59 81
-f 99 95 77
-f 77 81 99
-f 123 117 95
-f 95 99 123
-f 139 133 117
-f 117 123 139
-f 145 140 133
-f 133 139 145
-f 20 8 4
-f 4 16 20
-f 27 14 8
-f 8 20 27
-f 39 29 14
-f 14 27 39
-f 51 43 29
-f 29 39 51
-f 71 59 43
-f 43 51 71
-f 88 81 59
-f 59 71 88
-f 109 99 81
-f 81 88 109
-f 137 123 99
-f 99 109 137
-f 153 139 123
-f 123 137 153
-f 159 145 139
-f 139 153 159
-f 36 20 16
-f 16 34 36
-f 49 27 20
-f 20 36 49
-f 57 39 27
-f 27 49 57
-f 72 51 39
-f 39 57 72
-f 90 71 51
-f 51 72 90
-f 110 88 71
-f 71 90 110
-f 141 109 88
-f 88 110 141
-f 163 137 109
-f 109 141 163
-f 172 153 137
-f 137 163 172
-f 176 159 153
-f 153 172 176
-f 69 36 34
-f 34 67 69
-f 79 49 36
-f 36 69 79
-f 87 57 49
-f 49 79 87
-f 107 72 57
-f 57 87 107
-f 129 90 72
-f 72 107 129
-f 157 110 90
-f 90 129 157
-f 175 141 110
-f 110 157 175
-f 185 163 141
-f 141 175 185
-f 195 172 163
-f 163 185 195
-f 202 176 172
-f 172 195 202
-f 120 69 67
-f 67 114 120
-f 131 79 69
-f 69 120 131
-f 149 87 79
-f 79 131 149
-f 165 107 87
-f 87 149 165
-f 179 129 107
-f 107 165 179
-f 193 157 129
-f 129 179 193
-f 207 175 157
-f 157 193 207
-f 217 185 175
-f 175 207 217
-f 220 195 185
-f 185 217 220
-f 224 202 195
-f 195 220 224
-f 190 120 114
-f 114 189 190
-f 204 131 120
-f 120 190 204
-f 211 149 131
-f 131 204 211
-f 214 165 149
-f 149 211 214
-f 226 179 165
-f 165 214 226
-f 232 193 179
-f 179 226 232
-f 237 207 193
-f 193 232 237
-f 241 217 207
-f 207 237 241
-f 243 220 217
-f 217 241 243
-f 248 224 220
-f 220 243 248
-f 246 190 189
-f 189 242 246
-f 254 204 190
-f 190 246 254
-f 257 211 204
-f 204 254 257
-f 264 214 211
-f 211 257 264
-f 268 226 214
-f 214 264 268
-f 274 232 226
-f 226 268 274
-f 278 237 232
-f 232 274 278
-f 280 241 237
-f 237 278 280
-f 283 243 241
-f 241 280 283
-f 285 248 243
-f 243 283 285
-f 294 246 242
-f 242 292 294
-f 296 254 246
-f 246 294 296
-f 300 257 254
-f 254 296 300
-f 304 264 257
-f 257 300 304
-f 306 268 264
-f 264 304 306
-f 308 274 268
-f 268 306 308
-f 310 278 274
-f 274 308 310
-f 313 280 278
-f 278 310 313
-f 314 283 280
-f 280 313 314
-f 317 285 283
-f 283 314 317
-f 356 294 292
-f 292 358 356
-f 354 296 294
-f 294 356 354
-f 352 300 296
-f 296 354 352
-f 350 304 300
-f 300 352 350
-f 348 306 304
-f 304 350 348
-f 346 308 306
-f 306 348 346
-f 344 310 308
-f 308 346 344
-f 342 313 310
-f 310 344 342
-f 340 314 313
-f 313 342 340
-f 338 317 314
-f 314 340 338
-f 424 356 358
-f 358 426 424
-f 422 354 356
-f 356 424 422
-f 418 352 354
-f 354 422 418
-f 414 350 352
-f 352 418 414
-f 407 348 350
-f 350 414 407
-f 402 346 348
-f 348 407 402
-f 393 344 346
-f 346 402 393
-f 383 342 344
-f 344 393 383
-f 377 340 342
-f 342 383 377
-f 375 338 340
-f 340 377 375
-f 3186 3113 3115
-f 3115 3182 3186
-f 3192 3110 3113
-f 3113 3186 3192
-f 3196 3109 3110
-f 3110 3192 3196
-f 3205 3106 3109
-f 3109 3196 3205
-f 3211 3104 3106
-f 3106 3205 3211
-f 3215 3102 3104
-f 3104 3211 3215
-f 3217 3101 3102
-f 3102 3215 3217
-f 3220 3098 3101
-f 3101 3217 3220
-f 3222 3097 3098
-f 3098 3220 3222
-f 3223 3095 3097
-f 3097 3222 3223
-f 3227 3186 3182
-f 3182 3225 3227
-f 3229 3192 3186
-f 3186 3227 3229
-f 3231 3196 3192
-f 3192 3229 3231
-f 3233 3205 3196
-f 3196 3231 3233
-f 3235 3211 3205
-f 3205 3233 3235
-f 3241 3215 3211
-f 3211 3235 3241
-f 3245 3217 3215
-f 3215 3241 3245
-f 3249 3220 3217
-f 3217 3245 3249
-f 3251 3222 3220
-f 3220 3249 3251
-f 3253 3223 3222
-f 3222 3251 3253
-f 3239 3227 3225
-f 3225 3237 3239
-f 3243 3229 3227
-f 3227 3239 3243
-f 3247 3231 3229
-f 3229 3243 3247
-f 3257 3233 3231
-f 3231 3247 3257
-f 3263 3235 3233
-f 3233 3257 3263
-f 3271 3241 3235
-f 3235 3263 3271
-f 3279 3245 3241
-f 3241 3271 3279
-f 3285 3249 3245
-f 3245 3279 3285
-f 3293 3251 3249
-f 3249 3285 3293
-f 3297 3253 3251
-f 3251 3293 3297
-f 3259 3239 3237
-f 3237 3255 3259
-f 3261 3243 3239
-f 3239 3259 3261
-f 3265 3247 3243
-f 3243 3261 3265
-f 3275 3257 3247
-f 3247 3265 3275
-f 3287 3263 3257
-f 3257 3275 3287
-f 3303 3271 3263
-f 3263 3287 3303
-f 3314 3279 3271
-f 3271 3303 3314
-f 3320 3285 3279
-f 3279 3314 3320
-f 3330 3293 3285
-f 3285 3320 3330
-f 3332 3297 3293
-f 3293 3330 3332
-f 3270 3259 3255
-f 3255 3268 3270
-f 3273 3261 3259
-f 3259 3270 3273
-f 3283 3265 3261
-f 3261 3273 3283
-f 3299 3275 3265
-f 3265 3283 3299
-f 3308 3287 3275
-f 3275 3299 3308
-f 3322 3303 3287
-f 3287 3308 3322
-f 3338 3314 3303
-f 3303 3322 3338
-f 3346 3320 3314
-f 3314 3338 3346
-f 3351 3330 3320
-f 3320 3346 3351
-f 3355 3332 3330
-f 3330 3351 3355
-f 3282 3270 3268
-f 3268 3278 3282
-f 3290 3273 3270
-f 3270 3282 3290
-f 3302 3283 3273
-f 3273 3290 3302
-f 3312 3299 3283
-f 3283 3302 3312
-f 3324 3308 3299
-f 3299 3312 3324
-f 3340 3322 3308
-f 3308 3324 3340
-f 3353 3338 3322
-f 3322 3340 3353
-f 3368 3346 3338
-f 3338 3353 3368
-f 3373 3351 3346
-f 3346 3368 3373
-f 3379 3355 3351
-f 3351 3373 3379
-f 3295 3282 3278
-f 3278 3292 3295
-f 3306 3290 3282
-f 3282 3295 3306
-f 3316 3302 3290
-f 3290 3306 3316
-f 3326 3312 3302
-f 3302 3316 3326
-f 3345 3324 3312
-f 3312 3326 3345
-f 3359 3340 3324
-f 3324 3345 3359
-f 3376 3353 3340
-f 3340 3359 3376
-f 3394 3368 3353
-f 3353 3376 3394
-f 3404 3373 3368
-f 3368 3394 3404
-f 3406 3379 3373
-f 3373 3404 3406
-f 3310 3295 3292
-f 3292 3307 3310
-f 3318 3306 3295
-f 3295 3310 3318
-f 3336 3316 3306
-f 3306 3318 3336
-f 3348 3326 3316
-f 3316 3336 3348
-f 3369 3345 3326
-f 3326 3348 3369
-f 3389 3359 3345
-f 3345 3369 3389
-f 3425 3376 3359
-f 3359 3389 3425
-f 3449 3394 3376
-f 3376 3425 3449
-f 3468 3404 3394
-f 3394 3449 3468
-f 3472 3406 3404
-f 3404 3468 3472
-f 3335 3310 3307
-f 3307 3329 3335
-f 3343 3318 3310
-f 3310 3335 3343
-f 3362 3336 3318
-f 3318 3343 3362
-f 3386 3348 3336
-f 3336 3362 3386
-f 3422 3369 3348
-f 3348 3386 3422
-f 3464 3389 3369
-f 3369 3422 3464
-f 3490 3425 3389
-f 3389 3464 3490
-f 3505 3449 3425
-f 3425 3490 3505
-f 3521 3468 3449
-f 3449 3505 3521
-f 3523 3472 3468
-f 3468 3521 3523
-f 3364 3335 3329
-f 3329 3357 3364
-f 3382 3343 3335
-f 3335 3364 3382
-f 3416 3362 3343
-f 3343 3382 3416
-f 3465 3386 3362
-f 3362 3416 3465
-f 3495 3422 3386
-f 3386 3465 3495
-f 3528 3464 3422
-f 3422 3495 3528
-f 3553 3490 3464
-f 3464 3528 3553
-f 3579 3505 3490
-f 3490 3553 3579
-f 3592 3521 3505
-f 3505 3579 3592
-f 3604 3523 3521
-f 3521 3592 3604
-f 3221 3096 3094
-f 3094 3224 3221
-f 3219 3099 3096
-f 3096 3221 3219
-f 3218 3100 3099
-f 3099 3219 3218
-f 3216 3103 3100
-f 3100 3218 3216
-f 3212 3105 3103
-f 3103 3216 3212
-f 3206 3107 3105
-f 3105 3212 3206
-f 3197 3108 3107
-f 3107 3206 3197
-f 3193 3111 3108
-f 3108 3197 3193
-f 3187 3112 3111
-f 3111 3193 3187
-f 3183 3114 3112
-f 3112 3187 3183
-f 3252 3221 3224
-f 3224 3254 3252
-f 3250 3219 3221
-f 3221 3252 3250
-f 3246 3218 3219
-f 3219 3250 3246
-f 3242 3216 3218
-f 3218 3246 3242
-f 3236 3212 3216
-f 3216 3242 3236
-f 3234 3206 3212
-f 3212 3236 3234
-f 3232 3197 3206
-f 3206 3234 3232
-f 3230 3193 3197
-f 3197 3232 3230
-f 3228 3187 3193
-f 3193 3230 3228
-f 3226 3183 3187
-f 3187 3228 3226
-f 3294 3252 3254
-f 3254 3298 3294
-f 3286 3250 3252
-f 3252 3294 3286
-f 3280 3246 3250
-f 3250 3286 3280
-f 3272 3242 3246
-f 3246 3280 3272
-f 3264 3236 3242
-f 3242 3272 3264
-f 3258 3234 3236
-f 3236 3264 3258
-f 3248 3232 3234
-f 3234 3258 3248
-f 3244 3230 3232
-f 3232 3248 3244
-f 3240 3228 3230
-f 3230 3244 3240
-f 3238 3226 3228
-f 3228 3240 3238
-f 3331 3294 3298
-f 3298 3333 3331
-f 3321 3286 3294
-f 3294 3331 3321
-f 3315 3280 3286
-f 3286 3321 3315
-f 3304 3272 3280
-f 3280 3315 3304
-f 3288 3264 3272
-f 3272 3304 3288
-f 3276 3258 3264
-f 3264 3288 3276
-f 3266 3248 3258
-f 3258 3276 3266
-f 3262 3244 3248
-f 3248 3266 3262
-f 3260 3240 3244
-f 3244 3262 3260
-f 3256 3238 3240
-f 3240 3260 3256
-f 3350 3331 3333
-f 3333 3354 3350
-f 3347 3321 3331
-f 3331 3350 3347
-f 3339 3315 3321
-f 3321 3347 3339
-f 3323 3304 3315
-f 3315 3339 3323
-f 3309 3288 3304
-f 3304 3323 3309
-f 3300 3276 3288
-f 3288 3309 3300
-f 3284 3266 3276
-f 3276 3300 3284
-f 3274 3262 3266
-f 3266 3284 3274
-f 3269 3260 3262
-f 3262 3274 3269
-f 3267 3256 3260
-f 3260 3269 3267
-f 3372 3350 3354
-f 3354 3378 3372
-f 3367 3347 3350
-f 3350 3372 3367
-f 3352 3339 3347
-f 3347 3367 3352
-f 3341 3323 3339
-f 3339 3352 3341
-f 3325 3309 3323
-f 3323 3341 3325
-f 3313 3300 3309
-f 3309 3325 3313
-f 3301 3284 3300
-f 3300 3313 3301
-f 3289 3274 3284
-f 3284 3301 3289
-f 3281 3269 3274
-f 3274 3289 3281
-f 3277 3267 3269
-f 3269 3281 3277
-f 3403 3372 3378
-f 3378 3405 3403
-f 3393 3367 3372
-f 3372 3403 3393
-f 3377 3352 3367
-f 3367 3393 3377
-f 3360 3341 3352
-f 3352 3377 3360
-f 3344 3325 3341
-f 3341 3360 3344
-f 3327 3313 3325
-f 3325 3344 3327
-f 3317 3301 3313
-f 3313 3327 3317
-f 3305 3289 3301
-f 3301 3317 3305
-f 3296 3281 3289
-f 3289 3305 3296
-f 3291 3277 3281
-f 3281 3296 3291
-f 3469 3403 3405
-f 3405 3472 3469
-f 3450 3393 3403
-f 3403 3469 3450
-f 3426 3377 3393
-f 3393 3450 3426
-f 3390 3360 3377
-f 3377 3426 3390
-f 3370 3344 3360
-f 3360 3390 3370
-f 3349 3327 3344
-f 3344 3370 3349
-f 3337 3317 3327
-f 3327 3349 3337
-f 3319 3305 3317
-f 3317 3337 3319
-f 3311 3296 3305
-f 3305 3319 3311
-f 3307 3291 3296
-f 3296 3311 3307
-f 3520 3469 3472
-f 3472 3522 3520
-f 3504 3450 3469
-f 3469 3520 3504
-f 3489 3426 3450
-f 3450 3504 3489
-f 3463 3390 3426
-f 3426 3489 3463
-f 3421 3370 3390
-f 3390 3463 3421
-f 3385 3349 3370
-f 3370 3421 3385
-f 3361 3337 3349
-f 3349 3385 3361
-f 3342 3319 3337
-f 3337 3361 3342
-f 3334 3311 3319
-f 3319 3342 3334
-f 3328 3307 3311
-f 3311 3334 3328
-f 3591 3520 3522
-f 3522 3603 3591
-f 3578 3504 3520
-f 3520 3591 3578
-f 3552 3489 3504
-f 3504 3578 3552
-f 3530 3463 3489
-f 3489 3552 3530
-f 3499 3421 3463
-f 3463 3530 3499
-f 3467 3385 3421
-f 3421 3499 3467
-f 3415 3361 3385
-f 3385 3467 3415
-f 3381 3342 3361
-f 3361 3415 3381
-f 3363 3334 3342
-f 3342 3381 3363
-f 3356 3328 3334
-f 3334 3363 3356
-f 3374 3365 3358
-f 3358 3371 3374
-f 3395 3383 3365
-f 3365 3374 3395
-f 3443 3417 3383
-f 3383 3395 3443
-f 3481 3466 3417
-f 3417 3443 3481
-f 3514 3496 3466
-f 3466 3481 3514
-f 3545 3529 3496
-f 3496 3514 3545
-f 3573 3551 3529
-f 3529 3545 3573
-f 3597 3577 3551
-f 3551 3573 3597
-f 3613 3590 3577
-f 3577 3597 3613
-f 3619 3603 3590
-f 3590 3613 3619
-f 3387 3374 3371
-f 3371 3380 3387
-f 3413 3395 3374
-f 3374 3387 3413
-f 3461 3443 3395
-f 3395 3413 3461
-f 3493 3481 3443
-f 3443 3461 3493
-f 3524 3514 3481
-f 3481 3493 3524
-f 3556 3545 3514
-f 3514 3524 3556
-f 3584 3573 3545
-f 3545 3556 3584
-f 3611 3597 3573
-f 3573 3584 3611
-f 3628 3613 3597
-f 3597 3611 3628
-f 3632 3619 3613
-f 3613 3628 3632
-f 3398 3387 3380
-f 3380 3391 3398
-f 3435 3413 3387
-f 3387 3398 3435
-f 3473 3461 3413
-f 3413 3435 3473
-f 3500 3493 3461
-f 3461 3473 3500
-f 3531 3524 3493
-f 3493 3500 3531
-f 3562 3556 3524
-f 3524 3531 3562
-f 3595 3584 3556
-f 3556 3562 3595
-f 3617 3611 3584
-f 3584 3595 3617
-f 3633 3628 3611
-f 3611 3617 3633
-f 3641 3632 3628
-f 3628 3633 3641
-f 3409 3398 3391
-f 3391 3400 3409
-f 3447 3435 3398
-f 3398 3409 3447
-f 3477 3473 3435
-f 3435 3447 3477
-f 3506 3500 3473
-f 3473 3477 3506
-f 3540 3531 3500
-f 3500 3506 3540
-f 3567 3562 3531
-f 3531 3540 3567
-f 3601 3595 3562
-f 3562 3567 3601
-f 3624 3617 3595
-f 3595 3601 3624
-f 3639 3633 3617
-f 3617 3624 3639
-f 3644 3641 3633
-f 3633 3639 3644
-f 3433 3409 3400
-f 3400 3411 3433
-f 3453 3447 3409
-f 3409 3433 3453
-f 3483 3477 3447
-f 3447 3453 3483
-f 3510 3506 3477
-f 3477 3483 3510
-f 3543 3540 3506
-f 3506 3510 3543
-f 3569 3567 3540
-f 3540 3543 3569
-f 3599 3601 3567
-f 3567 3569 3599
-f 3622 3624 3601
-f 3601 3599 3622
-f 3637 3639 3624
-f 3624 3622 3637
-f 3642 3644 3639
-f 3639 3637 3642
-f 3439 3433 3411
-f 3411 3424 3439
-f 3458 3453 3433
-f 3433 3439 3458
-f 3487 3483 3453
-f 3453 3458 3487
-f 3513 3510 3483
-f 3483 3487 3513
-f 3542 3543 3510
-f 3510 3513 3542
-f 3566 3569 3543
-f 3543 3542 3566
-f 3593 3599 3569
-f 3569 3566 3593
-f 3616 3622 3599
-f 3599 3593 3616
-f 3630 3637 3622
-f 3622 3616 3630
-f 3636 3642 3637
-f 3637 3630 3636
-f 3441 3439 3424
-f 3424 3429 3441
-f 3459 3458 3439
-f 3439 3441 3459
-f 3485 3487 3458
-f 3458 3459 3485
-f 3508 3513 3487
-f 3487 3485 3508
-f 3533 3542 3513
-f 3513 3508 3533
-f 3558 3566 3542
-f 3542 3533 3558
-f 3582 3593 3566
-f 3566 3558 3582
-f 3607 3616 3593
-f 3593 3582 3607
-f 3620 3630 3616
-f 3616 3607 3620
-f 3626 3636 3630
-f 3630 3620 3626
-f 3437 3441 3429
-f 3429 3427 3437
-f 3455 3459 3441
-f 3441 3437 3455
-f 3479 3485 3459
-f 3459 3455 3479
-f 3502 3508 3485
-f 3485 3479 3502
-f 3526 3533 3508
-f 3508 3502 3526
-f 3547 3558 3533
-f 3533 3526 3547
-f 3571 3582 3558
-f 3558 3547 3571
-f 3588 3607 3582
-f 3582 3571 3588
-f 3605 3620 3607
-f 3607 3588 3605
-f 3609 3626 3620
-f 3620 3605 3609
-f 3419 3437 3427
-f 3427 3408 3419
-f 3445 3455 3437
-f 3437 3419 3445
-f 3470 3479 3455
-f 3455 3445 3470
-f 3492 3502 3479
-f 3479 3470 3492
-f 3517 3526 3502
-f 3502 3492 3517
-f 3536 3547 3526
-f 3526 3517 3536
-f 3554 3571 3547
-f 3547 3536 3554
-f 3575 3588 3571
-f 3571 3554 3575
-f 3580 3605 3588
-f 3588 3575 3580
-f 3587 3609 3605
-f 3605 3580 3587
-f 3401 3419 3408
-f 3408 3397 3401
-f 3431 3445 3419
-f 3419 3401 3431
-f 3451 3470 3445
-f 3445 3431 3451
-f 3475 3492 3470
-f 3470 3451 3475
-f 3497 3517 3492
-f 3492 3475 3497
-f 3518 3536 3517
-f 3517 3497 3518
-f 3537 3554 3536
-f 3536 3518 3537
-f 3549 3575 3554
-f 3554 3537 3549
-f 3560 3580 3575
-f 3575 3549 3560
-f 3564 3587 3580
-f 3580 3560 3564
-f 3614 3591 3603
-f 3603 3619 3614
-f 3598 3578 3591
-f 3591 3614 3598
-f 3574 3552 3578
-f 3578 3598 3574
-f 3546 3530 3552
-f 3552 3574 3546
-f 3515 3499 3530
-f 3530 3546 3515
-f 3482 3467 3499
-f 3499 3515 3482
-f 3444 3418 3467
-f 3467 3482 3444
-f 3396 3384 3418
-f 3418 3444 3396
-f 3375 3366 3384
-f 3384 3396 3375
-f 3371 3358 3366
-f 3366 3375 3371
-f 3629 3614 3619
-f 3619 3632 3629
-f 3612 3598 3614
-f 3614 3629 3612
-f 3585 3574 3598
-f 3598 3612 3585
-f 3557 3546 3574
-f 3574 3585 3557
-f 3525 3515 3546
-f 3546 3557 3525
-f 3494 3482 3515
-f 3515 3525 3494
-f 3462 3444 3482
-f 3482 3494 3462
-f 3414 3396 3444
-f 3444 3462 3414
-f 3388 3375 3396
-f 3396 3414 3388
-f 3380 3371 3375
-f 3375 3388 3380
-f 3634 3629 3632
-f 3632 3641 3634
-f 3618 3612 3629
-f 3629 3634 3618
-f 3596 3585 3612
-f 3612 3618 3596
-f 3563 3557 3585
-f 3585 3596 3563
-f 3532 3525 3557
-f 3557 3563 3532
-f 3501 3494 3525
-f 3525 3532 3501
-f 3474 3462 3494
-f 3494 3501 3474
-f 3436 3414 3462
-f 3462 3474 3436
-f 3399 3388 3414
-f 3414 3436 3399
-f 3392 3380 3388
-f 3388 3399 3392
-f 3640 3634 3641
-f 3641 3644 3640
-f 3625 3618 3634
-f 3634 3640 3625
-f 3602 3596 3618
-f 3618 3625 3602
-f 3568 3563 3596
-f 3596 3602 3568
-f 3539 3532 3563
-f 3563 3568 3539
-f 3507 3501 3532
-f 3532 3539 3507
-f 3478 3474 3501
-f 3501 3507 3478
-f 3448 3436 3474
-f 3474 3478 3448
-f 3410 3399 3436
-f 3436 3448 3410
-f 3400 3392 3399
-f 3399 3410 3400
-f 3638 3640 3644
-f 3644 3643 3638
-f 3623 3625 3640
-f 3640 3638 3623
-f 3600 3602 3625
-f 3625 3623 3600
-f 3570 3568 3602
-f 3602 3600 3570
-f 3544 3539 3568
-f 3568 3570 3544
-f 3511 3507 3539
-f 3539 3544 3511
-f 3484 3478 3507
-f 3507 3511 3484
-f 3454 3448 3478
-f 3478 3484 3454
-f 3434 3410 3448
-f 3448 3454 3434
-f 3412 3400 3410
-f 3410 3434 3412
-f 3631 3638 3643
-f 3643 3635 3631
-f 3615 3623 3638
-f 3638 3631 3615
-f 3594 3600 3623
-f 3623 3615 3594
-f 3565 3570 3600
-f 3600 3594 3565
-f 3541 3544 3570
-f 3570 3565 3541
-f 3512 3511 3544
-f 3544 3541 3512
-f 3488 3484 3511
-f 3511 3512 3488
-f 3457 3454 3484
-f 3484 3488 3457
-f 3440 3434 3454
-f 3454 3457 3440
-f 3423 3412 3434
-f 3434 3440 3423
-f 3621 3631 3635
-f 3635 3627 3621
-f 3608 3615 3631
-f 3631 3621 3608
-f 3583 3594 3615
-f 3615 3608 3583
-f 3559 3565 3594
-f 3594 3583 3559
-f 3534 3541 3565
-f 3565 3559 3534
-f 3509 3512 3541
-f 3541 3534 3509
-f 3486 3488 3512
-f 3512 3509 3486
-f 3460 3457 3488
-f 3488 3486 3460
-f 3442 3440 3457
-f 3457 3460 3442
-f 3430 3423 3440
-f 3440 3442 3430
-f 3606 3621 3627
-f 3627 3610 3606
-f 3589 3608 3621
-f 3621 3606 3589
-f 3572 3583 3608
-f 3608 3589 3572
-f 3548 3559 3583
-f 3583 3572 3548
-f 3527 3534 3559
-f 3559 3548 3527
-f 3503 3509 3534
-f 3534 3527 3503
-f 3480 3486 3509
-f 3509 3503 3480
-f 3456 3460 3486
-f 3486 3480 3456
-f 3438 3442 3460
-f 3460 3456 3438
-f 3428 3430 3442
-f 3442 3438 3428
-f 3581 3606 3610
-f 3610 3586 3581
-f 3576 3589 3606
-f 3606 3581 3576
-f 3555 3572 3589
-f 3589 3576 3555
-f 3535 3548 3572
-f 3572 3555 3535
-f 3516 3527 3548
-f 3548 3535 3516
-f 3491 3503 3527
-f 3527 3516 3491
-f 3471 3480 3503
-f 3503 3491 3471
-f 3446 3456 3480
-f 3480 3471 3446
-f 3420 3438 3456
-f 3456 3446 3420
-f 3407 3428 3438
-f 3438 3420 3407
-f 3561 3581 3586
-f 3586 3564 3561
-f 3550 3576 3581
-f 3581 3561 3550
-f 3538 3555 3576
-f 3576 3550 3538
-f 3519 3535 3555
-f 3555 3538 3519
-f 3498 3516 3535
-f 3535 3519 3498
-f 3476 3491 3516
-f 3516 3498 3476
-f 3452 3471 3491
-f 3491 3476 3452
-f 3432 3446 3471
-f 3471 3452 3432
-f 3402 3420 3446
-f 3446 3432 3402
-f 3397 3407 3420
-f 3420 3402 3397
-f 1888 2110 2104
-f 1888 2104 2096
-f 1888 2096 2076
-f 1888 2076 2048
-f 1888 2048 2030
-f 1888 2030 2006
-f 1888 2006 1982
-f 1888 1982 1960
-f 1888 1960 1936
-f 1888 1936 1732
-f 2257 2104 2110
-f 2110 2261 2257
-f 2249 2096 2104
-f 2104 2257 2249
-f 2226 2076 2096
-f 2096 2249 2226
-f 2200 2048 2076
-f 2076 2226 2200
-f 2142 2030 2048
-f 2048 2200 2142
-f 2094 2006 2030
-f 2030 2142 2094
-f 2036 1982 2006
-f 2006 2094 2036
-f 1988 1960 1982
-f 1982 2036 1988
-f 1948 1936 1960
-f 1960 1988 1948
-f 1728 1732 1936
-f 1936 1948 1728
-f 2310 2257 2261
-f 2261 2315 2310
-f 2300 2249 2257
-f 2257 2310 2300
-f 2279 2226 2249
-f 2249 2300 2279
-f 2243 2200 2226
-f 2226 2279 2243
-f 2204 2142 2200
-f 2200 2243 2204
-f 2132 2094 2142
-f 2142 2204 2132
-f 2067 2036 2094
-f 2094 2132 2067
-f 2000 1988 2036
-f 2036 2067 2000
-f 1956 1948 1988
-f 1988 2000 1956
-f 1734 1728 1948
-f 1948 1956 1734
-f 2312 2310 2315
-f 2315 2316 2312
-f 2302 2300 2310
-f 2310 2312 2302
-f 2281 2279 2300
-f 2300 2302 2281
-f 2245 2243 2279
-f 2279 2281 2245
-f 2206 2204 2243
-f 2243 2245 2206
-f 2134 2132 2204
-f 2204 2206 2134
-f 2068 2067 2132
-f 2132 2134 2068
-f 2002 2000 2067
-f 2067 2068 2002
-f 1958 1956 2000
-f 2000 2002 1958
-f 1878 1734 1956
-f 1956 1958 1878
-f 2285 2312 2316
-f 2316 2289 2285
-f 2259 2302 2312
-f 2312 2285 2259
-f 2241 2281 2302
-f 2302 2259 2241
-f 2214 2245 2281
-f 2281 2241 2214
-f 2168 2206 2245
-f 2245 2214 2168
-f 2106 2134 2206
-f 2206 2168 2106
-f 2042 2068 2134
-f 2134 2106 2042
-f 1994 2002 2068
-f 2068 2042 1994
-f 1952 1958 2002
-f 2002 1994 1952
-f 1731 1878 1958
-f 1958 1952 1731
-f 2220 2285 2289
-f 2289 2225 2220
-f 2210 2259 2285
-f 2285 2220 2210
-f 2186 2241 2259
-f 2259 2210 2186
-f 2146 2214 2241
-f 2241 2186 2146
-f 2108 2168 2214
-f 2214 2146 2108
-f 2060 2106 2168
-f 2168 2108 2060
-f 2018 2042 2106
-f 2106 2060 2018
-f 1978 1994 2042
-f 2042 2018 1978
-f 1944 1952 1994
-f 1994 1978 1944
-f 1727 1731 1952
-f 1952 1944 1727
-f 2141 2220 2225
-f 2225 2145 2141
-f 2127 2210 2220
-f 2220 2141 2127
-f 2112 2186 2210
-f 2210 2127 2112
-f 2084 2146 2186
-f 2186 2112 2084
-f 2044 2108 2146
-f 2146 2084 2044
-f 2024 2060 2108
-f 2108 2044 2024
-f 1992 2018 2060
-f 2060 2024 1992
-f 1970 1978 2018
-f 2018 1992 1970
-f 1942 1944 1978
-f 1978 1970 1942
-f 1721 1727 1944
-f 1944 1942 1721
-f 2079 2141 2145
-f 2145 2087 2079
-f 2075 2127 2141
-f 2141 2079 2075
-f 2055 2112 2127
-f 2127 2075 2055
-f 2039 2084 2112
-f 2112 2055 2039
-f 2021 2044 2084
-f 2084 2039 2021
-f 1996 2024 2044
-f 2044 2021 1996
-f 1974 1992 2024
-f 2024 1996 1974
-f 1954 1970 1992
-f 1992 1974 1954
-f 1934 1942 1970
-f 1970 1954 1934
-f 1720 1721 1942
-f 1942 1934 1720
-f 2063 2079 2087
-f 2087 2071 2063
-f 2051 2075 2079
-f 2079 2063 2051
-f 2041 2055 2075
-f 2075 2051 2041
-f 2029 2039 2055
-f 2055 2041 2029
-f 2013 2021 2039
-f 2039 2029 2013
-f 1991 1996 2021
-f 2021 2013 1991
-f 1972 1974 1996
-f 1996 1991 1972
-f 1950 1954 1974
-f 1974 1972 1950
-f 1932 1934 1954
-f 1954 1950 1932
-f 1701 1720 1934
-f 1934 1932 1701
-f 2115 2063 2071
-f 2071 2123 2115
-f 2101 2051 2063
-f 2063 2115 2101
-f 2081 2041 2051
-f 2051 2101 2081
-f 2057 2029 2041
-f 2041 2081 2057
-f 2033 2013 2029
-f 2029 2057 2033
-f 2009 1991 2013
-f 2013 2033 2009
-f 1984 1972 1991
-f 1991 2009 1984
-f 1964 1950 1972
-f 1972 1984 1964
-f 1938 1932 1950
-f 1950 1964 1938
-f 1698 1701 1932
-f 1932 1938 1698
-f 1888 1886 1686
-f 1888 1686 1662
-f 1888 1662 1640
-f 1888 1640 1616
-f 1888 1616 1592
-f 1888 1592 1574
-f 1888 1574 1546
-f 1888 1546 1526
-f 1888 1526 1518
-f 1888 1518 1512
-f 1674 1686 1886
-f 1886 1884 1674
-f 1634 1662 1686
-f 1686 1674 1634
-f 1586 1640 1662
-f 1662 1634 1586
-f 1528 1616 1640
-f 1640 1586 1528
-f 1480 1592 1616
-f 1616 1528 1480
-f 1422 1574 1592
-f 1592 1480 1422
-f 1396 1546 1574
-f 1574 1422 1396
-f 1373 1526 1546
-f 1546 1396 1373
-f 1365 1518 1526
-f 1526 1373 1365
-f 1361 1512 1518
-f 1518 1365 1361
-f 1666 1674 1884
-f 1884 1882 1666
-f 1622 1634 1674
-f 1674 1666 1622
-f 1557 1586 1634
-f 1634 1622 1557
-f 1490 1528 1586
-f 1586 1557 1490
-f 1418 1480 1528
-f 1528 1490 1418
-f 1379 1422 1480
-f 1480 1418 1379
-f 1343 1396 1422
-f 1422 1379 1343
-f 1322 1373 1396
-f 1396 1343 1322
-f 1312 1365 1373
-f 1373 1322 1312
-f 1309 1361 1365
-f 1365 1312 1309
-f 1664 1666 1882
-f 1882 1879 1664
-f 1620 1622 1666
-f 1666 1664 1620
-f 1554 1557 1622
-f 1622 1620 1554
-f 1488 1490 1557
-f 1557 1554 1488
-f 1416 1418 1490
-f 1490 1488 1416
-f 1377 1379 1418
-f 1418 1416 1377
-f 1341 1343 1379
-f 1379 1377 1341
-f 1320 1322 1343
-f 1343 1341 1320
-f 1310 1312 1322
-f 1322 1320 1310
-f 1306 1309 1312
-f 1312 1310 1306
-f 1670 1664 1879
-f 1879 1876 1670
-f 1628 1620 1664
-f 1664 1670 1628
-f 1580 1554 1620
-f 1620 1628 1580
-f 1516 1488 1554
-f 1554 1580 1516
-f 1454 1416 1488
-f 1488 1516 1454
-f 1408 1377 1416
-f 1416 1454 1408
-f 1381 1341 1377
-f 1377 1408 1381
-f 1363 1320 1341
-f 1341 1381 1363
-f 1337 1310 1320
-f 1320 1363 1337
-f 1333 1306 1310
-f 1310 1337 1333
-f 1678 1670 1876
-f 1876 1874 1678
-f 1644 1628 1670
-f 1670 1678 1644
-f 1604 1580 1628
-f 1628 1644 1604
-f 1562 1516 1580
-f 1580 1604 1562
-f 1514 1454 1516
-f 1516 1562 1514
-f 1476 1408 1454
-f 1454 1514 1476
-f 1436 1381 1408
-f 1408 1476 1436
-f 1412 1363 1381
-f 1381 1436 1412
-f 1402 1337 1363
-f 1363 1412 1402
-f 1399 1333 1337
-f 1337 1402 1399
-f 1680 1678 1874
-f 1874 1872 1680
-f 1652 1644 1678
-f 1678 1680 1652
-f 1630 1604 1644
-f 1644 1652 1630
-f 1598 1562 1604
-f 1604 1630 1598
-f 1578 1514 1562
-f 1562 1598 1578
-f 1538 1476 1514
-f 1514 1578 1538
-f 1510 1436 1476
-f 1476 1538 1510
-f 1497 1412 1436
-f 1436 1510 1497
-f 1483 1402 1412
-f 1412 1497 1483
-f 1479 1399 1402
-f 1402 1483 1479
-f 1688 1680 1872
-f 1872 1870 1688
-f 1668 1652 1680
-f 1680 1688 1668
-f 1648 1630 1652
-f 1652 1668 1648
-f 1626 1598 1630
-f 1630 1648 1626
-f 1603 1578 1598
-f 1598 1626 1603
-f 1585 1538 1578
-f 1578 1603 1585
-f 1569 1510 1538
-f 1538 1585 1569
-f 1549 1497 1510
-f 1510 1569 1549
-f 1545 1483 1497
-f 1497 1549 1545
-f 1537 1479 1483
-f 1483 1545 1537
-f 1690 1688 1870
-f 1870 1868 1690
-f 1672 1668 1688
-f 1688 1690 1672
-f 1650 1648 1668
-f 1668 1672 1650
-f 1633 1626 1648
-f 1648 1650 1633
-f 1611 1603 1626
-f 1626 1633 1611
-f 1595 1585 1603
-f 1603 1611 1595
-f 1583 1569 1585
-f 1585 1595 1583
-f 1573 1549 1569
-f 1569 1583 1573
-f 1561 1545 1549
-f 1549 1573 1561
-f 1553 1537 1545
-f 1545 1561 1553
-f 1684 1690 1868
-f 1868 1865 1684
-f 1658 1672 1690
-f 1690 1684 1658
-f 1638 1650 1672
-f 1672 1658 1638
-f 1615 1633 1650
-f 1650 1638 1615
-f 1591 1611 1633
-f 1633 1615 1591
-f 1567 1595 1611
-f 1611 1591 1567
-f 1543 1583 1595
-f 1595 1567 1543
-f 1523 1573 1583
-f 1583 1543 1523
-f 1509 1561 1573
-f 1573 1523 1509
-f 1501 1553 1561
-f 1561 1509 1501
-f 1888 1513 1519
-f 1888 1519 1527
-f 1888 1527 1547
-f 1888 1547 1575
-f 1888 1575 1593
-f 1888 1593 1617
-f 1888 1617 1641
-f 1888 1641 1663
-f 1888 1663 1687
-f 1888 1687 1894
-f 1366 1519 1513
-f 1513 1362 1366
-f 1374 1527 1519
-f 1519 1366 1374
-f 1397 1547 1527
-f 1527 1374 1397
-f 1423 1575 1547
-f 1547 1397 1423
-f 1481 1593 1575
-f 1575 1423 1481
-f 1529 1617 1593
-f 1593 1481 1529
-f 1587 1641 1617
-f 1617 1529 1587
-f 1635 1663 1641
-f 1641 1587 1635
-f 1675 1687 1663
-f 1663 1635 1675
-f 1895 1894 1687
-f 1687 1675 1895
-f 1313 1366 1362
-f 1362 1308 1313
-f 1323 1374 1366
-f 1366 1313 1323
-f 1344 1397 1374
-f 1374 1323 1344
-f 1380 1423 1397
-f 1397 1344 1380
-f 1419 1481 1423
-f 1423 1380 1419
-f 1491 1529 1481
-f 1481 1419 1491
-f 1556 1587 1529
-f 1529 1491 1556
-f 1623 1635 1587
-f 1587 1556 1623
-f 1667 1675 1635
-f 1635 1623 1667
-f 1890 1895 1675
-f 1675 1667 1890
-f 1311 1313 1308
-f 1308 1307 1311
-f 1321 1323 1313
-f 1313 1311 1321
-f 1342 1344 1323
-f 1323 1321 1342
-f 1378 1380 1344
-f 1344 1342 1378
-f 1417 1419 1380
-f 1380 1378 1417
-f 1489 1491 1419
-f 1419 1417 1489
-f 1555 1556 1491
-f 1491 1489 1555
-f 1621 1623 1556
-f 1556 1555 1621
-f 1665 1667 1623
-f 1623 1621 1665
-f 1881 1890 1667
-f 1667 1665 1881
-f 1338 1311 1307
-f 1307 1334 1338
-f 1364 1321 1311
-f 1311 1338 1364
-f 1382 1342 1321
-f 1321 1364 1382
-f 1409 1378 1342
-f 1342 1382 1409
-f 1455 1417 1378
-f 1378 1409 1455
-f 1517 1489 1417
-f 1417 1455 1517
-f 1581 1555 1489
-f 1489 1517 1581
-f 1629 1621 1555
-f 1555 1581 1629
-f 1671 1665 1621
-f 1621 1629 1671
-f 1893 1881 1665
-f 1665 1671 1893
-f 1403 1338 1334
-f 1334 1398 1403
-f 1413 1364 1338
-f 1338 1403 1413
-f 1437 1382 1364
-f 1364 1413 1437
-f 1477 1409 1382
-f 1382 1437 1477
-f 1515 1455 1409
-f 1409 1477 1515
-f 1563 1517 1455
-f 1455 1515 1563
-f 1605 1581 1517
-f 1517 1563 1605
-f 1645 1629 1581
-f 1581 1605 1645
-f 1679 1671 1629
-f 1629 1645 1679
-f 1900 1893 1671
-f 1671 1679 1900
-f 1482 1403 1398
-f 1398 1478 1482
-f 1496 1413 1403
-f 1403 1482 1496
-f 1511 1437 1413
-f 1413 1496 1511
-f 1539 1477 1437
-f 1437 1511 1539
-f 1579 1515 1477
-f 1477 1539 1579
-f 1599 1563 1515
-f 1515 1579 1599
-f 1631 1605 1563
-f 1563 1599 1631
-f 1653 1645 1605
-f 1605 1631 1653
-f 1681 1679 1645
-f 1645 1653 1681
-f 1902 1900 1679
-f 1679 1681 1902
-f 1544 1482 1478
-f 1478 1536 1544
-f 1548 1496 1482
-f 1482 1544 1548
-f 1568 1511 1496
-f 1496 1548 1568
-f 1584 1539 1511
-f 1511 1568 1584
-f 1602 1579 1539
-f 1539 1584 1602
-f 1627 1599 1579
-f 1579 1602 1627
-f 1649 1631 1599
-f 1599 1627 1649
-f 1669 1653 1631
-f 1631 1649 1669
-f 1689 1681 1653
-f 1653 1669 1689
-f 1921 1902 1681
-f 1681 1689 1921
-f 1560 1544 1536
-f 1536 1552 1560
-f 1572 1548 1544
-f 1544 1560 1572
-f 1582 1568 1548
-f 1548 1572 1582
-f 1594 1584 1568
-f 1568 1582 1594
-f 1610 1602 1584
-f 1584 1594 1610
-f 1632 1627 1602
-f 1602 1610 1632
-f 1651 1649 1627
-f 1627 1632 1651
-f 1673 1669 1649
-f 1649 1651 1673
-f 1691 1689 1669
-f 1669 1673 1691
-f 1922 1921 1689
-f 1689 1691 1922
-f 1508 1560 1552
-f 1552 1500 1508
-f 1522 1572 1560
-f 1560 1508 1522
-f 1542 1582 1572
-f 1572 1522 1542
-f 1566 1594 1582
-f 1582 1542 1566
-f 1590 1610 1594
-f 1594 1566 1590
-f 1614 1632 1610
-f 1610 1590 1614
-f 1639 1651 1632
-f 1632 1614 1639
-f 1659 1673 1651
-f 1651 1639 1659
-f 1685 1691 1673
-f 1673 1659 1685
-f 1928 1922 1691
-f 1691 1685 1928
-f 1888 1887 1937
-f 1888 1937 1961
-f 1888 1961 1983
-f 1888 1983 2007
-f 1888 2007 2031
-f 1888 2031 2049
-f 1888 2049 2077
-f 1888 2077 2097
-f 1888 2097 2105
-f 1888 2105 2111
-f 1949 1937 1887
-f 1887 1885 1949
-f 1989 1961 1937
-f 1937 1949 1989
-f 2037 1983 1961
-f 1961 1989 2037
-f 2095 2007 1983
-f 1983 2037 2095
-f 2143 2031 2007
-f 2007 2095 2143
-f 2201 2049 2031
-f 2031 2143 2201
-f 2227 2077 2049
-f 2049 2201 2227
-f 2250 2097 2077
-f 2077 2227 2250
-f 2258 2105 2097
-f 2097 2250 2258
-f 2262 2111 2105
-f 2105 2258 2262
-f 1957 1949 1885
-f 1885 1883 1957
-f 2001 1989 1949
-f 1949 1957 2001
-f 2066 2037 1989
-f 1989 2001 2066
-f 2133 2095 2037
-f 2037 2066 2133
-f 2205 2143 2095
-f 2095 2133 2205
-f 2244 2201 2143
-f 2143 2205 2244
-f 2280 2227 2201
-f 2201 2244 2280
-f 2301 2250 2227
-f 2227 2280 2301
-f 2311 2258 2250
-f 2250 2301 2311
-f 2314 2262 2258
-f 2258 2311 2314
-f 1959 1957 1883
-f 1883 1880 1959
-f 2003 2001 1957
-f 1957 1959 2003
-f 2069 2066 2001
-f 2001 2003 2069
-f 2135 2133 2066
-f 2066 2069 2135
-f 2207 2205 2133
-f 2133 2135 2207
-f 2246 2244 2205
-f 2205 2207 2246
-f 2282 2280 2244
-f 2244 2246 2282
-f 2303 2301 2280
-f 2280 2282 2303
-f 2313 2311 2301
-f 2301 2303 2313
-f 2317 2314 2311
-f 2311 2313 2317
-f 1953 1959 1880
-f 1880 1877 1953
-f 1995 2003 1959
-f 1959 1953 1995
-f 2043 2069 2003
-f 2003 1995 2043
-f 2107 2135 2069
-f 2069 2043 2107
-f 2169 2207 2135
-f 2135 2107 2169
-f 2215 2246 2207
-f 2207 2169 2215
-f 2242 2282 2246
-f 2246 2215 2242
-f 2260 2303 2282
-f 2282 2242 2260
-f 2286 2313 2303
-f 2303 2260 2286
-f 2290 2317 2313
-f 2313 2286 2290
-f 1945 1953 1877
-f 1877 1875 1945
-f 1979 1995 1953
-f 1953 1945 1979
-f 2019 2043 1995
-f 1995 1979 2019
-f 2061 2107 2043
-f 2043 2019 2061
-f 2109 2169 2107
-f 2107 2061 2109
-f 2147 2215 2169
-f 2169 2109 2147
-f 2187 2242 2215
-f 2215 2147 2187
-f 2211 2260 2242
-f 2242 2187 2211
-f 2221 2286 2260
-f 2260 2211 2221
-f 2224 2290 2286
-f 2286 2221 2224
-f 1943 1945 1875
-f 1875 1873 1943
-f 1971 1979 1945
-f 1945 1943 1971
-f 1993 2019 1979
-f 1979 1971 1993
-f 2025 2061 2019
-f 2019 1993 2025
-f 2045 2109 2061
-f 2061 2025 2045
-f 2085 2147 2109
-f 2109 2045 2085
-f 2113 2187 2147
-f 2147 2085 2113
-f 2126 2211 2187
-f 2187 2113 2126
-f 2140 2221 2211
-f 2211 2126 2140
-f 2144 2224 2221
-f 2221 2140 2144
-f 1935 1943 1873
-f 1873 1871 1935
-f 1955 1971 1943
-f 1943 1935 1955
-f 1975 1993 1971
-f 1971 1955 1975
-f 1997 2025 1993
-f 1993 1975 1997
-f 2020 2045 2025
-f 2025 1997 2020
-f 2038 2085 2045
-f 2045 2020 2038
-f 2054 2113 2085
-f 2085 2038 2054
-f 2074 2126 2113
-f 2113 2054 2074
-f 2078 2140 2126
-f 2126 2074 2078
-f 2086 2144 2140
-f 2140 2078 2086
-f 1933 1935 1871
-f 1871 1869 1933
-f 1951 1955 1935
-f 1935 1933 1951
-f 1973 1975 1955
-f 1955 1951 1973
-f 1990 1997 1975
-f 1975 1973 1990
-f 2012 2020 1997
-f 1997 1990 2012
-f 2028 2038 2020
-f 2020 2012 2028
-f 2040 2054 2038
-f 2038 2028 2040
-f 2050 2074 2054
-f 2054 2040 2050
-f 2062 2078 2074
-f 2074 2050 2062
-f 2070 2086 2078
-f 2078 2062 2070
-f 1939 1933 1869
-f 1869 1866 1939
-f 1965 1951 1933
-f 1933 1939 1965
-f 1985 1973 1951
-f 1951 1965 1985
-f 2008 1990 1973
-f 1973 1985 2008
-f 2032 2012 1990
-f 1990 2008 2032
-f 2056 2028 2012
-f 2012 2032 2056
-f 2080 2040 2028
-f 2028 2056 2080
-f 2100 2050 2040
-f 2040 2080 2100
-f 2114 2062 2050
-f 2050 2100 2114
-f 2122 2070 2062
-f 2062 2114 2122
-f 2232 2116 2124
-f 2124 2236 2232
-f 2218 2102 2116
-f 2116 2232 2218
-f 2199 2082 2102
-f 2102 2218 2199
-f 2150 2058 2082
-f 2082 2199 2150
-f 2120 2034 2058
-f 2058 2150 2120
-f 2064 2010 2034
-f 2034 2120 2064
-f 2023 1986 2010
-f 2010 2064 2023
-f 1980 1966 1986
-f 1986 2023 1980
-f 1946 1940 1966
-f 1966 1980 1946
-f 1862 1730 1940
-f 1940 1946 1862
-f 2332 2232 2236
-f 2236 2336 2332
-f 2322 2218 2232
-f 2232 2332 2322
-f 2306 2199 2218
-f 2218 2322 2306
-f 2275 2150 2199
-f 2199 2306 2275
-f 2234 2120 2150
-f 2150 2275 2234
-f 2170 2064 2120
-f 2120 2234 2170
-f 2093 2023 2064
-f 2064 2170 2093
-f 2016 1980 2023
-f 2023 2093 2016
-f 1968 1946 1980
-f 1980 2016 1968
-f 1858 1862 1946
-f 1946 1968 1858
-f 2409 2332 2336
-f 2336 2413 2409
-f 2400 2322 2332
-f 2332 2409 2400
-f 2376 2306 2322
-f 2322 2400 2376
-f 2349 2275 2306
-f 2306 2376 2349
-f 2324 2234 2275
-f 2275 2349 2324
-f 2271 2170 2234
-f 2234 2324 2271
-f 2185 2093 2170
-f 2170 2271 2185
-f 2072 2016 2093
-f 2093 2185 2072
-f 1976 1968 2016
-f 2016 2072 1976
-f 1729 1858 1968
-f 1968 1976 1729
-f 2488 2409 2413
-f 2413 2498 2488
-f 2470 2400 2409
-f 2409 2488 2470
-f 2444 2376 2400
-f 2400 2470 2444
-f 2418 2349 2376
-f 2376 2444 2418
-f 2384 2324 2349
-f 2349 2418 2384
-f 2338 2271 2324
-f 2324 2384 2338
-f 2269 2185 2271
-f 2271 2338 2269
-f 2138 2072 2185
-f 2185 2269 2138
-f 1998 1976 2072
-f 2072 2138 1998
-f 1722 1729 1976
-f 1976 1998 1722
-f 2559 2488 2498
-f 2498 2569 2559
-f 2549 2470 2488
-f 2488 2559 2549
-f 2531 2444 2470
-f 2470 2549 2531
-f 2492 2418 2444
-f 2444 2531 2492
-f 2436 2384 2418
-f 2418 2492 2436
-f 2394 2338 2384
-f 2384 2436 2394
-f 2326 2269 2338
-f 2338 2394 2326
-f 2212 2138 2269
-f 2269 2326 2212
-f 2026 1998 2138
-f 2138 2212 2026
-f 1850 1722 1998
-f 1998 2026 1850
-f 2653 2559 2569
-f 2569 2655 2653
-f 2631 2549 2559
-f 2559 2653 2631
-f 2593 2531 2549
-f 2549 2631 2593
-f 2551 2492 2531
-f 2531 2593 2551
-f 2510 2436 2492
-f 2492 2551 2510
-f 2432 2394 2436
-f 2436 2510 2432
-f 2366 2326 2394
-f 2394 2432 2366
-f 2263 2212 2326
-f 2326 2366 2263
-f 2052 2026 2212
-f 2212 2263 2052
-f 1726 1850 2026
-f 2026 2052 1726
-f 2720 2653 2655
-f 2655 2726 2720
-f 2697 2631 2653
-f 2653 2720 2697
-f 2662 2593 2631
-f 2631 2697 2662
-f 2607 2551 2593
-f 2593 2662 2607
-f 2547 2510 2551
-f 2551 2607 2547
-f 2484 2432 2510
-f 2510 2547 2484
-f 2405 2366 2432
-f 2432 2484 2405
-f 2308 2263 2366
-f 2366 2405 2308
-f 2090 2052 2263
-f 2263 2308 2090
-f 1719 1726 2052
-f 2052 2090 1719
-f 2787 2720 2726
-f 2726 2795 2787
-f 2759 2697 2720
-f 2720 2787 2759
-f 2713 2662 2697
-f 2697 2759 2713
-f 2657 2607 2662
-f 2662 2713 2657
-f 2589 2547 2607
-f 2607 2657 2589
-f 2525 2484 2547
-f 2547 2589 2525
-f 2422 2405 2484
-f 2484 2525 2422
-f 2330 2308 2405
-f 2405 2422 2330
-f 2118 2090 2308
-f 2308 2330 2118
-f 1700 1719 2090
-f 2090 2118 1700
-f 2834 2787 2795
-f 2795 2844 2834
-f 2798 2759 2787
-f 2787 2834 2798
-f 2750 2713 2759
-f 2759 2798 2750
-f 2690 2657 2713
-f 2713 2750 2690
-f 2624 2589 2657
-f 2657 2690 2624
-f 2536 2525 2589
-f 2589 2624 2536
-f 2441 2422 2525
-f 2525 2536 2441
-f 2340 2330 2422
-f 2422 2441 2340
-f 2128 2118 2330
-f 2330 2340 2128
-f 1825 1700 2118
-f 2118 2128 1825
-f 2847 2834 2844
-f 2844 2857 2847
-f 2821 2798 2834
-f 2834 2847 2821
-f 2765 2750 2798
-f 2798 2821 2765
-f 2703 2690 2750
-f 2750 2765 2703
-f 2637 2624 2690
-f 2690 2703 2637
-f 2543 2536 2624
-f 2624 2637 2543
-f 2446 2441 2536
-f 2536 2543 2446
-f 2344 2340 2441
-f 2441 2446 2344
-f 2136 2128 2340
-f 2340 2344 2136
-f 1713 1825 2128
-f 2128 2136 1713
-f 1676 1682 1864
-f 1864 1862 1676
-f 1642 1656 1682
-f 1682 1676 1642
-f 1601 1636 1656
-f 1656 1642 1601
-f 1558 1612 1636
-f 1636 1601 1558
-f 1502 1588 1612
-f 1612 1558 1502
-f 1472 1564 1588
-f 1588 1502 1472
-f 1425 1540 1564
-f 1564 1472 1425
-f 1404 1520 1540
-f 1540 1425 1404
-f 1390 1506 1520
-f 1520 1404 1390
-f 1387 1498 1506
-f 1506 1390 1387
-f 1654 1676 1862
-f 1862 1859 1654
-f 1606 1642 1676
-f 1676 1654 1606
-f 1531 1601 1642
-f 1642 1606 1531
-f 1452 1558 1601
-f 1601 1531 1452
-f 1388 1502 1558
-f 1558 1452 1388
-f 1347 1472 1502
-f 1502 1388 1347
-f 1316 1425 1472
-f 1472 1347 1316
-f 1300 1404 1425
-f 1425 1316 1300
-f 1290 1390 1404
-f 1404 1300 1290
-f 1286 1387 1390
-f 1390 1290 1286
-f 1646 1654 1859
-f 1859 1856 1646
-f 1550 1606 1654
-f 1654 1646 1550
-f 1439 1531 1606
-f 1606 1550 1439
-f 1351 1452 1531
-f 1531 1439 1351
-f 1298 1388 1452
-f 1452 1351 1298
-f 1275 1347 1388
-f 1388 1298 1275
-f 1246 1316 1347
-f 1347 1275 1246
-f 1222 1300 1316
-f 1316 1246 1222
-f 1215 1290 1300
-f 1300 1222 1215
-f 1211 1286 1290
-f 1290 1215 1211
-f 1624 1646 1856
-f 1856 1854 1624
-f 1484 1550 1646
-f 1646 1624 1484
-f 1353 1439 1550
-f 1550 1484 1353
-f 1284 1351 1439
-f 1439 1353 1284
-f 1238 1298 1351
-f 1351 1284 1238
-f 1204 1275 1298
-f 1298 1238 1204
-f 1178 1246 1275
-f 1275 1204 1178
-f 1152 1222 1246
-f 1246 1178 1152
-f 1134 1215 1222
-f 1222 1152 1134
-f 1124 1211 1215
-f 1215 1134 1124
-f 1596 1624 1854
-f 1854 1851 1596
-f 1410 1484 1624
-f 1624 1596 1410
-f 1296 1353 1484
-f 1484 1410 1296
-f 1228 1284 1353
-f 1353 1296 1228
-f 1186 1238 1284
-f 1284 1228 1186
-f 1130 1204 1238
-f 1238 1186 1130
-f 1091 1178 1204
-f 1204 1130 1091
-f 1073 1152 1178
-f 1178 1091 1073
-f 1063 1134 1152
-f 1152 1073 1063
-f 1053 1124 1134
-f 1134 1063 1053
-f 1570 1596 1851
-f 1851 1848 1570
-f 1359 1410 1596
-f 1596 1570 1359
-f 1256 1296 1410
-f 1410 1359 1256
-f 1190 1228 1296
-f 1296 1256 1190
-f 1112 1186 1228
-f 1228 1190 1112
-f 1071 1130 1186
-f 1186 1112 1071
-f 1029 1091 1130
-f 1130 1071 1029
-f 991 1073 1091
-f 1091 1029 991
-f 969 1063 1073
-f 1073 991 969
-f 967 1053 1063
-f 1063 969 967
-f 1532 1570 1848
-f 1848 1846 1532
-f 1314 1359 1570
-f 1570 1532 1314
-f 1219 1256 1359
-f 1359 1314 1219
-f 1138 1190 1256
-f 1256 1219 1138
-f 1075 1112 1190
-f 1190 1138 1075
-f 1015 1071 1112
-f 1112 1075 1015
-f 962 1029 1071
-f 1071 1015 962
-f 925 991 1029
-f 1029 962 925
-f 904 969 991
-f 991 925 904
-f 898 967 969
-f 969 904 898
-f 1504 1532 1846
-f 1846 1832 1504
-f 1292 1314 1532
-f 1532 1504 1292
-f 1200 1219 1314
-f 1314 1292 1200
-f 1097 1138 1219
-f 1219 1200 1097
-f 1033 1075 1138
-f 1138 1097 1033
-f 965 1015 1075
-f 1075 1033 965
-f 909 962 1015
-f 1015 965 909
-f 863 925 962
-f 962 909 863
-f 835 904 925
-f 925 863 835
-f 827 898 904
-f 904 835 827
-f 1494 1504 1832
-f 1832 1824 1494
-f 1282 1292 1504
-f 1504 1494 1282
-f 1183 1200 1292
-f 1292 1282 1183
-f 1088 1097 1200
-f 1200 1183 1088
-f 1000 1033 1097
-f 1097 1088 1000
-f 934 965 1033
-f 1033 1000 934
-f 874 909 965
-f 965 934 874
-f 826 863 909
-f 909 874 826
-f 790 835 863
-f 863 826 790
-f 780 827 835
-f 835 790 780
-f 1486 1494 1824
-f 1824 1814 1486
-f 1278 1282 1494
-f 1494 1486 1278
-f 1176 1183 1282
-f 1282 1278 1176
-f 1079 1088 1183
-f 1183 1176 1079
-f 985 1000 1088
-f 1088 1079 985
-f 919 934 1000
-f 1000 985 919
-f 857 874 934
-f 934 919 857
-f 801 826 874
-f 874 857 801
-f 775 790 826
-f 826 801 775
-f 765 780 790
-f 790 775 765
-f 1391 1507 1499
-f 1499 1387 1391
-f 1405 1521 1507
-f 1507 1391 1405
-f 1424 1541 1521
-f 1521 1405 1424
-f 1473 1565 1541
-f 1541 1424 1473
-f 1503 1589 1565
-f 1565 1473 1503
-f 1559 1613 1589
-f 1589 1503 1559
-f 1600 1637 1613
-f 1613 1559 1600
-f 1643 1657 1637
-f 1637 1600 1643
-f 1677 1683 1657
-f 1657 1643 1677
-f 1863 1892 1683
-f 1683 1677 1863
-f 1291 1391 1387
-f 1387 1287 1291
-f 1301 1405 1391
-f 1391 1291 1301
-f 1317 1424 1405
-f 1405 1301 1317
-f 1348 1473 1424
-f 1424 1317 1348
-f 1389 1503 1473
-f 1473 1348 1389
-f 1453 1559 1503
-f 1503 1389 1453
-f 1530 1600 1559
-f 1559 1453 1530
-f 1607 1643 1600
-f 1600 1530 1607
-f 1655 1677 1643
-f 1643 1607 1655
-f 1861 1863 1677
-f 1677 1655 1861
-f 1214 1291 1287
-f 1287 1210 1214
-f 1223 1301 1291
-f 1291 1214 1223
-f 1247 1317 1301
-f 1301 1223 1247
-f 1274 1348 1317
-f 1317 1247 1274
-f 1299 1389 1348
-f 1348 1274 1299
-f 1352 1453 1389
-f 1389 1299 1352
-f 1438 1530 1453
-f 1453 1352 1438
-f 1551 1607 1530
-f 1530 1438 1551
-f 1647 1655 1607
-f 1607 1551 1647
-f 1891 1861 1655
-f 1655 1647 1891
-f 1135 1214 1210
-f 1210 1125 1135
-f 1153 1223 1214
-f 1214 1135 1153
-f 1179 1247 1223
-f 1223 1153 1179
-f 1205 1274 1247
-f 1247 1179 1205
-f 1239 1299 1274
-f 1274 1205 1239
-f 1285 1352 1299
-f 1299 1239 1285
-f 1354 1438 1352
-f 1352 1285 1354
-f 1485 1551 1438
-f 1438 1354 1485
-f 1625 1647 1551
-f 1551 1485 1625
-f 1901 1891 1647
-f 1647 1625 1901
-f 1064 1135 1125
-f 1125 1054 1064
-f 1074 1153 1135
-f 1135 1064 1074
-f 1092 1179 1153
-f 1153 1074 1092
-f 1131 1205 1179
-f 1179 1092 1131
-f 1187 1239 1205
-f 1205 1131 1187
-f 1229 1285 1239
-f 1239 1187 1229
-f 1297 1354 1285
-f 1285 1229 1297
-f 1411 1485 1354
-f 1354 1297 1411
-f 1597 1625 1485
-f 1485 1411 1597
-f 1853 1901 1625
-f 1625 1597 1853
-f 970 1064 1054
-f 1054 968 970
-f 992 1074 1064
-f 1064 970 992
-f 1030 1092 1074
-f 1074 992 1030
-f 1072 1131 1092
-f 1092 1030 1072
-f 1113 1187 1131
-f 1131 1072 1113
-f 1191 1229 1187
-f 1187 1113 1191
-f 1257 1297 1229
-f 1229 1191 1257
-f 1360 1411 1297
-f 1297 1257 1360
-f 1571 1597 1411
-f 1411 1360 1571
-f 1899 1853 1597
-f 1597 1571 1899
-f 903 970 968
-f 968 897 903
-f 926 992 970
-f 970 903 926
-f 961 1030 992
-f 992 926 961
-f 1016 1072 1030
-f 1030 961 1016
-f 1076 1113 1072
-f 1072 1016 1076
-f 1139 1191 1113
-f 1113 1076 1139
-f 1218 1257 1191
-f 1191 1139 1218
-f 1315 1360 1257
-f 1257 1218 1315
-f 1533 1571 1360
-f 1360 1315 1533
-f 1920 1899 1571
-f 1571 1533 1920
-f 836 903 897
-f 897 828 836
-f 864 926 903
-f 903 836 864
-f 910 961 926
-f 926 864 910
-f 966 1016 961
-f 961 910 966
-f 1034 1076 1016
-f 1016 966 1034
-f 1098 1139 1076
-f 1076 1034 1098
-f 1201 1218 1139
-f 1139 1098 1201
-f 1293 1315 1218
-f 1218 1201 1293
-f 1505 1533 1315
-f 1315 1293 1505
-f 1924 1920 1533
-f 1533 1505 1924
-f 789 836 828
-f 828 779 789
-f 825 864 836
-f 836 789 825
-f 873 910 864
-f 864 825 873
-f 933 966 910
-f 910 873 933
-f 999 1034 966
-f 966 933 999
-f 1087 1098 1034
-f 1034 999 1087
-f 1182 1201 1098
-f 1098 1087 1182
-f 1283 1293 1201
-f 1201 1182 1283
-f 1495 1505 1293
-f 1293 1283 1495
-f 1826 1924 1505
-f 1505 1495 1826
-f 776 789 779
-f 779 766 776
-f 802 825 789
-f 789 776 802
-f 858 873 825
-f 825 802 858
-f 920 933 873
-f 873 858 920
-f 986 999 933
-f 933 920 986
-f 1080 1087 999
-f 999 986 1080
-f 1177 1182 1087
-f 1087 1080 1177
-f 1279 1283 1182
-f 1182 1177 1279
-f 1487 1495 1283
-f 1283 1279 1487
-f 1914 1826 1495
-f 1495 1487 1914
-f 1947 1941 1867
-f 1867 1863 1947
-f 1981 1967 1941
-f 1941 1947 1981
-f 2022 1987 1967
-f 1967 1981 2022
-f 2065 2011 1987
-f 1987 2022 2065
-f 2121 2035 2011
-f 2011 2065 2121
-f 2151 2059 2035
-f 2035 2121 2151
-f 2198 2083 2059
-f 2059 2151 2198
-f 2219 2103 2083
-f 2083 2198 2219
-f 2233 2117 2103
-f 2103 2219 2233
-f 2236 2125 2117
-f 2117 2233 2236
-f 1969 1947 1863
-f 1863 1860 1969
-f 2017 1981 1947
-f 1947 1969 2017
-f 2092 2022 1981
-f 1981 2017 2092
-f 2171 2065 2022
-f 2022 2092 2171
-f 2235 2121 2065
-f 2065 2171 2235
-f 2276 2151 2121
-f 2121 2235 2276
-f 2307 2198 2151
-f 2151 2276 2307
-f 2323 2219 2198
-f 2198 2307 2323
-f 2333 2233 2219
-f 2219 2323 2333
-f 2337 2236 2233
-f 2233 2333 2337
-f 1977 1969 1860
-f 1860 1857 1977
-f 2073 2017 1969
-f 1969 1977 2073
-f 2184 2092 2017
-f 2017 2073 2184
-f 2272 2171 2092
-f 2092 2184 2272
-f 2325 2235 2171
-f 2171 2272 2325
-f 2348 2276 2235
-f 2235 2325 2348
-f 2377 2307 2276
-f 2276 2348 2377
-f 2401 2323 2307
-f 2307 2377 2401
-f 2408 2333 2323
-f 2323 2401 2408
-f 2412 2337 2333
-f 2333 2408 2412
-f 1999 1977 1857
-f 1857 1855 1999
-f 2139 2073 1977
-f 1977 1999 2139
-f 2270 2184 2073
-f 2073 2139 2270
-f 2339 2272 2184
-f 2184 2270 2339
-f 2385 2325 2272
-f 2272 2339 2385
-f 2419 2348 2325
-f 2325 2385 2419
-f 2445 2377 2348
-f 2348 2419 2445
-f 2471 2401 2377
-f 2377 2445 2471
-f 2489 2408 2401
-f 2401 2471 2489
-f 2499 2412 2408
-f 2408 2489 2499
-f 2027 1999 1855
-f 1855 1852 2027
-f 2213 2139 1999
-f 1999 2027 2213
-f 2327 2270 2139
-f 2139 2213 2327
-f 2395 2339 2270
-f 2270 2327 2395
-f 2437 2385 2339
-f 2339 2395 2437
-f 2493 2419 2385
-f 2385 2437 2493
-f 2532 2445 2419
-f 2419 2493 2532
-f 2550 2471 2445
-f 2445 2532 2550
-f 2560 2489 2471
-f 2471 2550 2560
-f 2570 2499 2489
-f 2489 2560 2570
-f 2053 2027 1852
-f 1852 1849 2053
-f 2264 2213 2027
-f 2027 2053 2264
-f 2367 2327 2213
-f 2213 2264 2367
-f 2433 2395 2327
-f 2327 2367 2433
-f 2511 2437 2395
-f 2395 2433 2511
-f 2552 2493 2437
-f 2437 2511 2552
-f 2594 2532 2493
-f 2493 2552 2594
-f 2632 2550 2532
-f 2532 2594 2632
-f 2654 2560 2550
-f 2550 2632 2654
-f 2656 2570 2560
-f 2560 2654 2656
-f 2091 2053 1849
-f 1849 1847 2091
-f 2309 2264 2053
-f 2053 2091 2309
-f 2404 2367 2264
-f 2264 2309 2404
-f 2485 2433 2367
-f 2367 2404 2485
-f 2548 2511 2433
-f 2433 2485 2548
-f 2608 2552 2511
-f 2511 2548 2608
-f 2661 2594 2552
-f 2552 2608 2661
-f 2698 2632 2594
-f 2594 2661 2698
-f 2719 2654 2632
-f 2632 2698 2719
-f 2725 2656 2654
-f 2654 2719 2725
-f 2119 2091 1847
-f 1847 1833 2119
-f 2331 2309 2091
-f 2091 2119 2331
-f 2423 2404 2309
-f 2309 2331 2423
-f 2526 2485 2404
-f 2404 2423 2526
-f 2590 2548 2485
-f 2485 2526 2590
-f 2658 2608 2548
-f 2548 2590 2658
-f 2714 2661 2608
-f 2608 2658 2714
-f 2760 2698 2661
-f 2661 2714 2760
-f 2788 2719 2698
-f 2698 2760 2788
-f 2796 2725 2719
-f 2719 2788 2796
-f 2129 2119 1833
-f 1833 1827 2129
-f 2341 2331 2119
-f 2119 2129 2341
-f 2440 2423 2331
-f 2331 2341 2440
-f 2535 2526 2423
-f 2423 2440 2535
-f 2623 2590 2526
-f 2526 2535 2623
-f 2689 2658 2590
-f 2590 2623 2689
-f 2749 2714 2658
-f 2658 2689 2749
-f 2797 2760 2714
-f 2714 2749 2797
-f 2833 2788 2760
-f 2760 2797 2833
-f 2843 2796 2788
-f 2788 2833 2843
-f 2137 2129 1827
-f 1827 1815 2137
-f 2345 2341 2129
-f 2129 2137 2345
-f 2447 2440 2341
-f 2341 2345 2447
-f 2544 2535 2440
-f 2440 2447 2544
-f 2638 2623 2535
-f 2535 2544 2638
-f 2704 2689 2623
-f 2623 2638 2704
-f 2766 2749 2689
-f 2689 2704 2766
-f 2822 2797 2749
-f 2749 2766 2822
-f 2848 2833 2797
-f 2797 2822 2848
-f 2858 2843 2833
-f 2833 2848 2858
-f 1735 2334 2329
-f 1735 2329 2321
-f 1735 2321 2305
-f 1735 2305 2274
-f 1735 2274 2231
-f 1735 2231 2167
-f 1735 2167 2089
-f 1735 2089 2014
-f 1735 2014 1962
-f 1735 1962 1733
-f 2515 2329 2334
-f 2334 2524 2515
-f 2495 2321 2329
-f 2329 2515 2495
-f 2456 2305 2321
-f 2321 2495 2456
-f 2429 2274 2305
-f 2305 2456 2429
-f 2399 2231 2274
-f 2274 2429 2399
-f 2347 2167 2231
-f 2231 2399 2347
-f 2292 2089 2167
-f 2167 2347 2292
-f 2148 2014 2089
-f 2089 2292 2148
-f 2004 1962 2014
-f 2014 2148 2004
-f 1739 1733 1962
-f 1962 2004 1739
-f 2647 2515 2524
-f 2524 2649 2647
-f 2621 2495 2515
-f 2515 2647 2621
-f 2584 2456 2495
-f 2495 2621 2584
-f 2541 2429 2456
-f 2456 2584 2541
-f 2502 2399 2429
-f 2429 2541 2502
-f 2426 2347 2399
-f 2399 2502 2426
-f 2352 2292 2347
-f 2347 2426 2352
-f 2255 2148 2292
-f 2292 2352 2255
-f 2046 2004 2148
-f 2148 2255 2046
-f 1702 1739 2004
-f 2004 2046 1702
-f 2746 2647 2649
-f 2649 2757 2746
-f 2721 2621 2647
-f 2647 2746 2721
-f 2681 2584 2621
-f 2621 2721 2681
-f 2639 2541 2584
-f 2584 2681 2639
-f 2557 2502 2541
-f 2541 2639 2557
-f 2505 2426 2502
-f 2502 2557 2505
-f 2415 2352 2426
-f 2426 2505 2415
-f 2318 2255 2352
-f 2352 2415 2318
-f 2098 2046 2255
-f 2255 2318 2098
-f 1745 1702 2046
-f 2046 2098 1745
-f 2840 2746 2757
-f 2757 2849 2840
-f 2808 2721 2746
-f 2746 2840 2808
-f 2756 2681 2721
-f 2721 2808 2756
-f 2696 2639 2681
-f 2681 2756 2696
-f 2626 2557 2639
-f 2639 2696 2626
-f 2538 2505 2557
-f 2557 2626 2538
-f 2443 2415 2505
-f 2505 2538 2443
-f 2342 2318 2415
-f 2415 2443 2342
-f 2131 2098 2318
-f 2318 2342 2131
-f 1904 1745 2098
-f 2098 2131 1904
-f 2906 2840 2849
-f 2849 2925 2906
-f 2867 2808 2840
-f 2840 2906 2867
-f 2818 2756 2808
-f 2808 2867 2818
-f 2736 2696 2756
-f 2756 2818 2736
-f 2667 2626 2696
-f 2696 2736 2667
-f 2565 2538 2626
-f 2626 2667 2565
-f 2475 2443 2538
-f 2538 2565 2475
-f 2356 2342 2443
-f 2443 2475 2356
-f 2156 2131 2342
-f 2342 2356 2156
-f 1704 1904 2131
-f 2131 2156 1704
-f 2976 2906 2925
-f 2925 2987 2976
-f 2914 2867 2906
-f 2906 2976 2914
-f 2852 2818 2867
-f 2867 2914 2852
-f 2772 2736 2818
-f 2818 2852 2772
-f 2688 2667 2736
-f 2736 2772 2688
-f 2592 2565 2667
-f 2667 2688 2592
-f 2497 2475 2565
-f 2565 2592 2497
-f 2372 2356 2475
-f 2475 2497 2372
-f 2176 2156 2356
-f 2356 2372 2176
-f 1752 1704 2156
-f 2156 2176 1752
-f 2993 2976 2987
-f 2987 3011 2993
-f 2952 2914 2976
-f 2976 2993 2952
-f 2874 2852 2914
-f 2914 2952 2874
-f 2794 2772 2852
-f 2852 2874 2794
-f 2702 2688 2772
-f 2772 2794 2702
-f 2604 2592 2688
-f 2688 2702 2604
-f 2509 2497 2592
-f 2592 2604 2509
-f 2380 2372 2497
-f 2497 2509 2380
-f 2182 2176 2372
-f 2372 2380 2182
-f 1723 1752 2176
-f 2176 2182 1723
-f 3000 2993 3011
-f 3011 3020 3000
-f 2967 2952 2993
-f 2993 3000 2967
-f 2879 2874 2952
-f 2952 2967 2879
-f 2799 2794 2874
-f 2874 2879 2799
-f 2707 2702 2794
-f 2794 2799 2707
-f 2605 2604 2702
-f 2702 2707 2605
-f 2512 2509 2604
-f 2604 2605 2512
-f 2382 2380 2509
-f 2509 2512 2382
-f 2188 2182 2380
-f 2380 2382 2188
-f 1699 1723 2182
-f 2182 2188 1699
-f 3006 3000 3020
-f 3020 3022 3006
-f 2972 2967 3000
-f 3000 3006 2972
-f 2888 2879 2967
-f 2967 2972 2888
-f 2804 2799 2879
-f 2879 2888 2804
-f 2710 2707 2799
-f 2799 2804 2710
-f 2613 2605 2707
-f 2707 2710 2613
-f 2520 2512 2605
-f 2605 2613 2520
-f 2388 2382 2512
-f 2512 2520 2388
-f 2192 2188 2382
-f 2382 2388 2192
-f 1760 1699 2188
-f 2188 2192 1760
-f 1735 1737 1660
-f 1735 1660 1608
-f 1735 1608 1535
-f 1735 1535 1457
-f 1735 1457 1393
-f 1735 1393 1350
-f 1735 1350 1319
-f 1735 1319 1303
-f 1735 1303 1295
-f 1735 1295 1288
-f 1618 1660 1737
-f 1737 1739 1618
-f 1474 1608 1660
-f 1660 1618 1474
-f 1332 1535 1608
-f 1608 1474 1332
-f 1277 1457 1535
-f 1535 1332 1277
-f 1225 1393 1457
-f 1457 1277 1225
-f 1195 1350 1393
-f 1393 1225 1195
-f 1166 1319 1350
-f 1350 1195 1166
-f 1129 1303 1319
-f 1319 1166 1129
-f 1109 1295 1303
-f 1303 1129 1109
-f 1099 1288 1295
-f 1295 1109 1099
-f 1576 1618 1739
-f 1739 1741 1576
-f 1367 1474 1618
-f 1618 1576 1367
-f 1270 1332 1474
-f 1474 1367 1270
-f 1196 1277 1332
-f 1332 1270 1196
-f 1120 1225 1277
-f 1277 1196 1120
-f 1081 1195 1225
-f 1225 1120 1081
-f 1040 1166 1195
-f 1195 1081 1040
-f 1001 1129 1166
-f 1166 1040 1001
-f 975 1109 1129
-f 1129 1001 975
-f 973 1099 1109
-f 1109 975 973
-f 1524 1576 1741
-f 1741 1744 1524
-f 1304 1367 1576
-f 1576 1524 1304
-f 1209 1270 1367
-f 1367 1304 1209
-f 1119 1196 1270
-f 1270 1209 1119
-f 1065 1120 1196
-f 1196 1119 1065
-f 983 1081 1120
-f 1120 1065 983
-f 941 1040 1081
-f 1081 983 941
-f 901 1001 1040
-f 1040 941 901
-f 878 975 1001
-f 1001 901 878
-f 865 973 975
-f 975 878 865
-f 1493 1524 1744
-f 1744 1747 1493
-f 1280 1304 1524
-f 1524 1493 1280
-f 1181 1209 1304
-f 1304 1280 1181
-f 1086 1119 1209
-f 1209 1181 1086
-f 998 1065 1119
-f 1119 1086 998
-f 928 983 1065
-f 1065 998 928
-f 868 941 983
-f 983 928 868
-f 816 901 941
-f 941 868 816
-f 784 878 901
-f 901 816 784
-f 773 865 878
-f 878 784 773
-f 1466 1493 1747
-f 1747 1749 1466
-f 1266 1280 1493
-f 1493 1466 1266
-f 1149 1181 1280
-f 1280 1266 1149
-f 1057 1086 1181
-f 1181 1149 1057
-f 955 998 1086
-f 1086 1057 955
-f 888 928 998
-f 998 955 888
-f 806 868 928
-f 928 888 806
-f 755 816 868
-f 868 806 755
-f 718 784 816
-f 816 755 718
-f 697 773 784
-f 784 718 697
-f 1446 1466 1749
-f 1749 1753 1446
-f 1250 1266 1466
-f 1466 1446 1250
-f 1127 1149 1266
-f 1266 1250 1127
-f 1032 1057 1149
-f 1149 1127 1032
-f 936 955 1057
-f 1057 1032 936
-f 852 888 955
-f 955 936 852
-f 772 806 888
-f 888 852 772
-f 710 755 806
-f 806 772 710
-f 648 718 755
-f 755 710 648
-f 637 697 718
-f 718 648 637
-f 1440 1446 1753
-f 1753 1755 1440
-f 1242 1250 1446
-f 1446 1440 1242
-f 1115 1127 1250
-f 1250 1242 1115
-f 1020 1032 1127
-f 1127 1115 1020
-f 922 936 1032
-f 1032 1020 922
-f 830 852 936
-f 936 922 830
-f 750 772 852
-f 852 830 750
-f 672 710 772
-f 772 750 672
-f 631 648 710
-f 710 672 631
-f 613 637 648
-f 648 631 613
-f 1434 1440 1755
-f 1755 1757 1434
-f 1240 1242 1440
-f 1440 1434 1240
-f 1110 1115 1242
-f 1242 1240 1110
-f 1017 1020 1115
-f 1115 1110 1017
-f 915 922 1020
-f 1020 1017 915
-f 823 830 922
-f 922 915 823
-f 743 750 830
-f 830 823 743
-f 655 672 750
-f 750 743 655
-f 622 631 672
-f 672 655 622
-f 602 613 631
-f 631 622 602
-f 1428 1434 1757
-f 1757 1760 1428
-f 1232 1240 1434
-f 1434 1428 1232
-f 1105 1110 1240
-f 1240 1232 1105
-f 1010 1017 1110
-f 1110 1105 1010
-f 913 915 1017
-f 1017 1010 913
-f 821 823 915
-f 915 913 821
-f 736 743 823
-f 823 821 736
-f 652 655 743
-f 743 736 652
-f 619 622 655
-f 655 652 619
-f 601 602 622
-f 622 619 601
-f 1735 1289 1294
-f 1735 1294 1302
-f 1735 1302 1318
-f 1735 1318 1349
-f 1735 1349 1392
-f 1735 1392 1456
-f 1735 1456 1534
-f 1735 1534 1609
-f 1735 1609 1661
-f 1735 1661 1889
-f 1108 1294 1289
-f 1289 1099 1108
-f 1128 1302 1294
-f 1294 1108 1128
-f 1167 1318 1302
-f 1302 1128 1167
-f 1194 1349 1318
-f 1318 1167 1194
-f 1224 1392 1349
-f 1349 1194 1224
-f 1276 1456 1392
-f 1392 1224 1276
-f 1331 1534 1456
-f 1456 1276 1331
-f 1475 1609 1534
-f 1534 1331 1475
-f 1619 1661 1609
-f 1609 1475 1619
-f 1738 1889 1661
-f 1661 1619 1738
-f 976 1108 1099
-f 1099 974 976
-f 1002 1128 1108
-f 1108 976 1002
-f 1039 1167 1128
-f 1128 1002 1039
-f 1082 1194 1167
-f 1167 1039 1082
-f 1121 1224 1194
-f 1194 1082 1121
-f 1197 1276 1224
-f 1224 1121 1197
-f 1271 1331 1276
-f 1276 1197 1271
-f 1368 1475 1331
-f 1331 1271 1368
-f 1577 1619 1475
-f 1475 1368 1577
-f 1903 1738 1619
-f 1619 1577 1903
-f 877 976 974
-f 974 866 877
-f 902 1002 976
-f 976 877 902
-f 942 1039 1002
-f 1002 902 942
-f 984 1082 1039
-f 1039 942 984
-f 1066 1121 1082
-f 1082 984 1066
-f 1118 1197 1121
-f 1121 1066 1118
-f 1208 1271 1197
-f 1197 1118 1208
-f 1305 1368 1271
-f 1271 1208 1305
-f 1525 1577 1368
-f 1368 1305 1525
-f 1742 1903 1577
-f 1577 1525 1742
-f 783 877 866
-f 866 774 783
-f 815 902 877
-f 877 783 815
-f 867 942 902
-f 902 815 867
-f 927 984 942
-f 942 867 927
-f 997 1066 984
-f 984 927 997
-f 1085 1118 1066
-f 1066 997 1085
-f 1180 1208 1118
-f 1118 1085 1180
-f 1281 1305 1208
-f 1208 1180 1281
-f 1492 1525 1305
-f 1305 1281 1492
-f 1703 1742 1525
-f 1525 1492 1703
-f 717 783 774
-f 774 698 717
-f 756 815 783
-f 783 717 756
-f 805 867 815
-f 815 756 805
-f 887 927 867
-f 867 805 887
-f 956 997 927
-f 927 887 956
-f 1058 1085 997
-f 997 956 1058
-f 1148 1180 1085
-f 1085 1058 1148
-f 1267 1281 1180
-f 1180 1148 1267
-f 1467 1492 1281
-f 1281 1267 1467
-f 1905 1703 1492
-f 1492 1467 1905
-f 647 717 698
-f 698 636 647
-f 709 756 717
-f 717 647 709
-f 771 805 756
-f 756 709 771
-f 851 887 805
-f 805 771 851
-f 935 956 887
-f 887 851 935
-f 1031 1058 956
-f 956 935 1031
-f 1126 1148 1058
-f 1058 1031 1126
-f 1251 1267 1148
-f 1148 1126 1251
-f 1447 1467 1267
-f 1267 1251 1447
-f 1751 1905 1467
-f 1467 1447 1751
-f 630 647 636
-f 636 612 630
-f 671 709 647
-f 647 630 671
-f 749 771 709
-f 709 671 749
-f 829 851 771
-f 771 749 829
-f 921 935 851
-f 851 829 921
-f 1019 1031 935
-f 935 921 1019
-f 1114 1126 1031
-f 1031 1019 1114
-f 1243 1251 1126
-f 1126 1114 1243
-f 1441 1447 1251
-f 1251 1243 1441
-f 1896 1751 1447
-f 1447 1441 1896
-f 623 630 612
-f 612 603 623
-f 656 671 630
-f 630 623 656
-f 744 749 671
-f 671 656 744
-f 824 829 749
-f 749 744 824
-f 916 921 829
-f 829 824 916
-f 1018 1019 921
-f 921 916 1018
-f 1111 1114 1019
-f 1019 1018 1111
-f 1241 1243 1114
-f 1114 1111 1241
-f 1435 1441 1243
-f 1243 1241 1435
-f 1923 1896 1441
-f 1441 1435 1923
-f 617 623 603
-f 603 601 617
-f 650 656 623
-f 623 617 650
-f 734 744 656
-f 656 650 734
-f 818 824 744
-f 744 734 818
-f 912 916 824
-f 824 818 912
-f 1009 1018 916
-f 916 912 1009
-f 1102 1111 1018
-f 1018 1009 1102
-f 1235 1241 1111
-f 1111 1102 1235
-f 1431 1435 1241
-f 1241 1235 1431
-f 1759 1923 1435
-f 1435 1431 1759
-f 1735 1736 1963
-f 1735 1963 2015
-f 1735 2015 2088
-f 1735 2088 2166
-f 1735 2166 2230
-f 1735 2230 2273
-f 1735 2273 2304
-f 1735 2304 2320
-f 1735 2320 2328
-f 1735 2328 2335
-f 2005 1963 1736
-f 1736 1738 2005
-f 2149 2015 1963
-f 1963 2005 2149
-f 2291 2088 2015
-f 2015 2149 2291
-f 2346 2166 2088
-f 2088 2291 2346
-f 2398 2230 2166
-f 2166 2346 2398
-f 2428 2273 2230
-f 2230 2398 2428
-f 2457 2304 2273
-f 2273 2428 2457
-f 2494 2320 2304
-f 2304 2457 2494
-f 2514 2328 2320
-f 2320 2494 2514
-f 2524 2335 2328
-f 2328 2514 2524
-f 2047 2005 1738
-f 1738 1740 2047
-f 2256 2149 2005
-f 2005 2047 2256
-f 2353 2291 2149
-f 2149 2256 2353
-f 2427 2346 2291
-f 2291 2353 2427
-f 2503 2398 2346
-f 2346 2427 2503
-f 2542 2428 2398
-f 2398 2503 2542
-f 2583 2457 2428
-f 2428 2542 2583
-f 2622 2494 2457
-f 2457 2583 2622
-f 2648 2514 2494
-f 2494 2622 2648
-f 2650 2524 2514
-f 2514 2648 2650
-f 2099 2047 1740
-f 1740 1743 2099
-f 2319 2256 2047
-f 2047 2099 2319
-f 2414 2353 2256
-f 2256 2319 2414
-f 2504 2427 2353
-f 2353 2414 2504
-f 2558 2503 2427
-f 2427 2504 2558
-f 2640 2542 2503
-f 2503 2558 2640
-f 2682 2583 2542
-f 2542 2640 2682
-f 2722 2622 2583
-f 2583 2682 2722
-f 2745 2648 2622
-f 2622 2722 2745
-f 2758 2650 2648
-f 2648 2745 2758
-f 2130 2099 1743
-f 1743 1746 2130
-f 2343 2319 2099
-f 2099 2130 2343
-f 2442 2414 2319
-f 2319 2343 2442
-f 2537 2504 2414
-f 2414 2442 2537
-f 2625 2558 2504
-f 2504 2537 2625
-f 2695 2640 2558
-f 2558 2625 2695
-f 2755 2682 2640
-f 2640 2695 2755
-f 2807 2722 2682
-f 2682 2755 2807
-f 2839 2745 2722
-f 2722 2807 2839
-f 2850 2758 2745
-f 2745 2839 2850
-f 2157 2130 1746
-f 1746 1748 2157
-f 2357 2343 2130
-f 2130 2157 2357
-f 2474 2442 2343
-f 2343 2357 2474
-f 2566 2537 2442
-f 2442 2474 2566
-f 2668 2625 2537
-f 2537 2566 2668
-f 2735 2695 2625
-f 2625 2668 2735
-f 2817 2755 2695
-f 2695 2735 2817
-f 2868 2807 2755
-f 2755 2817 2868
-f 2905 2839 2807
-f 2807 2868 2905
-f 2926 2850 2839
-f 2839 2905 2926
-f 2177 2157 1748
-f 1748 1750 2177
-f 2373 2357 2157
-f 2157 2177 2373
-f 2496 2474 2357
-f 2357 2373 2496
-f 2591 2566 2474
-f 2474 2496 2591
-f 2687 2668 2566
-f 2566 2591 2687
-f 2771 2735 2668
-f 2668 2687 2771
-f 2851 2817 2735
-f 2735 2771 2851
-f 2913 2868 2817
-f 2817 2851 2913
-f 2975 2905 2868
-f 2868 2913 2975
-f 2986 2926 2905
-f 2905 2975 2986
-f 2183 2177 1750
-f 1750 1754 2183
-f 2381 2373 2177
-f 2177 2183 2381
-f 2508 2496 2373
-f 2373 2381 2508
-f 2603 2591 2496
-f 2496 2508 2603
-f 2701 2687 2591
-f 2591 2603 2701
-f 2793 2771 2687
-f 2687 2701 2793
-f 2873 2851 2771
-f 2771 2793 2873
-f 2951 2913 2851
-f 2851 2873 2951
-f 2992 2975 2913
-f 2913 2951 2992
-f 3010 2986 2975
-f 2975 2992 3010
-f 2189 2183 1754
-f 1754 1756 2189
-f 2383 2381 2183
-f 2183 2189 2383
-f 2513 2508 2381
-f 2381 2383 2513
-f 2606 2603 2508
-f 2508 2513 2606
-f 2708 2701 2603
-f 2603 2606 2708
-f 2800 2793 2701
-f 2701 2708 2800
-f 2880 2873 2793
-f 2793 2800 2880
-f 2968 2951 2873
-f 2873 2880 2968
-f 3001 2992 2951
-f 2951 2968 3001
-f 3021 3010 2992
-f 2992 3001 3021
-f 2195 2189 1756
-f 1756 1759 2195
-f 2390 2383 2189
-f 2189 2195 2390
-f 2517 2513 2383
-f 2383 2390 2517
-f 2612 2606 2513
-f 2513 2517 2612
-f 2709 2708 2606
-f 2606 2612 2709
-f 2801 2800 2708
-f 2708 2709 2801
-f 2886 2880 2800
-f 2800 2801 2886
-f 2970 2968 2880
-f 2880 2886 2970
-f 3004 3001 2968
-f 2968 2970 3004
-f 3022 3021 3001
-f 3001 3004 3022

+ 0 - 12
objects/test_guy.mtl

@@ -1,12 +0,0 @@
-# Blender 4.4.3 MTL File: 'None'
-# www.blender.org
-
-newmtl Material.001
-Ns 250.000000
-Ka 1.000000 1.000000 1.000000
-Ks 0.500000 0.500000 0.500000
-Ke 0.000000 0.000000 0.000000
-Ni 1.500000
-d 1.000000
-illum 2
-map_Kd /home/iver/Documents/C-rasterizer/textures/test_guy_texture.png

+ 0 - 12
objects/test_guy_hd.mtl

@@ -1,12 +0,0 @@
-# Blender 4.4.3 MTL File: 'None'
-# www.blender.org
-
-newmtl Material.001
-Ns 250.000000
-Ka 1.000000 1.000000 1.000000
-Ks 0.500000 0.500000 0.500000
-Ke 0.000000 0.000000 0.000000
-Ni 1.500000
-d 1.000000
-illum 2
-map_Kd /home/iver/Documents/C-rasterizer/textures/test_guy_texture.png

+ 0 - 427
objects/test_guy_hd.obj

@@ -1,427 +0,0 @@
-# Blender 4.4.3
-# www.blender.org
-mtllib test_guy_hd.mtl
-o Cube.006
-v 0.404644 1.892923 -0.724644
-v 0.404644 3.203644 -0.724644
-v 0.404644 1.892923 0.724644
-v 0.404644 3.203644 0.724644
-v -0.404644 1.892923 -0.724644
-v -0.404644 3.203644 -0.724644
-v -0.404644 1.892923 0.724644
-v -0.404644 3.203644 0.724644
-v 1.473023 -4.522150 -1.586363
-v 1.473023 -5.441304 -1.586363
-v 1.473023 -4.522150 -0.377075
-v 1.473023 -5.441304 -0.377075
-v -0.596265 -4.522150 -1.586363
-v -0.596265 -5.441304 -1.586363
-v -0.596265 -4.522150 -0.377075
-v -0.596265 -5.441304 -0.377075
-v 0.274679 -0.870033 -1.837181
-v 0.274679 -0.539934 -2.674177
-v 0.274679 -1.852967 -2.286243
-v 0.274679 -1.522867 -3.123240
-v -0.294609 -0.870033 -1.837181
-v -0.294609 -0.539934 -2.674177
-v -0.294609 -1.852967 -2.286243
-v -0.294609 -1.522867 -3.123240
-v 0.434644 -1.176707 -1.276363
-v 0.434644 -4.994697 -1.276363
-v 0.434644 -1.176707 -0.687075
-v 0.434644 -4.994697 -0.687075
-v -0.434644 -1.176707 -1.276363
-v -0.434644 -4.994697 -1.276363
-v -0.434644 -1.176707 -0.687075
-v -0.434644 -4.994697 -0.687075
-v 0.434644 -1.176707 0.687074
-v 0.434644 -4.994697 0.687074
-v 0.434644 -1.176707 1.276363
-v 0.434644 -4.994697 1.276363
-v -0.434644 -1.176707 0.687074
-v -0.434644 -4.994697 0.687074
-v -0.434644 -1.176707 1.276363
-v -0.434644 -4.994697 1.276363
-v 1.473023 -4.522150 0.377075
-v 1.473023 -5.441304 0.377075
-v 1.473023 -4.522150 1.586363
-v 1.473023 -5.441304 1.586363
-v -0.596265 -4.522150 0.377075
-v -0.596265 -5.441304 0.377075
-v -0.596265 -4.522150 1.586363
-v -0.596265 -5.441304 1.586363
-v 0.234644 1.401997 -0.965264
-v 0.234644 1.601404 -1.470879
-v 0.234644 -1.240130 -2.172345
-v 0.234644 -1.040723 -2.677960
-v -0.234644 1.401997 -0.965264
-v -0.234644 1.601404 -1.470879
-v -0.234644 -1.240130 -2.172345
-v -0.234644 -1.040723 -2.677960
-v 0.234644 -1.240130 2.172343
-v 0.234644 -1.040723 2.677958
-v 0.234644 1.401997 0.965262
-v 0.234644 1.601404 1.470877
-v -0.234644 -1.240130 2.172343
-v -0.234644 -1.040723 2.677958
-v -0.234644 1.401997 0.965262
-v -0.234644 1.601404 1.470877
-v 0.274679 -1.852967 2.286244
-v 0.274679 -1.522867 3.123240
-v 0.274679 -0.870033 1.837181
-v 0.274679 -0.539934 2.674177
-v -0.294609 -1.852967 2.286244
-v -0.294609 -1.522867 3.123240
-v -0.294609 -0.870033 1.837181
-v -0.294609 -0.539934 2.674177
-v 0.594644 2.089632 -1.544644
-v 0.594644 -1.728358 -1.544644
-v 0.594644 2.089632 1.544644
-v 0.594644 -1.728358 1.544644
-v -0.594644 2.089632 -1.544644
-v -0.594644 -1.728358 -1.544644
-v -0.594644 2.089632 1.544644
-v -0.594644 -1.728358 1.544644
-v 2.258631 2.922323 -0.954644
-v 2.258631 4.790511 -0.954644
-v 2.258631 2.922323 0.954644
-v 2.258631 4.790511 0.954644
-v -1.070658 2.922323 -0.954644
-v -1.070658 4.790511 -0.954644
-v -1.070658 2.922323 0.954644
-v -1.070658 4.790511 0.954644
-vn 1.0000 -0.0000 -0.0000
-vn -0.0000 -0.0000 1.0000
-vn -1.0000 -0.0000 -0.0000
-vn -0.0000 -0.0000 -1.0000
-vn -0.0000 -1.0000 -0.0000
-vn -0.0000 1.0000 -0.0000
-vn -0.0000 -0.9303 -0.3669
-vn -0.0000 0.9303 0.3669
-vn -0.0000 -0.4155 0.9096
-vn -0.0000 0.4155 -0.9096
-vn -0.0000 -0.9303 0.3669
-vn -0.0000 -0.4155 -0.9096
-vn -0.0000 0.4155 0.9096
-vt 0.633456 0.354066
-vt 0.723943 0.263579
-vt 0.723943 0.354066
-vt 0.247694 0.881223
-vt 0.338181 0.790736
-vt 0.338181 0.881223
-vt 0.000000 0.918410
-vt 0.090487 0.827924
-vt 0.090487 0.918410
-vt 0.385762 0.918410
-vt 0.476249 0.827924
-vt 0.476249 0.918410
-vt 0.849859 0.231368
-vt 0.939977 0.321855
-vt 0.849859 0.321855
-vt 0.713127 0.834985
-vt 0.803246 0.925472
-vt 0.713127 0.925472
-vt 0.196429 0.867196
-vt 0.132975 0.867196
-vt 0.132975 0.942698
-vt 0.851777 0.603617
-vt 0.788323 0.603617
-vt 0.788323 0.834985
-vt 0.701398 0.867196
-vt 0.637944 0.867196
-vt 0.637944 0.942698
-vt 0.701398 0.635828
-vt 0.637944 0.635828
-vt 0.788323 0.372249
-vt 0.863518 0.603617
-vt 0.713127 0.603617
-vt 0.385762 0.919516
-vt 0.385762 0.992938
-vt 0.442762 0.991832
-vt 0.839889 0.932181
-vt 0.789897 0.932181
-vt 0.789897 0.995833
-vt 0.499762 0.992938
-vt 0.499762 0.919516
-vt 0.992661 0.803543
-vt 0.942669 0.803543
-vt 0.942669 0.867196
-vt 0.311149 0.949081
-vt 0.374801 0.949081
-vt 0.374801 0.881223
-vt 0.915232 0.935054
-vt 0.978884 0.935054
-vt 0.978884 0.867196
-vt 0.381682 0.790736
-vt 0.381682 0.527157
-vt 0.344890 0.527157
-vt 0.615932 0.635828
-vt 0.615932 0.372249
-vt 0.518737 0.372249
-vt 0.888570 0.867196
-vt 0.888570 0.603617
-vt 0.713127 0.635828
-vt 0.713127 0.372249
-vt 0.956205 0.097195
-vt 0.992848 0.194391
-vt 0.956205 0.194391
-vt 0.803246 0.834985
-vt 0.803246 0.932181
-vt 0.233222 0.899406
-vt 0.233222 0.635828
-vt 0.196429 0.635828
-vt 0.730651 0.263579
-vt 0.730651 0.000000
-vt 0.633456 0.000000
-vt 0.900310 0.603617
-vt 0.900310 0.340039
-vt 0.863518 0.340039
-vt 0.344890 0.790736
-vt 0.247694 0.527157
-vt 0.956205 0.000000
-vt 0.992848 0.097195
-vt 0.196429 0.899406
-vt 0.233072 0.996602
-vt 0.196429 0.996602
-vt 0.915232 0.867196
-vt 0.851777 0.867196
-vt 0.851777 0.942698
-vt 0.196430 0.635828
-vt 0.132975 0.635828
-vt 0.311149 0.881223
-vt 0.247694 0.956725
-vt 0.869301 0.000000
-vt 0.805846 -0.000000
-vt 0.805846 0.231368
-vt 0.788322 0.603617
-vt 0.730651 0.231368
-vt 0.900310 0.340707
-vt 0.900310 0.538065
-vt 0.934743 0.537397
-vt 0.506447 0.827924
-vt 0.476249 0.880395
-vt 0.921772 0.197358
-vt 0.956205 0.198026
-vt 0.956205 0.000668
-vt 0.984608 0.538065
-vt 0.954410 0.590536
-vt 0.954410 0.538065
-vt 0.869301 0.182402
-vt 0.921772 0.182402
-vt 0.921772 -0.000000
-vt 0.888570 0.786019
-vt 0.941041 0.786019
-vt 0.941041 0.603617
-vt 0.969176 0.538065
-vt 0.969176 0.340707
-vt 0.090487 0.880395
-vt 0.123167 0.827924
-vt 0.123167 0.880395
-vt 0.941041 0.604285
-vt 0.941041 0.801643
-vt 0.975474 0.800975
-vt 0.338181 0.843207
-vt 0.370862 0.843207
-vt 0.370862 0.790736
-vt 0.571208 0.764800
-vt 0.518737 0.764800
-vt 0.518737 0.947202
-vt 0.623679 0.764800
-vt 0.571208 0.947202
-vt 0.939977 0.304790
-vt 0.996977 0.305896
-vt 0.996977 0.232474
-vt 0.713127 0.926578
-vt 0.713127 1.000000
-vt 0.770128 0.998894
-vt 0.900310 0.601717
-vt 0.954410 0.601717
-vt 0.063652 0.918410
-vt 0.000000 0.986268
-vt 0.127305 0.918410
-vt 0.063652 0.986268
-vt 0.192881 0.263579
-vt 0.192881 0.000000
-vt 0.000000 0.000000
-vt 0.380669 0.527157
-vt 0.380669 0.263579
-vt 0.247694 0.263579
-vt 0.385762 0.263579
-vt 0.385762 0.000000
-vt 0.518737 0.635828
-vt 0.385762 0.372249
-vt 0.000000 0.635828
-vt 0.000000 0.827924
-vt 0.385762 0.635828
-vt 0.385762 0.827924
-vt 0.637944 0.764800
-vt 0.128972 0.263579
-vt 0.128972 0.635828
-vt 0.849859 0.360340
-vt 0.730651 0.360340
-vt 0.514734 0.000000
-vt 0.514734 0.372249
-vt 0.633456 0.372249
-vt 0.247694 0.635828
-vt 0.633456 0.263579
-vt 0.247694 0.790736
-vt 0.939977 0.231368
-vt 0.196429 0.942698
-vt 0.851777 0.834985
-vt 0.701398 0.942698
-vt 0.863518 0.372249
-vt 0.442762 0.918410
-vt 0.839889 0.995833
-vt 0.992661 0.867196
-vt 0.839889 0.834985
-vt 0.992848 0.000000
-vt 0.233072 0.899406
-vt 0.915232 0.942698
-vt 0.311149 0.956725
-vt 0.869301 0.231368
-vt 0.788322 0.372249
-vt 0.934743 0.340038
-vt 0.506447 0.880395
-vt 0.984608 0.590536
-vt 0.975474 0.603617
-vt 0.623679 0.947202
-vt 0.888570 0.803543
-vt 0.770128 0.925472
-vt 0.127305 0.986268
-vt 0.000000 0.263579
-vt 0.132975 0.827924
-vt 0.518737 0.827924
-s 1
-usemtl Material.001
-f 2/1/1 3/2/1 1/3/1
-f 4/4/2 7/5/2 3/6/2
-f 8/7/3 5/8/3 7/9/3
-f 6/10/4 1/11/4 5/12/4
-f 7/13/5 1/14/5 3/15/5
-f 4/16/6 6/17/6 8/18/6
-f 10/19/1 9/20/1 11/21/1
-f 12/22/2 11/23/2 15/24/2
-f 16/25/3 15/26/3 13/27/3
-f 14/28/4 13/29/4 9/26/4
-f 15/30/6 11/23/6 9/31/6
-f 12/32/5 16/16/5 14/24/5
-f 17/33/1 19/34/1 20/35/1
-f 20/36/7 19/37/7 23/38/7
-f 24/35/3 23/39/3 21/40/3
-f 22/41/8 21/42/8 17/43/8
-f 23/44/9 19/45/9 17/46/9
-f 20/47/10 24/48/10 22/49/10
-f 26/50/1 25/51/1 27/52/1
-f 28/53/2 27/54/2 31/55/2
-f 32/56/3 31/57/3 29/22/3
-f 30/58/4 29/59/4 25/54/4
-f 31/60/5 25/61/5 27/62/5
-f 28/63/6 30/36/6 32/64/6
-f 34/65/1 33/66/1 35/67/1
-f 36/68/2 35/69/2 39/70/2
-f 40/71/3 39/72/3 37/73/3
-f 38/74/4 37/52/4 33/75/4
-f 39/76/5 33/77/5 35/60/5
-f 36/78/6 38/79/6 40/80/6
-f 42/81/1 41/82/1 43/83/1
-f 44/84/2 43/85/2 47/20/2
-f 48/86/3 47/4/3 45/87/3
-f 46/88/4 45/89/4 41/90/4
-f 47/59/6 43/32/6 41/91/6
-f 44/69/5 48/92/5 46/90/5
-f 49/93/1 51/94/1 52/95/1
-f 52/96/8 55/97/8 51/11/8
-f 56/98/3 55/99/3 53/100/3
-f 54/101/7 49/102/7 53/103/7
-f 55/104/9 51/105/9 49/106/9
-f 52/107/10 56/108/10 54/109/10
-f 58/95/1 57/110/1 59/111/1
-f 60/112/11 63/113/11 59/114/11
-f 63/115/3 61/116/3 62/117/3
-f 62/118/11 61/119/11 57/120/11
-f 63/121/12 59/122/12 57/123/12
-f 60/124/13 64/121/13 62/125/13
-f 66/126/1 65/127/1 67/128/1
-f 68/56/11 71/42/11 67/43/11
-f 71/129/3 69/130/3 70/131/3
-f 70/132/11 69/133/11 65/103/11
-f 71/134/12 67/7/12 65/135/12
-f 68/136/13 72/134/13 70/137/13
-f 74/138/1 73/139/1 75/140/1
-f 76/141/2 75/142/2 79/143/2
-f 80/144/3 79/145/3 77/139/3
-f 78/146/4 77/55/4 73/147/4
-f 79/85/6 75/148/6 73/149/6
-f 76/146/5 80/150/5 78/151/5
-f 82/146/1 83/152/1 81/122/1
-f 84/148/2 87/153/2 83/154/2
-f 88/92/3 85/155/3 87/156/3
-f 86/147/4 81/157/4 85/158/4
-f 87/157/5 81/159/5 83/158/5
-f 84/153/6 86/160/6 88/154/6
-f 2/1/1 4/161/1 3/2/1
-f 4/4/2 8/162/2 7/5/2
-f 8/7/3 6/149/3 5/8/3
-f 6/10/4 2/151/4 1/11/4
-f 7/13/5 5/163/5 1/14/5
-f 4/16/6 2/63/6 6/17/6
-f 10/19/1 11/21/1 12/164/1
-f 12/22/2 15/24/2 16/165/2
-f 16/25/3 13/27/3 14/166/3
-f 14/28/4 9/26/4 10/25/4
-f 15/30/6 9/31/6 13/167/6
-f 12/32/5 14/24/5 10/23/5
-f 17/33/1 20/35/1 18/168/1
-f 20/36/7 23/38/7 24/169/7
-f 24/35/3 21/40/3 22/168/3
-f 22/41/8 17/43/8 18/170/8
-f 23/44/9 17/46/9 21/86/9
-f 20/47/10 22/49/10 18/81/10
-f 26/50/1 27/52/1 28/74/1
-f 28/53/2 31/55/2 32/146/2
-f 32/56/3 29/22/3 30/82/3
-f 30/58/4 25/54/4 26/53/4
-f 31/60/5 29/77/5 25/61/5
-f 28/63/6 26/171/6 30/36/6
-f 34/65/1 35/67/1 36/78/1
-f 36/68/2 39/70/2 40/161/2
-f 40/71/3 37/73/3 38/31/3
-f 38/74/4 33/75/4 34/162/4
-f 39/76/5 37/172/5 33/77/5
-f 36/78/6 34/173/6 38/79/6
-f 42/81/1 43/83/1 44/174/1
-f 44/84/2 47/20/2 48/19/2
-f 48/86/3 45/87/3 46/175/3
-f 46/88/4 41/90/4 42/176/4
-f 47/59/6 41/91/6 45/177/6
-f 44/69/5 46/90/5 42/89/5
-f 49/93/1 52/95/1 50/178/1
-f 52/96/8 56/179/8 55/97/8
-f 56/98/3 53/100/3 54/106/3
-f 54/101/7 50/180/7 49/102/7
-f 55/104/9 49/106/9 53/88/9
-f 52/107/10 54/109/10 50/57/10
-f 58/95/1 59/111/1 60/178/1
-f 60/112/11 64/8/11 63/113/11
-f 63/115/3 62/117/3 64/181/3
-f 62/118/11 57/120/11 58/5/11
-f 63/121/12 57/123/12 61/125/12
-f 60/124/13 62/125/13 58/182/13
-f 66/126/1 67/128/1 68/163/1
-f 68/56/11 72/183/11 71/42/11
-f 71/129/3 70/131/3 72/184/3
-f 70/132/11 65/103/11 66/94/11
-f 71/134/12 65/135/12 69/137/12
-f 68/136/13 70/137/13 66/185/13
-f 74/138/1 75/140/1 76/186/1
-f 76/141/2 79/143/2 80/75/2
-f 80/144/3 77/139/3 78/138/3
-f 78/146/4 73/147/4 74/150/4
-f 79/85/6 73/149/6 77/187/6
-f 76/146/5 78/151/5 74/188/5
-f 82/146/1 84/29/1 83/152/1
-f 84/148/2 88/186/2 87/153/2
-f 88/92/3 86/13/3 85/155/3
-f 86/147/4 82/145/4 81/157/4
-f 87/157/5 85/70/5 81/159/5
-f 84/153/6 82/143/6 86/160/6

File diff suppressed because it is too large
+ 13 - 0
pocl.log


+ 0 - 92
readme.md

@@ -1,93 +1 @@
 # RasterIver, a Rendering Engine
-<p align="center">
-  <img src="https://mynameisthe.com/f/1749237242096-rasteriver_example.gif" alt="animated" >
-</p>
-
-#### RasterIver?
-Rasterizer + Iver = RasterIver
-
-## Features
-(todo: write features)
-
-## RI_FLAG List
-- `RI_FLAG_DEBUG` Turns debugging on or off
-- `RI_FLAG_DEBUG_LEVEL` Indepth-ness of debugging 
-- `RI_FLAG_SHOW_BUFFER` The "buffer" to render
-- `RI_FLAG_SHOW_FPS` Shows the FPS
-- `RI_FLAG_DEBUG_FPS` Prints FPS in the console
-- `RI_FLAG_CLEAN_POLYGONS` Clear the polygon array after RI_RequestPolyons is called
-- `RI_FLAG_POPULATE_POLYGONS` Sets random values in the polygon array
-- `RI_FLAG_BE_MASTER_RENDERER` Whether you want to use objects or to have direct access to the polygon array
-- `RI_FLAG_SHOW_FRAME` Shows the current frame #
-- `RI_FLAG_DEBUG_FRAME` Prints the current frame # in the console
-- `RI_FLAG_SHOW_INFO` Shows object info
-- `RI_FLAG_DEBUG_TICK` Turns debugging on or off for anything that would fill up the console when constantly ticking
-- `RI_FLAG_USE_CPU` Use the CPU over the GPU
-- `RI_FLAG_HANDLE_SDL_EVENTS` Whether RasterIver should handle SDL events
-
-## Requirements
-#### To Run
-- SDL2
-- SDL2 TTF
-- OpenCL Runtimes
-#### To Build
-- SDL2
-- SDL2 TTF
-- OpenCL Developer Libraries
-- ROCm if using AMD
-- CUDA if using NVIDIA
-
-
-# Todo
-- [x] make todo list
-- [ ] function to request a mesh. I.E., request a number of polygons/verticies (maybe from presets? planes, cubes, idk) and be able to edit them on the fly. Useful for dynamic terrain or something like that
-- [x] texture support
-- [x] fix interpolation issue with UV maps (and probably normals and Z values too)
-- [ ] fix horribly named variables in request object functions
-- [ ] include rasteriver.h in the kernels for better code updatability (i dont think you can do that)
-- [x] make kernels not be in strings (read the file at compile time and put it inside rasteriver.c as a string? put it in a header like how it is now?)
-- [x] change all iterator variables in for loops to have "i_" before it's variable name
-- [x] add descriptions to RI functions
-- [x] optimize object memory usage by not loading object data multiple times when the same object is requested
-- [x] add checks for invalid/nonexistant files (files like object files & texture files)
-- [x] perspective
-- [x] euler rotation
-- [ ] quaternion rotation
-- [ ] sheer transform (and other fancy ones?)
-- [ ] simple lighting using normals
-- [ ] complex lighting using rays for shadows and stuff
-- [x] polygon clipping by subdividing
-- [x] flag for using CPU instead of GPU
-- [ ] actually acurate FPS cap
-- [ ] make an option for multiple cameras, or defining a camera. I want to be able to write it to a "texture" in menory and have objects use it as their texture
-- [ ] add shaders. Maybe have shader kernels? I have no idea how you would implement that but it sounds cool
-- [x] make the returned array from RI_RequestObjects easier to write to I.E., not a 1D array. Maybe have it so you could do objects[obj #].x_position or something like that. I wonder if I could implement functions with that, too, so you could do objects.get_first_element()
-- [ ] object higherarchies (maybe not. This is moving towards game engine territory. Once I get this into a working release, I'll start working on a game engine)
-- [ ] deltaTime variable or function. (function that returns pointer? function that returns the last deltatime value?)
-- [x] make a function to set a custom debug prefix
-- [ ] add multiple texture support for objects
-- [ ] add support for normal maps
-- [ ] add support for bump/height/displacement maps
-- [ ] add support for transparent textures
-- [ ] allow objects to have no texture
-- [ ] make checks for objects trying to have a texture, but no UV coords (generate them?)
-- [x] FOV
-- [x] add materials
-- [x] make another kernel that calculated transforms & perspective before rasterizing
-- [ ] add ability to request objects multiple times 
-- [ ] give objects IDs or some way to track them so that you can remove them dynamically
-- [ ] make CUDA version because OpenCL is slow with NVIDIA
-- [x] [this wasn't actually a problem. I had -999999999 for r_w but switched how the inputs are. It was rotatiing things -99999999 rad and looked like it was off] fix center of perspective being in the wrong spot
-- [ ] make function for world scale/master scale (scales everything. from origin? from object origins?)
-- [x] I think calculations for debugging memory usage are outdated/wrong
-- [ ] use correct types for stuff (like size_t)
-- [ ] add target resolution
-- [ ] find a faster way to draw pixels to the window
-- [ ] replace "RI_RequestObjects" with 2 functions, RI_CreateObject (which returns a pointer to the object) and RI_LoadObjectFile (which takes in an object file and a pointer). It'll be tough making the object data arrays basically dynamic, but it shouldn't be too hard. Maybe I'll make a termination sequence after each object's data points. Like [x, y, z..... NULL, 0, INFINITY, x, y, z......]. If I know the object I want to delete, I know the start and stopping points of all it's data points. All I have to do is cut them out. Is there a way to squish it back together though? Maybe I could shift all the other data points down, but if there is a substantial amount of them after the cut one, it could take forever.
-- [ ] antialiasing
-- [ ] fix gaps in thin lines
-- [ ] add "transformed" before verticies and normals memory buffers in main kernel to make it less confusing
-- [ ] add overdraw "buffer"
-- [ ] fix spaghetti code
-- [ ] add polygon clipping to GPU
-- [ ] add command line arguments like to select desired GPU 

+ 1 - 1
run

@@ -1 +1 @@
-./builds/final\ binaries/main.bin
+./builds/main.bin

+ 0 - 210
src/RasterIver/headers/bugMath.h

@@ -1,210 +0,0 @@
-#include <math.h>
-
-//SIXBUGSTHREEBRANCHES VERIFIED HEADER
-
-#ifndef BUGMATH_H
-#define BUGMATH_H
-
-
-typedef struct {
-    float x;
-    float y;
-} Vec2;
-
-Vec2 vec2_add(Vec2 a, Vec2 b){
-    Vec2 result = {a.x + b.x, a.y + b.y};
-
-    return result;
-}
-
-Vec2 vec2_sub(Vec2 a, Vec2 b){
-    Vec2 result = {a.x - b.x, a.y - b.y};
-
-    return result;
-}
-
-Vec2 vec2_ham(Vec2 a, Vec2 b){
-    Vec2 result = {a.x * b.x, a.y * b.y};
-
-    return result;
-}
-
-Vec2 vec2_div(Vec2 a, Vec2 b){
-    Vec2 result = {a.x / b.x, a.y / b.y};
-
-    return result;
-}
-
-Vec2 vec2_scale_m(Vec2 v, float scalar){
-    Vec2 result = {v.x*scalar, v.y*scalar};
-
-    return result;
-}
-
-Vec2 vec2_scale_d(Vec2 v, float scalar){
-    Vec2 result = {v.x/scalar, v.y/scalar};
-
-    return result;
-}
-
-Vec2 vec2_perp(Vec2 v){
-    Vec2 result = {-v.y, v.x};
-
-    return result;
-}
-
-float vec2_mag(Vec2 v){
-    float mag = v.x*v.x + v.y*v.y;
-    if(mag == 1.0f){
-        return mag;
-    }
-    return sqrtf(mag);
-}
-
-Vec2 vec2_norm(Vec2 v){
-    return vec2_scale_d(v, vec2_mag(v));
-}
-
-float vec2_dot(Vec2 a, Vec2 b){
-    return a.x*b.x + a.y*b.y;
-}
-
-
-
-typedef struct {
-    float x;
-    float y;
-    float z;
-} Vec3;
-
-Vec3 vec3_add(Vec3 a, Vec3 b){
-    Vec3 result = {a.x + b.x, a.y + b.y, a.z + b.z};
-
-    return result;
-}
-
-Vec3 vec3_sub(Vec3 a, Vec3 b){
-    Vec3 result = {a.x - b.x, a.y - b.y, a.z - b.z};
-
-    return result;
-}
-
-Vec3 vec3_ham(Vec3 a, Vec3 b){
-    Vec3 result = {a.x * b.x, a.y * b.y, a.z * b.z};
-
-    return result;
-}
-
-Vec3 vec3_div(Vec3 a, Vec3 b){
-    Vec3 result = {a.x / b.x, a.y / b.y, a.z / b.z};
-
-    return result;
-}
-
-float vec3_dot(Vec3 a, Vec3 b){
-    return a.x*b.x + a.y*b.y + a.z*b.z;
-}
-
-Vec3 vec3_cross(Vec3 a, Vec3 b){
-    Vec3 result = {a.y*b.z - b.y*a.z, a.z*b.x - b.z*a.x, a.x*b.y - b.x*a.y};;
-
-    return result;
-}
-
-Vec3 vec3_scale_m(Vec3 v, float scalar){
-    Vec3 result = {v.x*scalar, v.y*scalar, v.z*scalar};
-
-    return result;
-}
-
-Vec3 vec3_scale_d(Vec3 v, float scalar){
-    Vec3 result = {v.x/scalar, v.y/scalar, v.z/scalar};
-
-    return result;
-}
-
-float vec3_mag(Vec3 v){
-    float mag = v.x*v.x + v.y*v.y + v.z*v.z;
-    if(mag == 1.0f){
-        return mag;
-    }
-    return sqrtf(mag);
-}
-
-Vec3 vec3_norm(Vec3 v){
-    return vec3_scale_d(v, vec3_mag(v));
-}
-
-
-
-
-typedef struct {
-    float w;
-    float x;
-    float y;
-    float z;
-} Vec4;
-
-Vec4 vec4_add(Vec4 a, Vec4 b){
-    Vec4 result = {a.w + b.w, a.x + b.x, a.y + b.y, a.z + b.z};
-
-    return result;
-}
-
-Vec4 vec4_sub(Vec4 a, Vec4 b){
-    Vec4 result = {a.w - b.w, a.x - b.x, a.y - b.y, a.z - b.z};
-
-    return result;
-}
-
-Vec4 vec4_ham(Vec4 a, Vec4 b){
-    Vec4 result = {a.w * b.w, a.x * b.x, a.y * b.y, a.z * b.z};
-
-    return result;
-}
-
-Vec4 vec4_div(Vec4 a, Vec4 b){
-    Vec4 result = {a.w / b.w, a.x / b.x, a.y / b.y, a.z / b.z};
-
-    return result;
-}
-
-Vec4 quat_mul(Vec4 a, Vec4 b){
-    Vec4 result;
-
-    result.w = (a.w*b.w - a.x*b.x - a.y*b.y - a.z*b.z);
-    result.x = (a.w*b.x + a.x*b.w + a.y*b.z - a.z*b.y);
-    result.y = (a.w*b.y - a.x*b.z + a.y*b.w + a.z*b.x);
-    result.z = (a.w*b.z + a.x*b.y - a.y*b.x + a.z*b.w);
-    
-    return result;
-}
-
-float vec4_dot(Vec4 a, Vec4 b){
-    return a.w*b.w + a.x*b.x + a.y*b.y + a.z*b.z;
-}
-
-Vec4 vec4_scale_m(Vec4 q, float scalar){
-    Vec4 result = {q.w*scalar, q.x*scalar, q.y*scalar, q.z*scalar};
-    return result;
-}
-
-Vec4 vec4_scale_d(Vec4 q, float scalar){
-    Vec4 result = {q.w/scalar, q.x/scalar, q.y/scalar, q.z/scalar};
-    return result;
-}
-
-float vec4_mag(Vec4 q){
-    float mag = q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z;
-    if(mag == 1.0f){
-        return mag;
-    }
-    return sqrtf(mag);
-}
-
-Vec4 vec4_norm(Vec4 q){
-    return vec4_scale_d(q, vec4_mag(q));
-}
-
-
-#endif

+ 0 - 82
src/RasterIver/headers/object.h

@@ -1,82 +0,0 @@
-#ifndef OBJECT_H
-#define OBJECT_H
-
-#include <CL/cl_platform.h>
-
-typedef struct {
-    float x;
-    float y;
-} Vec2;
-
-Vec2 lerp(Vec2 pos1, Vec2 pos2, float fraction){
-    Vec2 result;
-
-    float w0 = 1.0 - fraction;
-    float w1 = fraction;
-
-    result.x = pos1.x * w0 + pos2.x * w1;
-    result.y = pos1.y * w0 + pos2.y * w1;
-
-    return result;
-
-}
-
-typedef struct __attribute__((aligned(4))) {
-    cl_uchar a; // 1
-    cl_uchar r; // 1
-    cl_uchar g; // 1
-    cl_uchar b; // 1
-} ColorARGB; // size: 4, align: 4
-
-typedef struct __attribute__((aligned(4))) {
-    ColorARGB albedo;     // 4
-    cl_int textureOffset; // 4
-    cl_int normalMapOffset; // 4
-    cl_int bumpMapOffset; // 4
-    cl_ulong properties; // 8
-} Material; // size 24
-
-typedef struct __attribute__((aligned(16))) {
-    cl_float x; // 4
-    cl_float y; // 4
-    cl_float z; // 4
-    cl_float _pad0; // padding to align to 16 bytes
-} Vec3;
-
-typedef struct __attribute__((aligned(16))) {
-    cl_float w;
-    cl_float x;
-    cl_float y;
-    cl_float z;
-} Vec4;
-
-typedef struct __attribute__((aligned(16))) {
-    Vec3 position;  // 16 bytes
-    Vec3 scale;     // 16 bytes
-    Vec4 rotation;  // 16 bytes
-} Transform; // size: 48 bytes
-
-typedef struct __attribute__((aligned(4))) {
-    cl_int transformedVertexOffset;
-    cl_int transformedNormalOffset;
-    cl_int triangleCount;
-    cl_int vertexCount;
-    cl_int normalCount;
-    cl_int uvCount;
-    cl_int triangleOffset;
-    cl_int vertexOffset;
-    cl_int normalOffset;
-    cl_int uvOffset;
-} ModelInfo; // 10 × 4 = 40 bytes
-
-typedef struct __attribute__((aligned(16))) {
-    Transform transform;   // 64
-    ModelInfo modelInfo;   // 40
-    cl_int id;             // 4
-    cl_int split_triangles;          // 4 (pad so Material starts at 8-byte boundary)
-    Material material;     // 8
-    cl_int _pad2;          // 4 (pad to make Object size 128 bytes)
-    cl_int _pad3;          // 4
-} Object; // total: 64 + 40 + 4 + 4 + 8 + 4 + 4 = 128 bytes
-
-#endif

+ 0 - 172
src/RasterIver/headers/rasteriver.h

@@ -1,172 +0,0 @@
-#ifndef RASTERIVER_H
-#define RASTERIVER_H
-
-#define STB_IMAGE_IMPLEMENTATION
-#include "stb_image.h"
-#include <stdint.h>
-#include <SDL2/SDL.h>
-#include "object.h"
-
-typedef int RI_result;
-typedef int RI_flag;
-typedef int RI_value;
-typedef uint32_t RI_uint;
-typedef float* RI_polygons;
-typedef float* RI_verticies;
-typedef int* RI_triangles;
-typedef Object* RI_objects;
-typedef unsigned char* RI_textures;
-
-// the size of each object instance in the objects array
-// xyz + rot(xyz) + scale(xyz) = 9
-// 9 + polygon count + polygon index + vertex index + normal index + UV index + texture index + rotation w = 16
-#define object_size 16
-
-// vertex size
-// the size of each instance of verticies
-#define vs 3
-
-// triangle size
-// 3 xyz 3 normals 3 uvs 
-#define ts 9
-
-// texture info size
-// width + height + value offset = 3
-#define tis 3
-
-#define transformed_verticies_size 12
-
-// PI
-#define RI_PI 3.14159265359
-#define RI_2PI 6.28318530718
-
-typedef struct {
-    float x, y, z, r_x, r_y, r_z, r_w, s_x, s_y, s_z;
-    uint64_t material_flags;
-    char file_path[40];
-    char texture[40];
-} RI_newObject;
-
-typedef struct {
-    int verticies, normals, uvs, faces, length_of_texture;
-} load_object_return;
-
-// RI_result
-typedef enum {
-    RI_ERROR        = -1,
-    RI_SUCCESS      =  0,
-    RI_NOT_RUNNING  = -2,
-    RI_RUNNING      =  1,
-    RI_INVALID_FLAG = -3,
-    RI_INVALID_VALUE = -4,
-} RI_result_enum;
-
-// RI_flag
-typedef enum {
-    RI_FLAG_DEBUG               = 0,
-    RI_FLAG_DEBUG_LEVEL         = 1,
-    RI_FLAG_SHOW_BUFFER         = 2,
-    RI_FLAG_SHOW_FPS            = 3,
-    RI_FLAG_DEBUG_FPS           = 4,
-    RI_FLAG_CLEAN_POLYGONS      = 5,
-    RI_FLAG_POPULATE_POLYGONS   = 6,
-    RI_FLAG_BE_MASTER_RENDERER  = 7,
-    RI_FLAG_DEBUG_FRAME         = 8,
-    RI_FLAG_SHOW_FRAME          = 9,
-    RI_FLAG_SHOW_INFO           = 10,
-    RI_FLAG_DEBUG_TICK          = 11,
-    RI_FLAG_USE_CPU             = 12,
-    RI_FLAG_HANDLE_SDL_EVENTS   = 13,
-} RI_flag_enum;
-
-typedef enum {
-    RI_VALUE_WIREFRAME_SCALE = 0,
-    RI_VALUE_SELECTED_TRIANGLE = 1,
-    RI_VALUE_MINIMUM_CLIP = 2,
-} RI_value_enum;
-
-// RI_BUFFER
-typedef enum {
-    RI_BUFFER_COMPLETE  = 0,
-    RI_BUFFER_Z         = 1,
-    RI_BUFFER_NORMAL    = 2,
-    RI_BUFFER_UV        = 3,
-} RI_buffer_enum;
-
-// RI_DEBUG
-typedef enum {
-    RI_DEBUG_LOW      = 0,
-    RI_DEBUG_MEDIUM   = 1,
-    RI_DEBUG_HIGH     = 2,
-} RI_debug_enum;
-
-typedef enum {
-    RI_MATERIAL_UNLIT = ((uint64_t)1 << 0), // should calculate lighting
-    RI_MATERIAL_DONT_CAST_SHADOW = ((uint64_t)1 << 1), // should cast shadow on other objects
-    RI_MATERIAL_HAS_TEXTURE = ((uint64_t)1 << 2), // has a texture
-    RI_MATERIAL_HAS_NORMAL_MAP = ((uint64_t)1 << 3), // has a normal map
-    RI_MATERIAL_HAS_BUMP_MAP = ((uint64_t)1 << 4), // has a bump map
-    RI_MATERIAL_TRANSPARENT = ((uint64_t)1 << 5), // has transparency
-    RI_MATERIAL_WIREFRAME = ((uint64_t)1 << 6), // render as wireframe
-    RI_MATERIAL_DONT_RECEIVE_SHADOW = ((uint64_t)1 << 7), // should shadows render on it
-    RI_MATERIAL_DONT_DEPTH_TEST = ((uint64_t)1 << 8), // should check Z buffer (if 1, render on top of everything)
-    RI_MATERIAL_DONT_DEPTH_WRITE = ((uint64_t)1 << 9), // should write to the Z buffer (if 1, render behind everything)
-    RI_MATERIAL_DOUBLE_SIDED = ((uint64_t)1 << 10), // ignore backface culling
-} RI_material_properties_enum;
-
-typedef enum {
-    RI_PMP_TEXTURED = RI_MATERIAL_HAS_TEXTURE,
-} RI_preset_material_properties;
-
-// RI_BOOL
-typedef enum {
-    RI_TRUE      = 1,
-    RI_FALSE   = 0,
-} RI_bool_enum;
-
-// Initializes OpenCL, SDL2, and anything else Rasteriver needs to function
-RI_result   RI_Init();
-
-// Safely stops Rasteriver
-RI_result   RI_Stop();
-
-// Checks if Rasteriver is still running and returns if it is
-RI_result   RI_IsRunning();
-
-// Asks Rasteriver to allocate space for a number of polygons
-// Returns a pointer to the new object
-int* RI_RequestMesh(int RI_PolygonsToRequest);
-
-// Asks Rasteriver to allocate and load objects
-// Returns a pointer to the objects array
-RI_objects  RI_RequestObjects(RI_newObject *RI_ObjectBuffer, int RI_ObjectsToRequest);
-
-// Ticks Rasteriver
-RI_result   RI_Tick();
-
-// Sets the background color
-RI_result   RI_SetBackground(RI_uint RI_BackgroundColor);
-
-// Depricated
-// Shows the Z buffer
-RI_result   RI_ShowZBuffer(int RI_ShowZBufferFlag);
-
-// Sets a flag
-RI_result   RI_SetFlag(RI_flag RI_FlagToSet, int RI_Value);
-
-// Sets a value
-RI_result   RI_SetValue(RI_value RI_ValueToSet, float RI_Value);
-
-// Sets the FPS limit
-RI_result   RI_SetFpsCap(int RI_FpsCap);
-
-// Depricated
-// Returns a list of Rasteriver flags
-RI_result   RI_ListFlags();
-
-// Sets the prefix when debugging
-// Takes a 49 char string (50 including \0)
-// Default is [RasterIver] 
-RI_result RI_SetDebugPrefix(char RI_Prefix[50]);
-
-#endif // RASTERIVER_H

+ 0 - 7988
src/RasterIver/headers/stb_image.h

@@ -1,7988 +0,0 @@
-/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb
-                                  no warranty implied; use at your own risk
-
-   Do this:
-      #define STB_IMAGE_IMPLEMENTATION
-   before you include this file in *one* C or C++ file to create the implementation.
-
-   // i.e. it should look like this:
-   #include ...
-   #include ...
-   #include ...
-   #define STB_IMAGE_IMPLEMENTATION
-   #include "stb_image.h"
-
-   You can #define STBI_ASSERT(x) before the #include to avoid using assert.h.
-   And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free
-
-
-   QUICK NOTES:
-      Primarily of interest to game developers and other people who can
-          avoid problematic images and only need the trivial interface
-
-      JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
-      PNG 1/2/4/8/16-bit-per-channel
-
-      TGA (not sure what subset, if a subset)
-      BMP non-1bpp, non-RLE
-      PSD (composited view only, no extra channels, 8/16 bit-per-channel)
-
-      GIF (*comp always reports as 4-channel)
-      HDR (radiance rgbE format)
-      PIC (Softimage PIC)
-      PNM (PPM and PGM binary only)
-
-      Animated GIF still needs a proper API, but here's one way to do it:
-          http://gist.github.com/urraka/685d9a6340b26b830d49
-
-      - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
-      - decode from arbitrary I/O callbacks
-      - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
-
-   Full documentation under "DOCUMENTATION" below.
-
-
-LICENSE
-
-  See end of file for license information.
-
-RECENT REVISION HISTORY:
-
-      2.30  (2024-05-31) avoid erroneous gcc warning
-      2.29  (2023-05-xx) optimizations
-      2.28  (2023-01-29) many error fixes, security errors, just tons of stuff
-      2.27  (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
-      2.26  (2020-07-13) many minor fixes
-      2.25  (2020-02-02) fix warnings
-      2.24  (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically
-      2.23  (2019-08-11) fix clang static analysis warning
-      2.22  (2019-03-04) gif fixes, fix warnings
-      2.21  (2019-02-25) fix typo in comment
-      2.20  (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
-      2.19  (2018-02-11) fix warning
-      2.18  (2018-01-30) fix warnings
-      2.17  (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
-      2.16  (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
-      2.15  (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
-      2.14  (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
-      2.13  (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
-      2.12  (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
-      2.11  (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
-                         RGB-format JPEG; remove white matting in PSD;
-                         allocate large structures on the stack;
-                         correct channel count for PNG & BMP
-      2.10  (2016-01-22) avoid warning introduced in 2.09
-      2.09  (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
-
-   See end of file for full revision history.
-
-
- ============================    Contributors    =========================
-
- Image formats                          Extensions, features
-    Sean Barrett (jpeg, png, bmp)          Jetro Lauha (stbi_info)
-    Nicolas Schulz (hdr, psd)              Martin "SpartanJ" Golini (stbi_info)
-    Jonathan Dummer (tga)                  James "moose2000" Brown (iPhone PNG)
-    Jean-Marc Lienher (gif)                Ben "Disch" Wenger (io callbacks)
-    Tom Seddon (pic)                       Omar Cornut (1/2/4-bit PNG)
-    Thatcher Ulrich (psd)                  Nicolas Guillemot (vertical flip)
-    Ken Miller (pgm, ppm)                  Richard Mitton (16-bit PSD)
-    github:urraka (animated gif)           Junggon Kim (PNM comments)
-    Christopher Forseth (animated gif)     Daniel Gibson (16-bit TGA)
-                                           socks-the-fox (16-bit PNG)
-                                           Jeremy Sawicki (handle all ImageNet JPGs)
- Optimizations & bugfixes                  Mikhail Morozov (1-bit BMP)
-    Fabian "ryg" Giesen                    Anael Seghezzi (is-16-bit query)
-    Arseny Kapoulkine                      Simon Breuss (16-bit PNM)
-    John-Mark Allen
-    Carmelo J Fdez-Aguera
-
- Bug & warning fixes
-    Marc LeBlanc            David Woo          Guillaume George     Martins Mozeiko
-    Christpher Lloyd        Jerry Jansson      Joseph Thomson       Blazej Dariusz Roszkowski
-    Phil Jordan                                Dave Moore           Roy Eltham
-    Hayaki Saito            Nathan Reed        Won Chun
-    Luke Graham             Johan Duparc       Nick Verigakis       the Horde3D community
-    Thomas Ruf              Ronny Chevalier                         github:rlyeh
-    Janez Zemva             John Bartholomew   Michal Cichon        github:romigrou
-    Jonathan Blow           Ken Hamada         Tero Hanninen        github:svdijk
-    Eugene Golushkov        Laurent Gomila     Cort Stratton        github:snagar
-    Aruelien Pocheville     Sergio Gonzalez    Thibault Reuille     github:Zelex
-    Cass Everitt            Ryamond Barbiero                        github:grim210
-    Paul Du Bois            Engin Manap        Aldo Culquicondor    github:sammyhw
-    Philipp Wiesemann       Dale Weiler        Oriol Ferrer Mesia   github:phprus
-    Josh Tobin              Neil Bickford      Matthew Gregan       github:poppolopoppo
-    Julian Raschke          Gregory Mullen     Christian Floisand   github:darealshinji
-    Baldur Karlsson         Kevin Schmidt      JR Smith             github:Michaelangel007
-                            Brad Weinberger    Matvey Cherevko      github:mosra
-    Luca Sas                Alexander Veselov  Zack Middleton       [reserved]
-    Ryan C. Gordon          [reserved]                              [reserved]
-                     DO NOT ADD YOUR NAME HERE
-
-                     Jacko Dirks
-
-  To add your name to the credits, pick a random blank space in the middle and fill it.
-  80% of merge conflicts on stb PRs are due to people adding their name at the end
-  of the credits.
-*/
-
-#ifndef STBI_INCLUDE_STB_IMAGE_H
-#define STBI_INCLUDE_STB_IMAGE_H
-
-// DOCUMENTATION
-//
-// Limitations:
-//    - no 12-bit-per-channel JPEG
-//    - no JPEGs with arithmetic coding
-//    - GIF always returns *comp=4
-//
-// Basic usage (see HDR discussion below for HDR usage):
-//    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 *channels_in_file  -- outputs # of image components in image file
-//    int desired_channels   -- 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, or NULL on an allocation failure or if the image is
-// corrupt or invalid. 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 'desired_channels' if desired_channels is non-zero, or
-// *channels_in_file otherwise. If desired_channels is non-zero,
-// *channels_in_file has the number of components that _would_ have been
-// output otherwise. E.g. if you set desired_channels to 4, you will always
-// get RGBA output, but you can check *channels_in_file to see if it's trivially
-// opaque because e.g. there were only 3 channels in the source image.
-//
-// 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, *channels_in_file 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.
-//
-// To query the width, height and component count of an image without having to
-// decode the full file, you can use the stbi_info family of functions:
-//
-//   int x,y,n,ok;
-//   ok = stbi_info(filename, &x, &y, &n);
-//   // returns ok=1 and sets x, y, n if image is a supported format,
-//   // 0 otherwise.
-//
-// Note that stb_image pervasively uses ints in its public API for sizes,
-// including sizes of memory buffers. This is now part of the API and thus
-// hard to change without causing breakage. As a result, the various image
-// loaders all have certain limits on image size; these differ somewhat
-// by format but generally boil down to either just under 2GB or just under
-// 1GB. When the decoded image would be larger than this, stb_image decoding
-// will fail.
-//
-// Additionally, stb_image will reject image files that have any of their
-// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS,
-// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit,
-// the only way to have an image with such dimensions load correctly
-// is for it to have a rather extreme aspect ratio. Either way, the
-// assumption here is that such larger images are likely to be malformed
-// or malicious. If you do need to load an image with individual dimensions
-// larger than that, and it still fits in the overall size limit, you can
-// #define STBI_MAX_DIMENSIONS on your own to be something larger.
-//
-// ===========================================================================
-//
-// UNICODE:
-//
-//   If compiling for Windows and you wish to use Unicode filenames, compile
-//   with
-//       #define STBI_WINDOWS_UTF8
-//   and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert
-//   Windows wchar_t filenames to utf8.
-//
-// ===========================================================================
-//
-// Philosophy
-//
-// stb libraries are designed with the following priorities:
-//
-//    1. easy to use
-//    2. easy to maintain
-//    3. good performance
-//
-// Sometimes I let "good performance" creep up in priority over "easy to maintain",
-// and for best performance I may provide less-easy-to-use APIs that give higher
-// performance, in addition to the easy-to-use ones. Nevertheless, it's important
-// to keep in mind that from the standpoint of you, a client of this library,
-// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
-//
-// Some secondary priorities arise directly from the first two, some of which
-// provide more explicit reasons why performance can't be emphasized.
-//
-//    - Portable ("ease of use")
-//    - Small source code footprint ("easy to maintain")
-//    - No dependencies ("ease of use")
-//
-// ===========================================================================
-//
-// 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).
-//
-// ===========================================================================
-//
-// SIMD support
-//
-// The JPEG decoder will try to automatically use SIMD kernels on x86 when
-// supported by the compiler. For ARM Neon support, you must explicitly
-// request it.
-//
-// (The old do-it-yourself SIMD API is no longer supported in the current
-// code.)
-//
-// On x86, SSE2 will automatically be used when available based on a run-time
-// test; if not, the generic C versions are used as a fall-back. On ARM targets,
-// the typical path is to have separate builds for NEON and non-NEON devices
-// (at least this is true for iOS and Android). Therefore, the NEON support is
-// toggled by a build flag: define STBI_NEON to get NEON loops.
-//
-// If for some reason you do not want to use any of SIMD code, or if
-// you have issues compiling it, you can disable it entirely by
-// defining STBI_NO_SIMD.
-//
-// ===========================================================================
-//
-// HDR image support   (disable by defining STBI_NO_HDR)
-//
-// stb_image supports loading HDR images in general, and currently the Radiance
-// .HDR file format specifically. 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);
-//
-// ===========================================================================
-//
-// iPhone PNG support:
-//
-// We optionally support converting iPhone-formatted PNGs (which store
-// premultiplied BGRA) back to RGB, even though they're internally encoded
-// differently. To enable this conversion, call
-// stbi_convert_iphone_png_to_rgb(1).
-//
-// 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).
-//
-// ===========================================================================
-//
-// ADDITIONAL CONFIGURATION
-//
-//  - You can suppress implementation of any of the decoders to reduce
-//    your code footprint by #defining one or more of the following
-//    symbols before creating the implementation.
-//
-//        STBI_NO_JPEG
-//        STBI_NO_PNG
-//        STBI_NO_BMP
-//        STBI_NO_PSD
-//        STBI_NO_TGA
-//        STBI_NO_GIF
-//        STBI_NO_HDR
-//        STBI_NO_PIC
-//        STBI_NO_PNM   (.ppm and .pgm)
-//
-//  - You can request *only* certain decoders and suppress all other ones
-//    (this will be more forward-compatible, as addition of new decoders
-//    doesn't require you to disable them explicitly):
-//
-//        STBI_ONLY_JPEG
-//        STBI_ONLY_PNG
-//        STBI_ONLY_BMP
-//        STBI_ONLY_PSD
-//        STBI_ONLY_TGA
-//        STBI_ONLY_GIF
-//        STBI_ONLY_HDR
-//        STBI_ONLY_PIC
-//        STBI_ONLY_PNM   (.ppm and .pgm)
-//
-//   - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
-//     want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
-//
-//  - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater
-//    than that size (in either width or height) without further processing.
-//    This is to let programs in the wild set an upper bound to prevent
-//    denial-of-service attacks on untrusted data, as one could generate a
-//    valid image of gigantic dimensions and force stb_image to allocate a
-//    huge block of memory and spend disproportionate time decoding it. By
-//    default this is set to (1 << 24), which is 16777216, but that's still
-//    very big.
-
-#ifndef STBI_NO_STDIO
-#include <stdio.h>
-#endif // STBI_NO_STDIO
-
-#define STBI_VERSION 1
-
-enum
-{
-   STBI_default = 0, // only used for desired_channels
-
-   STBI_grey       = 1,
-   STBI_grey_alpha = 2,
-   STBI_rgb        = 3,
-   STBI_rgb_alpha  = 4
-};
-
-#include <stdlib.h>
-typedef unsigned char stbi_uc;
-typedef unsigned short stbi_us;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef STBIDEF
-#ifdef STB_IMAGE_STATIC
-#define STBIDEF static
-#else
-#define STBIDEF extern
-#endif
-#endif
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// PRIMARY API - works on images of any type
-//
-
-//
-// load image by filename, open file, or memory buffer
-//
-
-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,int n);                 // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
-   int      (*eof)   (void *user);                       // returns nonzero if we are at end of file/data
-} stbi_io_callbacks;
-
-////////////////////////////////////
-//
-// 8-bits-per-channel interface
-//
-
-STBIDEF stbi_uc *stbi_load_from_memory   (stbi_uc           const *buffer, int len   , int *x, int *y, int *channels_in_file, int desired_channels);
-STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk  , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
-
-#ifndef STBI_NO_STDIO
-STBIDEF stbi_uc *stbi_load            (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
-STBIDEF stbi_uc *stbi_load_from_file  (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
-// for stbi_load_from_file, file pointer is left pointing immediately after image
-#endif
-
-#ifndef STBI_NO_GIF
-STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
-#endif
-
-#ifdef STBI_WINDOWS_UTF8
-STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
-#endif
-
-////////////////////////////////////
-//
-// 16-bits-per-channel interface
-//
-
-STBIDEF stbi_us *stbi_load_16_from_memory   (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
-STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
-
-#ifndef STBI_NO_STDIO
-STBIDEF stbi_us *stbi_load_16          (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
-STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
-#endif
-
-////////////////////////////////////
-//
-// float-per-channel interface
-//
-#ifndef STBI_NO_LINEAR
-   STBIDEF float *stbi_loadf_from_memory     (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
-   STBIDEF float *stbi_loadf_from_callbacks  (stbi_io_callbacks const *clbk, void *user, int *x, int *y,  int *channels_in_file, int desired_channels);
-
-   #ifndef STBI_NO_STDIO
-   STBIDEF float *stbi_loadf            (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
-   STBIDEF float *stbi_loadf_from_file  (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
-   #endif
-#endif
-
-#ifndef STBI_NO_HDR
-   STBIDEF void   stbi_hdr_to_ldr_gamma(float gamma);
-   STBIDEF void   stbi_hdr_to_ldr_scale(float scale);
-#endif // STBI_NO_HDR
-
-#ifndef STBI_NO_LINEAR
-   STBIDEF void   stbi_ldr_to_hdr_gamma(float gamma);
-   STBIDEF void   stbi_ldr_to_hdr_scale(float scale);
-#endif // STBI_NO_LINEAR
-
-// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
-STBIDEF int    stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
-STBIDEF int    stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
-#ifndef STBI_NO_STDIO
-STBIDEF int      stbi_is_hdr          (char const *filename);
-STBIDEF int      stbi_is_hdr_from_file(FILE *f);
-#endif // STBI_NO_STDIO
-
-
-// get a VERY brief reason for failure
-// on most compilers (and ALL modern mainstream compilers) this is threadsafe
-STBIDEF const char *stbi_failure_reason  (void);
-
-// free the loaded image -- this is just free()
-STBIDEF void     stbi_image_free      (void *retval_from_stbi_load);
-
-// get image dimensions & components without fully decoding
-STBIDEF int      stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
-STBIDEF int      stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
-STBIDEF int      stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len);
-STBIDEF int      stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user);
-
-#ifndef STBI_NO_STDIO
-STBIDEF int      stbi_info               (char const *filename,     int *x, int *y, int *comp);
-STBIDEF int      stbi_info_from_file     (FILE *f,                  int *x, int *y, int *comp);
-STBIDEF int      stbi_is_16_bit          (char const *filename);
-STBIDEF int      stbi_is_16_bit_from_file(FILE *f);
-#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.
-STBIDEF 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"
-STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
-
-// flip the image vertically, so the first pixel in the output array is the bottom left
-STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
-
-// as above, but only applies to images loaded on the thread that calls the function
-// this function is only available if your compiler supports thread-local variables;
-// calling it will fail to link if your compiler doesn't
-STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply);
-STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert);
-STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip);
-
-// ZLIB client - used by PNG, available for other purposes
-
-STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
-STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header);
-STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
-STBIDEF int   stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
-
-STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
-STBIDEF int   stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-//
-//
-////   end header file   /////////////////////////////////////////////////////
-#endif // STBI_INCLUDE_STB_IMAGE_H
-
-#ifdef STB_IMAGE_IMPLEMENTATION
-
-#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \
-  || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \
-  || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \
-  || defined(STBI_ONLY_ZLIB)
-   #ifndef STBI_ONLY_JPEG
-   #define STBI_NO_JPEG
-   #endif
-   #ifndef STBI_ONLY_PNG
-   #define STBI_NO_PNG
-   #endif
-   #ifndef STBI_ONLY_BMP
-   #define STBI_NO_BMP
-   #endif
-   #ifndef STBI_ONLY_PSD
-   #define STBI_NO_PSD
-   #endif
-   #ifndef STBI_ONLY_TGA
-   #define STBI_NO_TGA
-   #endif
-   #ifndef STBI_ONLY_GIF
-   #define STBI_NO_GIF
-   #endif
-   #ifndef STBI_ONLY_HDR
-   #define STBI_NO_HDR
-   #endif
-   #ifndef STBI_ONLY_PIC
-   #define STBI_NO_PIC
-   #endif
-   #ifndef STBI_ONLY_PNM
-   #define STBI_NO_PNM
-   #endif
-#endif
-
-#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB)
-#define STBI_NO_ZLIB
-#endif
-
-
-#include <stdarg.h>
-#include <stddef.h> // ptrdiff_t on osx
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-
-#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
-#include <math.h>  // ldexp, pow
-#endif
-
-#ifndef STBI_NO_STDIO
-#include <stdio.h>
-#endif
-
-#ifndef STBI_ASSERT
-#include <assert.h>
-#define STBI_ASSERT(x) assert(x)
-#endif
-
-#ifdef __cplusplus
-#define STBI_EXTERN extern "C"
-#else
-#define STBI_EXTERN extern
-#endif
-
-
-#ifndef _MSC_VER
-   #ifdef __cplusplus
-   #define stbi_inline inline
-   #else
-   #define stbi_inline
-   #endif
-#else
-   #define stbi_inline __forceinline
-#endif
-
-#ifndef STBI_NO_THREAD_LOCALS
-   #if defined(__cplusplus) &&  __cplusplus >= 201103L
-      #define STBI_THREAD_LOCAL       thread_local
-   #elif defined(__GNUC__) && __GNUC__ < 5
-      #define STBI_THREAD_LOCAL       __thread
-   #elif defined(_MSC_VER)
-      #define STBI_THREAD_LOCAL       __declspec(thread)
-   #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
-      #define STBI_THREAD_LOCAL       _Thread_local
-   #endif
-
-   #ifndef STBI_THREAD_LOCAL
-      #if defined(__GNUC__)
-        #define STBI_THREAD_LOCAL       __thread
-      #endif
-   #endif
-#endif
-
-#if defined(_MSC_VER) || defined(__SYMBIAN32__)
-typedef unsigned short stbi__uint16;
-typedef   signed short stbi__int16;
-typedef unsigned int   stbi__uint32;
-typedef   signed int   stbi__int32;
-#else
-#include <stdint.h>
-typedef uint16_t stbi__uint16;
-typedef int16_t  stbi__int16;
-typedef uint32_t stbi__uint32;
-typedef int32_t  stbi__int32;
-#endif
-
-// should produce compiler error if size is wrong
-typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
-
-#ifdef _MSC_VER
-#define STBI_NOTUSED(v)  (void)(v)
-#else
-#define STBI_NOTUSED(v)  (void)sizeof(v)
-#endif
-
-#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) >> (-(y) & 31)))
-#endif
-
-#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
-// ok
-#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED)
-// ok
-#else
-#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)."
-#endif
-
-#ifndef STBI_MALLOC
-#define STBI_MALLOC(sz)           malloc(sz)
-#define STBI_REALLOC(p,newsz)     realloc(p,newsz)
-#define STBI_FREE(p)              free(p)
-#endif
-
-#ifndef STBI_REALLOC_SIZED
-#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
-#endif
-
-// x86/x64 detection
-#if defined(__x86_64__) || defined(_M_X64)
-#define STBI__X64_TARGET
-#elif defined(__i386) || defined(_M_IX86)
-#define STBI__X86_TARGET
-#endif
-
-#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
-// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
-// which in turn means it gets to use SSE2 everywhere. This is unfortunate,
-// but previous attempts to provide the SSE2 functions with runtime
-// detection caused numerous issues. The way architecture extensions are
-// exposed in GCC/Clang is, sadly, not really suited for one-file libs.
-// New behavior: if compiled with -msse2, we use SSE2 without any
-// detection; if not, we don't use it at all.
-#define STBI_NO_SIMD
-#endif
-
-#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD)
-// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET
-//
-// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the
-// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant.
-// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not
-// simultaneously enabling "-mstackrealign".
-//
-// See https://github.com/nothings/stb/issues/81 for more information.
-//
-// So default to no SSE2 on 32-bit MinGW. If you've read this far and added
-// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2.
-#define STBI_NO_SIMD
-#endif
-
-#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET))
-#define STBI_SSE2
-#include <emmintrin.h>
-
-#ifdef _MSC_VER
-
-#if _MSC_VER >= 1400  // not VC6
-#include <intrin.h> // __cpuid
-static int stbi__cpuid3(void)
-{
-   int info[4];
-   __cpuid(info,1);
-   return info[3];
-}
-#else
-static int stbi__cpuid3(void)
-{
-   int res;
-   __asm {
-      mov  eax,1
-      cpuid
-      mov  res,edx
-   }
-   return res;
-}
-#endif
-
-#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
-
-#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
-static int stbi__sse2_available(void)
-{
-   int info3 = stbi__cpuid3();
-   return ((info3 >> 26) & 1) != 0;
-}
-#endif
-
-#else // assume GCC-style if not VC++
-#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
-
-#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
-static int stbi__sse2_available(void)
-{
-   // If we're even attempting to compile this on GCC/Clang, that means
-   // -msse2 is on, which means the compiler is allowed to use SSE2
-   // instructions at will, and so are we.
-   return 1;
-}
-#endif
-
-#endif
-#endif
-
-// ARM NEON
-#if defined(STBI_NO_SIMD) && defined(STBI_NEON)
-#undef STBI_NEON
-#endif
-
-#ifdef STBI_NEON
-#include <arm_neon.h>
-#ifdef _MSC_VER
-#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
-#else
-#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
-#endif
-#endif
-
-#ifndef STBI_SIMD_ALIGN
-#define STBI_SIMD_ALIGN(type, name) type name
-#endif
-
-#ifndef STBI_MAX_DIMENSIONS
-#define STBI_MAX_DIMENSIONS (1 << 24)
-#endif
-
-///////////////////////////////////////////////
-//
-//  stbi__context struct and start_xxx functions
-
-// stbi__context structure is our basic context used by all images, so it
-// contains all the IO context, plus some basic image information
-typedef struct
-{
-   stbi__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;
-   stbi_uc buffer_start[128];
-   int callback_already_read;
-
-   stbi_uc *img_buffer, *img_buffer_end;
-   stbi_uc *img_buffer_original, *img_buffer_original_end;
-} stbi__context;
-
-
-static void stbi__refill_buffer(stbi__context *s);
-
-// initialize a memory-decode context
-static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
-{
-   s->io.read = NULL;
-   s->read_from_callbacks = 0;
-   s->callback_already_read = 0;
-   s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
-   s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
-}
-
-// initialize a callback-based context
-static void stbi__start_callbacks(stbi__context *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->callback_already_read = 0;
-   s->img_buffer = s->img_buffer_original = s->buffer_start;
-   stbi__refill_buffer(s);
-   s->img_buffer_original_end = s->img_buffer_end;
-}
-
-#ifndef STBI_NO_STDIO
-
-static int stbi__stdio_read(void *user, char *data, int size)
-{
-   return (int) fread(data,1,size,(FILE*) user);
-}
-
-static void stbi__stdio_skip(void *user, int n)
-{
-   int ch;
-   fseek((FILE*) user, n, SEEK_CUR);
-   ch = fgetc((FILE*) user);  /* have to read a byte to reset feof()'s flag */
-   if (ch != EOF) {
-      ungetc(ch, (FILE *) user);  /* push byte back onto stream if valid. */
-   }
-}
-
-static int stbi__stdio_eof(void *user)
-{
-   return feof((FILE*) user) || ferror((FILE *) user);
-}
-
-static stbi_io_callbacks stbi__stdio_callbacks =
-{
-   stbi__stdio_read,
-   stbi__stdio_skip,
-   stbi__stdio_eof,
-};
-
-static void stbi__start_file(stbi__context *s, FILE *f)
-{
-   stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f);
-}
-
-//static void stop_file(stbi__context *s) { }
-
-#endif // !STBI_NO_STDIO
-
-static void stbi__rewind(stbi__context *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;
-   s->img_buffer_end = s->img_buffer_original_end;
-}
-
-enum
-{
-   STBI_ORDER_RGB,
-   STBI_ORDER_BGR
-};
-
-typedef struct
-{
-   int bits_per_channel;
-   int num_channels;
-   int channel_order;
-} stbi__result_info;
-
-#ifndef STBI_NO_JPEG
-static int      stbi__jpeg_test(stbi__context *s);
-static void    *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int      stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp);
-#endif
-
-#ifndef STBI_NO_PNG
-static int      stbi__png_test(stbi__context *s);
-static void    *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int      stbi__png_info(stbi__context *s, int *x, int *y, int *comp);
-static int      stbi__png_is16(stbi__context *s);
-#endif
-
-#ifndef STBI_NO_BMP
-static int      stbi__bmp_test(stbi__context *s);
-static void    *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int      stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp);
-#endif
-
-#ifndef STBI_NO_TGA
-static int      stbi__tga_test(stbi__context *s);
-static void    *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int      stbi__tga_info(stbi__context *s, int *x, int *y, int *comp);
-#endif
-
-#ifndef STBI_NO_PSD
-static int      stbi__psd_test(stbi__context *s);
-static void    *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc);
-static int      stbi__psd_info(stbi__context *s, int *x, int *y, int *comp);
-static int      stbi__psd_is16(stbi__context *s);
-#endif
-
-#ifndef STBI_NO_HDR
-static int      stbi__hdr_test(stbi__context *s);
-static float   *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int      stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp);
-#endif
-
-#ifndef STBI_NO_PIC
-static int      stbi__pic_test(stbi__context *s);
-static void    *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int      stbi__pic_info(stbi__context *s, int *x, int *y, int *comp);
-#endif
-
-#ifndef STBI_NO_GIF
-static int      stbi__gif_test(stbi__context *s);
-static void    *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static void    *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
-static int      stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
-#endif
-
-#ifndef STBI_NO_PNM
-static int      stbi__pnm_test(stbi__context *s);
-static void    *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int      stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
-static int      stbi__pnm_is16(stbi__context *s);
-#endif
-
-static
-#ifdef STBI_THREAD_LOCAL
-STBI_THREAD_LOCAL
-#endif
-const char *stbi__g_failure_reason;
-
-STBIDEF const char *stbi_failure_reason(void)
-{
-   return stbi__g_failure_reason;
-}
-
-#ifndef STBI_NO_FAILURE_STRINGS
-static int stbi__err(const char *str)
-{
-   stbi__g_failure_reason = str;
-   return 0;
-}
-#endif
-
-static void *stbi__malloc(size_t size)
-{
-    return STBI_MALLOC(size);
-}
-
-// stb_image uses ints pervasively, including for offset calculations.
-// therefore the largest decoded image size we can support with the
-// current code, even on 64-bit targets, is INT_MAX. this is not a
-// significant limitation for the intended use case.
-//
-// we do, however, need to make sure our size calculations don't
-// overflow. hence a few helper functions for size calculations that
-// multiply integers together, making sure that they're non-negative
-// and no overflow occurs.
-
-// return 1 if the sum is valid, 0 on overflow.
-// negative terms are considered invalid.
-static int stbi__addsizes_valid(int a, int b)
-{
-   if (b < 0) return 0;
-   // now 0 <= b <= INT_MAX, hence also
-   // 0 <= INT_MAX - b <= INTMAX.
-   // And "a + b <= INT_MAX" (which might overflow) is the
-   // same as a <= INT_MAX - b (no overflow)
-   return a <= INT_MAX - b;
-}
-
-// returns 1 if the product is valid, 0 on overflow.
-// negative factors are considered invalid.
-static int stbi__mul2sizes_valid(int a, int b)
-{
-   if (a < 0 || b < 0) return 0;
-   if (b == 0) return 1; // mul-by-0 is always safe
-   // portable way to check for no overflows in a*b
-   return a <= INT_MAX/b;
-}
-
-#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR)
-// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow
-static int stbi__mad2sizes_valid(int a, int b, int add)
-{
-   return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add);
-}
-#endif
-
-// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow
-static int stbi__mad3sizes_valid(int a, int b, int c, int add)
-{
-   return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
-      stbi__addsizes_valid(a*b*c, add);
-}
-
-// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
-#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM)
-static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
-{
-   return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
-      stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add);
-}
-#endif
-
-#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR)
-// mallocs with size overflow checking
-static void *stbi__malloc_mad2(int a, int b, int add)
-{
-   if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
-   return stbi__malloc(a*b + add);
-}
-#endif
-
-static void *stbi__malloc_mad3(int a, int b, int c, int add)
-{
-   if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL;
-   return stbi__malloc(a*b*c + add);
-}
-
-#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM)
-static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
-{
-   if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL;
-   return stbi__malloc(a*b*c*d + add);
-}
-#endif
-
-// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow.
-static int stbi__addints_valid(int a, int b)
-{
-   if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow
-   if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0.
-   return a <= INT_MAX - b;
-}
-
-// returns 1 if the product of two ints fits in a signed short, 0 on overflow.
-static int stbi__mul2shorts_valid(int a, int b)
-{
-   if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
-   if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
-   if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN
-   return a >= SHRT_MIN / b;
-}
-
-// stbi__err - error
-// stbi__errpf - error returning pointer to float
-// stbi__errpuc - error returning pointer to unsigned char
-
-#ifdef STBI_NO_FAILURE_STRINGS
-   #define stbi__err(x,y)  0
-#elif defined(STBI_FAILURE_USERMSG)
-   #define stbi__err(x,y)  stbi__err(y)
-#else
-   #define stbi__err(x,y)  stbi__err(x)
-#endif
-
-#define stbi__errpf(x,y)   ((float *)(size_t) (stbi__err(x,y)?NULL:NULL))
-#define stbi__errpuc(x,y)  ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL))
-
-STBIDEF void stbi_image_free(void *retval_from_stbi_load)
-{
-   STBI_FREE(retval_from_stbi_load);
-}
-
-#ifndef STBI_NO_LINEAR
-static float   *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
-#endif
-
-#ifndef STBI_NO_HDR
-static stbi_uc *stbi__hdr_to_ldr(float   *data, int x, int y, int comp);
-#endif
-
-static int stbi__vertically_flip_on_load_global = 0;
-
-STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
-{
-   stbi__vertically_flip_on_load_global = flag_true_if_should_flip;
-}
-
-#ifndef STBI_THREAD_LOCAL
-#define stbi__vertically_flip_on_load  stbi__vertically_flip_on_load_global
-#else
-static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set;
-
-STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip)
-{
-   stbi__vertically_flip_on_load_local = flag_true_if_should_flip;
-   stbi__vertically_flip_on_load_set = 1;
-}
-
-#define stbi__vertically_flip_on_load  (stbi__vertically_flip_on_load_set       \
-                                         ? stbi__vertically_flip_on_load_local  \
-                                         : stbi__vertically_flip_on_load_global)
-#endif // STBI_THREAD_LOCAL
-
-static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
-{
-   memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
-   ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed
-   ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
-   ri->num_channels = 0;
-
-   // test the formats with a very explicit header first (at least a FOURCC
-   // or distinctive magic number first)
-   #ifndef STBI_NO_PNG
-   if (stbi__png_test(s))  return stbi__png_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_BMP
-   if (stbi__bmp_test(s))  return stbi__bmp_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_GIF
-   if (stbi__gif_test(s))  return stbi__gif_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_PSD
-   if (stbi__psd_test(s))  return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
-   #else
-   STBI_NOTUSED(bpc);
-   #endif
-   #ifndef STBI_NO_PIC
-   if (stbi__pic_test(s))  return stbi__pic_load(s,x,y,comp,req_comp, ri);
-   #endif
-
-   // then the formats that can end up attempting to load with just 1 or 2
-   // bytes matching expectations; these are prone to false positives, so
-   // try them later
-   #ifndef STBI_NO_JPEG
-   if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_PNM
-   if (stbi__pnm_test(s))  return stbi__pnm_load(s,x,y,comp,req_comp, ri);
-   #endif
-
-   #ifndef STBI_NO_HDR
-   if (stbi__hdr_test(s)) {
-      float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri);
-      return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
-   }
-   #endif
-
-   #ifndef STBI_NO_TGA
-   // test tga last because it's a crappy test!
-   if (stbi__tga_test(s))
-      return stbi__tga_load(s,x,y,comp,req_comp, ri);
-   #endif
-
-   return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
-}
-
-static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels)
-{
-   int i;
-   int img_len = w * h * channels;
-   stbi_uc *reduced;
-
-   reduced = (stbi_uc *) stbi__malloc(img_len);
-   if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory");
-
-   for (i = 0; i < img_len; ++i)
-      reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling
-
-   STBI_FREE(orig);
-   return reduced;
-}
-
-static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels)
-{
-   int i;
-   int img_len = w * h * channels;
-   stbi__uint16 *enlarged;
-
-   enlarged = (stbi__uint16 *) stbi__malloc(img_len*2);
-   if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
-
-   for (i = 0; i < img_len; ++i)
-      enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
-
-   STBI_FREE(orig);
-   return enlarged;
-}
-
-static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
-{
-   int row;
-   size_t bytes_per_row = (size_t)w * bytes_per_pixel;
-   stbi_uc temp[2048];
-   stbi_uc *bytes = (stbi_uc *)image;
-
-   for (row = 0; row < (h>>1); row++) {
-      stbi_uc *row0 = bytes + row*bytes_per_row;
-      stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row;
-      // swap row0 with row1
-      size_t bytes_left = bytes_per_row;
-      while (bytes_left) {
-         size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
-         memcpy(temp, row0, bytes_copy);
-         memcpy(row0, row1, bytes_copy);
-         memcpy(row1, temp, bytes_copy);
-         row0 += bytes_copy;
-         row1 += bytes_copy;
-         bytes_left -= bytes_copy;
-      }
-   }
-}
-
-#ifndef STBI_NO_GIF
-static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
-{
-   int slice;
-   int slice_size = w * h * bytes_per_pixel;
-
-   stbi_uc *bytes = (stbi_uc *)image;
-   for (slice = 0; slice < z; ++slice) {
-      stbi__vertical_flip(bytes, w, h, bytes_per_pixel);
-      bytes += slice_size;
-   }
-}
-#endif
-
-static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__result_info ri;
-   void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8);
-
-   if (result == NULL)
-      return NULL;
-
-   // it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
-   STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
-
-   if (ri.bits_per_channel != 8) {
-      result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
-      ri.bits_per_channel = 8;
-   }
-
-   // @TODO: move stbi__convert_format to here
-
-   if (stbi__vertically_flip_on_load) {
-      int channels = req_comp ? req_comp : *comp;
-      stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
-   }
-
-   return (unsigned char *) result;
-}
-
-static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__result_info ri;
-   void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16);
-
-   if (result == NULL)
-      return NULL;
-
-   // it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
-   STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
-
-   if (ri.bits_per_channel != 16) {
-      result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
-      ri.bits_per_channel = 16;
-   }
-
-   // @TODO: move stbi__convert_format16 to here
-   // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision
-
-   if (stbi__vertically_flip_on_load) {
-      int channels = req_comp ? req_comp : *comp;
-      stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16));
-   }
-
-   return (stbi__uint16 *) result;
-}
-
-#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR)
-static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
-{
-   if (stbi__vertically_flip_on_load && result != NULL) {
-      int channels = req_comp ? req_comp : *comp;
-      stbi__vertical_flip(result, *x, *y, channels * sizeof(float));
-   }
-}
-#endif
-
-#ifndef STBI_NO_STDIO
-
-#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
-STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
-STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
-#endif
-
-#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
-STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
-{
-	return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
-}
-#endif
-
-static FILE *stbi__fopen(char const *filename, char const *mode)
-{
-   FILE *f;
-#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
-   wchar_t wMode[64];
-   wchar_t wFilename[1024];
-	if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
-      return 0;
-
-	if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
-      return 0;
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-	if (0 != _wfopen_s(&f, wFilename, wMode))
-		f = 0;
-#else
-   f = _wfopen(wFilename, wMode);
-#endif
-
-#elif defined(_MSC_VER) && _MSC_VER >= 1400
-   if (0 != fopen_s(&f, filename, mode))
-      f=0;
-#else
-   f = fopen(filename, mode);
-#endif
-   return f;
-}
-
-
-STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
-{
-   FILE *f = stbi__fopen(filename, "rb");
-   unsigned char *result;
-   if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
-   result = stbi_load_from_file(f,x,y,comp,req_comp);
-   fclose(f);
-   return result;
-}
-
-STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
-{
-   unsigned char *result;
-   stbi__context s;
-   stbi__start_file(&s,f);
-   result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
-   if (result) {
-      // need to 'unget' all the characters in the IO buffer
-      fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
-   }
-   return result;
-}
-
-STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__uint16 *result;
-   stbi__context s;
-   stbi__start_file(&s,f);
-   result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
-   if (result) {
-      // need to 'unget' all the characters in the IO buffer
-      fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
-   }
-   return result;
-}
-
-STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp)
-{
-   FILE *f = stbi__fopen(filename, "rb");
-   stbi__uint16 *result;
-   if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file");
-   result = stbi_load_from_file_16(f,x,y,comp,req_comp);
-   fclose(f);
-   return result;
-}
-
-
-#endif //!STBI_NO_STDIO
-
-STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
-}
-
-STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
-   return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
-}
-
-STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
-}
-
-STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
-   return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
-}
-
-#ifndef STBI_NO_GIF
-STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
-{
-   unsigned char *result;
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-
-   result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
-   if (stbi__vertically_flip_on_load) {
-      stbi__vertical_flip_slices( result, *x, *y, *z, *comp );
-   }
-
-   return result;
-}
-#endif
-
-#ifndef STBI_NO_LINEAR
-static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
-{
-   unsigned char *data;
-   #ifndef STBI_NO_HDR
-   if (stbi__hdr_test(s)) {
-      stbi__result_info ri;
-      float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri);
-      if (hdr_data)
-         stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
-      return hdr_data;
-   }
-   #endif
-   data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp);
-   if (data)
-      return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
-   return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
-}
-
-STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__loadf_main(&s,x,y,comp,req_comp);
-}
-
-STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
-   return stbi__loadf_main(&s,x,y,comp,req_comp);
-}
-
-#ifndef STBI_NO_STDIO
-STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp)
-{
-   float *result;
-   FILE *f = stbi__fopen(filename, "rb");
-   if (!f) return stbi__errpf("can't fopen", "Unable to open file");
-   result = stbi_loadf_from_file(f,x,y,comp,req_comp);
-   fclose(f);
-   return result;
-}
-
-STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_file(&s,f);
-   return stbi__loadf_main(&s,x,y,comp,req_comp);
-}
-#endif // !STBI_NO_STDIO
-
-#endif // !STBI_NO_LINEAR
-
-// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is
-// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always
-// reports false!
-
-STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
-{
-   #ifndef STBI_NO_HDR
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__hdr_test(&s);
-   #else
-   STBI_NOTUSED(buffer);
-   STBI_NOTUSED(len);
-   return 0;
-   #endif
-}
-
-#ifndef STBI_NO_STDIO
-STBIDEF int      stbi_is_hdr          (char const *filename)
-{
-   FILE *f = stbi__fopen(filename, "rb");
-   int result=0;
-   if (f) {
-      result = stbi_is_hdr_from_file(f);
-      fclose(f);
-   }
-   return result;
-}
-
-STBIDEF int stbi_is_hdr_from_file(FILE *f)
-{
-   #ifndef STBI_NO_HDR
-   long pos = ftell(f);
-   int res;
-   stbi__context s;
-   stbi__start_file(&s,f);
-   res = stbi__hdr_test(&s);
-   fseek(f, pos, SEEK_SET);
-   return res;
-   #else
-   STBI_NOTUSED(f);
-   return 0;
-   #endif
-}
-#endif // !STBI_NO_STDIO
-
-STBIDEF int      stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user)
-{
-   #ifndef STBI_NO_HDR
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
-   return stbi__hdr_test(&s);
-   #else
-   STBI_NOTUSED(clbk);
-   STBI_NOTUSED(user);
-   return 0;
-   #endif
-}
-
-#ifndef STBI_NO_LINEAR
-static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f;
-
-STBIDEF void   stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
-STBIDEF void   stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
-#endif
-
-static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
-
-STBIDEF void   stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
-STBIDEF void   stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Common code used by all image loaders
-//
-
-enum
-{
-   STBI__SCAN_load=0,
-   STBI__SCAN_type,
-   STBI__SCAN_header
-};
-
-static void stbi__refill_buffer(stbi__context *s)
-{
-   int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
-   s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original);
-   if (n == 0) {
-      // at end of file, treat same as if from memory, but need to handle case
-      // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
-      s->read_from_callbacks = 0;
-      s->img_buffer = s->buffer_start;
-      s->img_buffer_end = s->buffer_start+1;
-      *s->img_buffer = 0;
-   } else {
-      s->img_buffer = s->buffer_start;
-      s->img_buffer_end = s->buffer_start + n;
-   }
-}
-
-stbi_inline static stbi_uc stbi__get8(stbi__context *s)
-{
-   if (s->img_buffer < s->img_buffer_end)
-      return *s->img_buffer++;
-   if (s->read_from_callbacks) {
-      stbi__refill_buffer(s);
-      return *s->img_buffer++;
-   }
-   return 0;
-}
-
-#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM)
-// nothing
-#else
-stbi_inline static int stbi__at_eof(stbi__context *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;
-}
-#endif
-
-#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC)
-// nothing
-#else
-static void stbi__skip(stbi__context *s, int n)
-{
-   if (n == 0) return;  // already there!
-   if (n < 0) {
-      s->img_buffer = s->img_buffer_end;
-      return;
-   }
-   if (s->io.read) {
-      int blen = (int) (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;
-}
-#endif
-
-#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM)
-// nothing
-#else
-static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
-{
-   if (s->io.read) {
-      int blen = (int) (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;
-}
-#endif
-
-#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC)
-// nothing
-#else
-static int stbi__get16be(stbi__context *s)
-{
-   int z = stbi__get8(s);
-   return (z << 8) + stbi__get8(s);
-}
-#endif
-
-#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC)
-// nothing
-#else
-static stbi__uint32 stbi__get32be(stbi__context *s)
-{
-   stbi__uint32 z = stbi__get16be(s);
-   return (z << 16) + stbi__get16be(s);
-}
-#endif
-
-#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
-// nothing
-#else
-static int stbi__get16le(stbi__context *s)
-{
-   int z = stbi__get8(s);
-   return z + (stbi__get8(s) << 8);
-}
-#endif
-
-#ifndef STBI_NO_BMP
-static stbi__uint32 stbi__get32le(stbi__context *s)
-{
-   stbi__uint32 z = stbi__get16le(s);
-   z += (stbi__uint32)stbi__get16le(s) << 16;
-   return z;
-}
-#endif
-
-#define STBI__BYTECAST(x)  ((stbi_uc) ((x) & 255))  // truncate int to byte without warnings
-
-#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM)
-// nothing
-#else
-//////////////////////////////////////////////////////////////////////////////
-//
-//  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 stbi_uc stbi__compute_y(int r, int g, int b)
-{
-   return (stbi_uc) (((r*77) + (g*150) +  (29*b)) >> 8);
-}
-#endif
-
-#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM)
-// nothing
-#else
-static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y)
-{
-   int i,j;
-   unsigned char *good;
-
-   if (req_comp == img_n) return data;
-   STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
-
-   good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0);
-   if (good == NULL) {
-      STBI_FREE(data);
-      return stbi__errpuc("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 STBI__COMBO(a,b)  ((a)*8+(b))
-      #define STBI__CASE(a,b)   case STBI__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 (STBI__COMBO(img_n, req_comp)) {
-         STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255;                                     } break;
-         STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0];                                  } break;
-         STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255;                     } break;
-         STBI__CASE(2,1) { dest[0]=src[0];                                                  } break;
-         STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0];                                  } break;
-         STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1];                  } break;
-         STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255;        } break;
-         STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]);                   } break;
-         STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255;    } break;
-         STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]);                   } break;
-         STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
-         STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];                    } break;
-         default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion");
-      }
-      #undef STBI__CASE
-   }
-
-   STBI_FREE(data);
-   return good;
-}
-#endif
-
-#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD)
-// nothing
-#else
-static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
-{
-   return (stbi__uint16) (((r*77) + (g*150) +  (29*b)) >> 8);
-}
-#endif
-
-#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD)
-// nothing
-#else
-static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
-{
-   int i,j;
-   stbi__uint16 *good;
-
-   if (req_comp == img_n) return data;
-   STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
-
-   good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2);
-   if (good == NULL) {
-      STBI_FREE(data);
-      return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
-   }
-
-   for (j=0; j < (int) y; ++j) {
-      stbi__uint16 *src  = data + j * x * img_n   ;
-      stbi__uint16 *dest = good + j * x * req_comp;
-
-      #define STBI__COMBO(a,b)  ((a)*8+(b))
-      #define STBI__CASE(a,b)   case STBI__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 (STBI__COMBO(img_n, req_comp)) {
-         STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff;                                     } break;
-         STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0];                                     } break;
-         STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff;                     } break;
-         STBI__CASE(2,1) { dest[0]=src[0];                                                     } break;
-         STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0];                                     } break;
-         STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1];                     } break;
-         STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff;        } break;
-         STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]);                   } break;
-         STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break;
-         STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]);                   } break;
-         STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
-         STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];                       } break;
-         default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion");
-      }
-      #undef STBI__CASE
-   }
-
-   STBI_FREE(data);
-   return good;
-}
-#endif
-
-#ifndef STBI_NO_LINEAR
-static float   *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
-{
-   int i,k,n;
-   float *output;
-   if (!data) return NULL;
-   output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0);
-   if (output == NULL) { STBI_FREE(data); return stbi__errpf("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, stbi__l2h_gamma) * stbi__l2h_scale);
-      }
-   }
-   if (n < comp) {
-      for (i=0; i < x*y; ++i) {
-         output[i*comp + n] = data[i*comp + n]/255.0f;
-      }
-   }
-   STBI_FREE(data);
-   return output;
-}
-#endif
-
-#ifndef STBI_NO_HDR
-#define stbi__float2int(x)   ((int) (x))
-static stbi_uc *stbi__hdr_to_ldr(float   *data, int x, int y, int comp)
-{
-   int i,k,n;
-   stbi_uc *output;
-   if (!data) return NULL;
-   output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0);
-   if (output == NULL) { STBI_FREE(data); return stbi__errpuc("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]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f;
-         if (z < 0) z = 0;
-         if (z > 255) z = 255;
-         output[i*comp + k] = (stbi_uc) stbi__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] = (stbi_uc) stbi__float2int(z);
-      }
-   }
-   STBI_FREE(data);
-   return output;
-}
-#endif
-
-//////////////////////////////////////////////////////////////////////////////
-//
-//  "baseline" JPEG/JFIF decoder
-//
-//    simple implementation
-//      - 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
-//      - some SIMD kernels for common paths on targets with SSE2/NEON
-//      - uses a lot of intermediate memory, could cache poorly
-
-#ifndef STBI_NO_JPEG
-
-// huffman decoding acceleration
-#define FAST_BITS   9  // larger handles more cases; smaller stomps less cache
-
-typedef struct
-{
-   stbi_uc  fast[1 << FAST_BITS];
-   // weirdly, repacking this into AoS is a 10% speed loss, instead of a win
-   stbi__uint16 code[256];
-   stbi_uc  values[256];
-   stbi_uc  size[257];
-   unsigned int maxcode[18];
-   int    delta[17];   // old 'firstsymbol' - old 'firstcode'
-} stbi__huffman;
-
-typedef struct
-{
-   stbi__context *s;
-   stbi__huffman huff_dc[4];
-   stbi__huffman huff_ac[4];
-   stbi__uint16 dequant[4][64];
-   stbi__int16 fast_ac[4][1 << FAST_BITS];
-
-// 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;
-      stbi_uc *data;
-      void *raw_data, *raw_coeff;
-      stbi_uc *linebuf;
-      short   *coeff;   // progressive only
-      int      coeff_w, coeff_h; // number of 8x8 coefficient blocks
-   } img_comp[4];
-
-   stbi__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            progressive;
-   int            spec_start;
-   int            spec_end;
-   int            succ_high;
-   int            succ_low;
-   int            eob_run;
-   int            jfif;
-   int            app14_color_transform; // Adobe APP14 tag
-   int            rgb;
-
-   int scan_n, order[4];
-   int restart_interval, todo;
-
-// kernels
-   void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]);
-   void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step);
-   stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs);
-} stbi__jpeg;
-
-static int stbi__build_huffman(stbi__huffman *h, int *count)
-{
-   int i,j,k=0;
-   unsigned int 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++] = (stbi_uc) (i+1);
-         if(k >= 257) return stbi__err("bad size list","Corrupt JPEG");
-      }
-   }
-   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++] = (stbi__uint16) (code++);
-         if (code-1 >= (1u << j)) return stbi__err("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] = (stbi_uc) i;
-         }
-      }
-   }
-   return 1;
-}
-
-// build a table that decodes both magnitude and value of small ACs in
-// one go.
-static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
-{
-   int i;
-   for (i=0; i < (1 << FAST_BITS); ++i) {
-      stbi_uc fast = h->fast[i];
-      fast_ac[i] = 0;
-      if (fast < 255) {
-         int rs = h->values[fast];
-         int run = (rs >> 4) & 15;
-         int magbits = rs & 15;
-         int len = h->size[fast];
-
-         if (magbits && len + magbits <= FAST_BITS) {
-            // magnitude code followed by receive_extend code
-            int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
-            int m = 1 << (magbits - 1);
-            if (k < m) k += (~0U << magbits) + 1;
-            // if the result is small enough, we can fit it in fast_ac table
-            if (k >= -128 && k <= 127)
-               fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits));
-         }
-      }
-   }
-}
-
-static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
-{
-   do {
-      unsigned int b = j->nomore ? 0 : stbi__get8(j->s);
-      if (b == 0xff) {
-         int c = stbi__get8(j->s);
-         while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes
-         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 const stbi__uint32 stbi__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 stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
-{
-   unsigned int temp;
-   int c,k;
-
-   if (j->code_bits < 16) stbi__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)) & stbi__bmask[k]) + h->delta[k];
-   if(c < 0 || c >= 256) // symbol id out of bounds!
-       return -1;
-   STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__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];
-}
-
-// bias[n] = (-1<<n) + 1
-static const int stbi__jbias[16] = {0,-1,-3,-7,-15,-31,-63,-127,-255,-511,-1023,-2047,-4095,-8191,-16383,-32767};
-
-// combined JPEG 'receive' and JPEG 'extend', since baseline
-// always extends everything it receives.
-stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
-{
-   unsigned int k;
-   int sgn;
-   if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
-   if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
-
-   sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative)
-   k = stbi_lrot(j->code_buffer, n);
-   j->code_buffer = k & ~stbi__bmask[n];
-   k &= stbi__bmask[n];
-   j->code_bits -= n;
-   return k + (stbi__jbias[n] & (sgn - 1));
-}
-
-// get some unsigned bits
-stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n)
-{
-   unsigned int k;
-   if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
-   if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
-   k = stbi_lrot(j->code_buffer, n);
-   j->code_buffer = k & ~stbi__bmask[n];
-   k &= stbi__bmask[n];
-   j->code_bits -= n;
-   return k;
-}
-
-stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
-{
-   unsigned int k;
-   if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
-   if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing
-   k = j->code_buffer;
-   j->code_buffer <<= 1;
-   --j->code_bits;
-   return k & 0x80000000;
-}
-
-// 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 const stbi_uc stbi__jpeg_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 stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant)
-{
-   int diff,dc,k;
-   int t;
-
-   if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-   t = stbi__jpeg_huff_decode(j, hdc);
-   if (t < 0 || t > 15) return stbi__err("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 ? stbi__extend_receive(j, t) : 0;
-   if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG");
-   dc = j->img_comp[b].dc_pred + diff;
-   j->img_comp[b].dc_pred = dc;
-   if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
-   data[0] = (short) (dc * dequant[0]);
-
-   // decode AC components, see JPEG spec
-   k = 1;
-   do {
-      unsigned int zig;
-      int c,r,s;
-      if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-      c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
-      r = fac[c];
-      if (r) { // fast-AC path
-         k += (r >> 4) & 15; // run
-         s = r & 15; // combined length
-         if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
-         j->code_buffer <<= s;
-         j->code_bits -= s;
-         // decode into unzigzag'd location
-         zig = stbi__jpeg_dezigzag[k++];
-         data[zig] = (short) ((r >> 8) * dequant[zig]);
-      } else {
-         int rs = stbi__jpeg_huff_decode(j, hac);
-         if (rs < 0) return stbi__err("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
-            zig = stbi__jpeg_dezigzag[k++];
-            data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]);
-         }
-      }
-   } while (k < 64);
-   return 1;
-}
-
-static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b)
-{
-   int diff,dc;
-   int t;
-   if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
-
-   if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-
-   if (j->succ_high == 0) {
-      // first scan for DC coefficient, must be first
-      memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
-      t = stbi__jpeg_huff_decode(j, hdc);
-      if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
-      diff = t ? stbi__extend_receive(j, t) : 0;
-
-      if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG");
-      dc = j->img_comp[b].dc_pred + diff;
-      j->img_comp[b].dc_pred = dc;
-      if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
-      data[0] = (short) (dc * (1 << j->succ_low));
-   } else {
-      // refinement scan for DC coefficient
-      if (stbi__jpeg_get_bit(j))
-         data[0] += (short) (1 << j->succ_low);
-   }
-   return 1;
-}
-
-// @OPTIMIZE: store non-zigzagged during the decode passes,
-// and only de-zigzag when dequantizing
-static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac)
-{
-   int k;
-   if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
-
-   if (j->succ_high == 0) {
-      int shift = j->succ_low;
-
-      if (j->eob_run) {
-         --j->eob_run;
-         return 1;
-      }
-
-      k = j->spec_start;
-      do {
-         unsigned int zig;
-         int c,r,s;
-         if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-         c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
-         r = fac[c];
-         if (r) { // fast-AC path
-            k += (r >> 4) & 15; // run
-            s = r & 15; // combined length
-            if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
-            j->code_buffer <<= s;
-            j->code_bits -= s;
-            zig = stbi__jpeg_dezigzag[k++];
-            data[zig] = (short) ((r >> 8) * (1 << shift));
-         } else {
-            int rs = stbi__jpeg_huff_decode(j, hac);
-            if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
-            s = rs & 15;
-            r = rs >> 4;
-            if (s == 0) {
-               if (r < 15) {
-                  j->eob_run = (1 << r);
-                  if (r)
-                     j->eob_run += stbi__jpeg_get_bits(j, r);
-                  --j->eob_run;
-                  break;
-               }
-               k += 16;
-            } else {
-               k += r;
-               zig = stbi__jpeg_dezigzag[k++];
-               data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift));
-            }
-         }
-      } while (k <= j->spec_end);
-   } else {
-      // refinement scan for these AC coefficients
-
-      short bit = (short) (1 << j->succ_low);
-
-      if (j->eob_run) {
-         --j->eob_run;
-         for (k = j->spec_start; k <= j->spec_end; ++k) {
-            short *p = &data[stbi__jpeg_dezigzag[k]];
-            if (*p != 0)
-               if (stbi__jpeg_get_bit(j))
-                  if ((*p & bit)==0) {
-                     if (*p > 0)
-                        *p += bit;
-                     else
-                        *p -= bit;
-                  }
-         }
-      } else {
-         k = j->spec_start;
-         do {
-            int r,s;
-            int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh
-            if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
-            s = rs & 15;
-            r = rs >> 4;
-            if (s == 0) {
-               if (r < 15) {
-                  j->eob_run = (1 << r) - 1;
-                  if (r)
-                     j->eob_run += stbi__jpeg_get_bits(j, r);
-                  r = 64; // force end of block
-               } else {
-                  // r=15 s=0 should write 16 0s, so we just do
-                  // a run of 15 0s and then write s (which is 0),
-                  // so we don't have to do anything special here
-               }
-            } else {
-               if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG");
-               // sign bit
-               if (stbi__jpeg_get_bit(j))
-                  s = bit;
-               else
-                  s = -bit;
-            }
-
-            // advance by r
-            while (k <= j->spec_end) {
-               short *p = &data[stbi__jpeg_dezigzag[k++]];
-               if (*p != 0) {
-                  if (stbi__jpeg_get_bit(j))
-                     if ((*p & bit)==0) {
-                        if (*p > 0)
-                           *p += bit;
-                        else
-                           *p -= bit;
-                     }
-               } else {
-                  if (r == 0) {
-                     *p = (short) s;
-                     break;
-                  }
-                  --r;
-               }
-            }
-         } while (k <= j->spec_end);
-      }
-   }
-   return 1;
-}
-
-// take a -128..127 value and stbi__clamp it and convert to 0..255
-stbi_inline static stbi_uc stbi__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 (stbi_uc) x;
-}
-
-#define stbi__f2f(x)  ((int) (((x) * 4096 + 0.5)))
-#define stbi__fsh(x)  ((x) * 4096)
-
-// derived from jidctint -- DCT_ISLOW
-#define STBI__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) * stbi__f2f(0.5411961f);       \
-   t2 = p1 + p3*stbi__f2f(-1.847759065f);      \
-   t3 = p1 + p2*stbi__f2f( 0.765366865f);      \
-   p2 = s0;                                    \
-   p3 = s4;                                    \
-   t0 = stbi__fsh(p2+p3);                      \
-   t1 = stbi__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)*stbi__f2f( 1.175875602f);      \
-   t0 = t0*stbi__f2f( 0.298631336f);           \
-   t1 = t1*stbi__f2f( 2.053119869f);           \
-   t2 = t2*stbi__f2f( 3.072711026f);           \
-   t3 = t3*stbi__f2f( 1.501321110f);           \
-   p1 = p5 + p1*stbi__f2f(-0.899976223f);      \
-   p2 = p5 + p2*stbi__f2f(-2.562915447f);      \
-   p3 = p3*stbi__f2f(-1.961570560f);           \
-   p4 = p4*stbi__f2f(-0.390180644f);           \
-   t3 += p1+p4;                                \
-   t2 += p2+p3;                                \
-   t1 += p2+p4;                                \
-   t0 += p1+p3;
-
-static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64])
-{
-   int i,val[64],*v=val;
-   stbi_uc *o;
-   short *d = data;
-
-   // columns
-   for (i=0; i < 8; ++i,++d, ++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]*4;
-         v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm;
-      } else {
-         STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[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
-      STBI__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] = stbi__clamp((x0+t3) >> 17);
-      o[7] = stbi__clamp((x0-t3) >> 17);
-      o[1] = stbi__clamp((x1+t2) >> 17);
-      o[6] = stbi__clamp((x1-t2) >> 17);
-      o[2] = stbi__clamp((x2+t1) >> 17);
-      o[5] = stbi__clamp((x2-t1) >> 17);
-      o[3] = stbi__clamp((x3+t0) >> 17);
-      o[4] = stbi__clamp((x3-t0) >> 17);
-   }
-}
-
-#ifdef STBI_SSE2
-// sse2 integer IDCT. not the fastest possible implementation but it
-// produces bit-identical results to the generic C version so it's
-// fully "transparent".
-static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
-{
-   // This is constructed to match our regular (generic) integer IDCT exactly.
-   __m128i row0, row1, row2, row3, row4, row5, row6, row7;
-   __m128i tmp;
-
-   // dot product constant: even elems=x, odd elems=y
-   #define dct_const(x,y)  _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y))
-
-   // out(0) = c0[even]*x + c0[odd]*y   (c0, x, y 16-bit, out 32-bit)
-   // out(1) = c1[even]*x + c1[odd]*y
-   #define dct_rot(out0,out1, x,y,c0,c1) \
-      __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \
-      __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \
-      __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \
-      __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \
-      __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \
-      __m128i out1##_h = _mm_madd_epi16(c0##hi, c1)
-
-   // out = in << 12  (in 16-bit, out 32-bit)
-   #define dct_widen(out, in) \
-      __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \
-      __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4)
-
-   // wide add
-   #define dct_wadd(out, a, b) \
-      __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \
-      __m128i out##_h = _mm_add_epi32(a##_h, b##_h)
-
-   // wide sub
-   #define dct_wsub(out, a, b) \
-      __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \
-      __m128i out##_h = _mm_sub_epi32(a##_h, b##_h)
-
-   // butterfly a/b, add bias, then shift by "s" and pack
-   #define dct_bfly32o(out0, out1, a,b,bias,s) \
-      { \
-         __m128i abiased_l = _mm_add_epi32(a##_l, bias); \
-         __m128i abiased_h = _mm_add_epi32(a##_h, bias); \
-         dct_wadd(sum, abiased, b); \
-         dct_wsub(dif, abiased, b); \
-         out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \
-         out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \
-      }
-
-   // 8-bit interleave step (for transposes)
-   #define dct_interleave8(a, b) \
-      tmp = a; \
-      a = _mm_unpacklo_epi8(a, b); \
-      b = _mm_unpackhi_epi8(tmp, b)
-
-   // 16-bit interleave step (for transposes)
-   #define dct_interleave16(a, b) \
-      tmp = a; \
-      a = _mm_unpacklo_epi16(a, b); \
-      b = _mm_unpackhi_epi16(tmp, b)
-
-   #define dct_pass(bias,shift) \
-      { \
-         /* even part */ \
-         dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \
-         __m128i sum04 = _mm_add_epi16(row0, row4); \
-         __m128i dif04 = _mm_sub_epi16(row0, row4); \
-         dct_widen(t0e, sum04); \
-         dct_widen(t1e, dif04); \
-         dct_wadd(x0, t0e, t3e); \
-         dct_wsub(x3, t0e, t3e); \
-         dct_wadd(x1, t1e, t2e); \
-         dct_wsub(x2, t1e, t2e); \
-         /* odd part */ \
-         dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \
-         dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \
-         __m128i sum17 = _mm_add_epi16(row1, row7); \
-         __m128i sum35 = _mm_add_epi16(row3, row5); \
-         dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \
-         dct_wadd(x4, y0o, y4o); \
-         dct_wadd(x5, y1o, y5o); \
-         dct_wadd(x6, y2o, y5o); \
-         dct_wadd(x7, y3o, y4o); \
-         dct_bfly32o(row0,row7, x0,x7,bias,shift); \
-         dct_bfly32o(row1,row6, x1,x6,bias,shift); \
-         dct_bfly32o(row2,row5, x2,x5,bias,shift); \
-         dct_bfly32o(row3,row4, x3,x4,bias,shift); \
-      }
-
-   __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f));
-   __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f));
-   __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f));
-   __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f));
-   __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f));
-   __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f));
-   __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f));
-   __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f));
-
-   // rounding biases in column/row passes, see stbi__idct_block for explanation.
-   __m128i bias_0 = _mm_set1_epi32(512);
-   __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17));
-
-   // load
-   row0 = _mm_load_si128((const __m128i *) (data + 0*8));
-   row1 = _mm_load_si128((const __m128i *) (data + 1*8));
-   row2 = _mm_load_si128((const __m128i *) (data + 2*8));
-   row3 = _mm_load_si128((const __m128i *) (data + 3*8));
-   row4 = _mm_load_si128((const __m128i *) (data + 4*8));
-   row5 = _mm_load_si128((const __m128i *) (data + 5*8));
-   row6 = _mm_load_si128((const __m128i *) (data + 6*8));
-   row7 = _mm_load_si128((const __m128i *) (data + 7*8));
-
-   // column pass
-   dct_pass(bias_0, 10);
-
-   {
-      // 16bit 8x8 transpose pass 1
-      dct_interleave16(row0, row4);
-      dct_interleave16(row1, row5);
-      dct_interleave16(row2, row6);
-      dct_interleave16(row3, row7);
-
-      // transpose pass 2
-      dct_interleave16(row0, row2);
-      dct_interleave16(row1, row3);
-      dct_interleave16(row4, row6);
-      dct_interleave16(row5, row7);
-
-      // transpose pass 3
-      dct_interleave16(row0, row1);
-      dct_interleave16(row2, row3);
-      dct_interleave16(row4, row5);
-      dct_interleave16(row6, row7);
-   }
-
-   // row pass
-   dct_pass(bias_1, 17);
-
-   {
-      // pack
-      __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7
-      __m128i p1 = _mm_packus_epi16(row2, row3);
-      __m128i p2 = _mm_packus_epi16(row4, row5);
-      __m128i p3 = _mm_packus_epi16(row6, row7);
-
-      // 8bit 8x8 transpose pass 1
-      dct_interleave8(p0, p2); // a0e0a1e1...
-      dct_interleave8(p1, p3); // c0g0c1g1...
-
-      // transpose pass 2
-      dct_interleave8(p0, p1); // a0c0e0g0...
-      dct_interleave8(p2, p3); // b0d0f0h0...
-
-      // transpose pass 3
-      dct_interleave8(p0, p2); // a0b0c0d0...
-      dct_interleave8(p1, p3); // a4b4c4d4...
-
-      // store
-      _mm_storel_epi64((__m128i *) out, p0); out += out_stride;
-      _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride;
-      _mm_storel_epi64((__m128i *) out, p2); out += out_stride;
-      _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride;
-      _mm_storel_epi64((__m128i *) out, p1); out += out_stride;
-      _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride;
-      _mm_storel_epi64((__m128i *) out, p3); out += out_stride;
-      _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e));
-   }
-
-#undef dct_const
-#undef dct_rot
-#undef dct_widen
-#undef dct_wadd
-#undef dct_wsub
-#undef dct_bfly32o
-#undef dct_interleave8
-#undef dct_interleave16
-#undef dct_pass
-}
-
-#endif // STBI_SSE2
-
-#ifdef STBI_NEON
-
-// NEON integer IDCT. should produce bit-identical
-// results to the generic C version.
-static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
-{
-   int16x8_t row0, row1, row2, row3, row4, row5, row6, row7;
-
-   int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f));
-   int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f));
-   int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f));
-   int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f));
-   int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f));
-   int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f));
-   int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f));
-   int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f));
-   int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f));
-   int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f));
-   int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f));
-   int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f));
-
-#define dct_long_mul(out, inq, coeff) \
-   int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \
-   int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff)
-
-#define dct_long_mac(out, acc, inq, coeff) \
-   int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \
-   int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff)
-
-#define dct_widen(out, inq) \
-   int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \
-   int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12)
-
-// wide add
-#define dct_wadd(out, a, b) \
-   int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \
-   int32x4_t out##_h = vaddq_s32(a##_h, b##_h)
-
-// wide sub
-#define dct_wsub(out, a, b) \
-   int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \
-   int32x4_t out##_h = vsubq_s32(a##_h, b##_h)
-
-// butterfly a/b, then shift using "shiftop" by "s" and pack
-#define dct_bfly32o(out0,out1, a,b,shiftop,s) \
-   { \
-      dct_wadd(sum, a, b); \
-      dct_wsub(dif, a, b); \
-      out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \
-      out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \
-   }
-
-#define dct_pass(shiftop, shift) \
-   { \
-      /* even part */ \
-      int16x8_t sum26 = vaddq_s16(row2, row6); \
-      dct_long_mul(p1e, sum26, rot0_0); \
-      dct_long_mac(t2e, p1e, row6, rot0_1); \
-      dct_long_mac(t3e, p1e, row2, rot0_2); \
-      int16x8_t sum04 = vaddq_s16(row0, row4); \
-      int16x8_t dif04 = vsubq_s16(row0, row4); \
-      dct_widen(t0e, sum04); \
-      dct_widen(t1e, dif04); \
-      dct_wadd(x0, t0e, t3e); \
-      dct_wsub(x3, t0e, t3e); \
-      dct_wadd(x1, t1e, t2e); \
-      dct_wsub(x2, t1e, t2e); \
-      /* odd part */ \
-      int16x8_t sum15 = vaddq_s16(row1, row5); \
-      int16x8_t sum17 = vaddq_s16(row1, row7); \
-      int16x8_t sum35 = vaddq_s16(row3, row5); \
-      int16x8_t sum37 = vaddq_s16(row3, row7); \
-      int16x8_t sumodd = vaddq_s16(sum17, sum35); \
-      dct_long_mul(p5o, sumodd, rot1_0); \
-      dct_long_mac(p1o, p5o, sum17, rot1_1); \
-      dct_long_mac(p2o, p5o, sum35, rot1_2); \
-      dct_long_mul(p3o, sum37, rot2_0); \
-      dct_long_mul(p4o, sum15, rot2_1); \
-      dct_wadd(sump13o, p1o, p3o); \
-      dct_wadd(sump24o, p2o, p4o); \
-      dct_wadd(sump23o, p2o, p3o); \
-      dct_wadd(sump14o, p1o, p4o); \
-      dct_long_mac(x4, sump13o, row7, rot3_0); \
-      dct_long_mac(x5, sump24o, row5, rot3_1); \
-      dct_long_mac(x6, sump23o, row3, rot3_2); \
-      dct_long_mac(x7, sump14o, row1, rot3_3); \
-      dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \
-      dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \
-      dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \
-      dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \
-   }
-
-   // load
-   row0 = vld1q_s16(data + 0*8);
-   row1 = vld1q_s16(data + 1*8);
-   row2 = vld1q_s16(data + 2*8);
-   row3 = vld1q_s16(data + 3*8);
-   row4 = vld1q_s16(data + 4*8);
-   row5 = vld1q_s16(data + 5*8);
-   row6 = vld1q_s16(data + 6*8);
-   row7 = vld1q_s16(data + 7*8);
-
-   // add DC bias
-   row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0));
-
-   // column pass
-   dct_pass(vrshrn_n_s32, 10);
-
-   // 16bit 8x8 transpose
-   {
-// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively.
-// whether compilers actually get this is another story, sadly.
-#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; }
-#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); }
-#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); }
-
-      // pass 1
-      dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6
-      dct_trn16(row2, row3);
-      dct_trn16(row4, row5);
-      dct_trn16(row6, row7);
-
-      // pass 2
-      dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4
-      dct_trn32(row1, row3);
-      dct_trn32(row4, row6);
-      dct_trn32(row5, row7);
-
-      // pass 3
-      dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0
-      dct_trn64(row1, row5);
-      dct_trn64(row2, row6);
-      dct_trn64(row3, row7);
-
-#undef dct_trn16
-#undef dct_trn32
-#undef dct_trn64
-   }
-
-   // row pass
-   // vrshrn_n_s32 only supports shifts up to 16, we need
-   // 17. so do a non-rounding shift of 16 first then follow
-   // up with a rounding shift by 1.
-   dct_pass(vshrn_n_s32, 16);
-
-   {
-      // pack and round
-      uint8x8_t p0 = vqrshrun_n_s16(row0, 1);
-      uint8x8_t p1 = vqrshrun_n_s16(row1, 1);
-      uint8x8_t p2 = vqrshrun_n_s16(row2, 1);
-      uint8x8_t p3 = vqrshrun_n_s16(row3, 1);
-      uint8x8_t p4 = vqrshrun_n_s16(row4, 1);
-      uint8x8_t p5 = vqrshrun_n_s16(row5, 1);
-      uint8x8_t p6 = vqrshrun_n_s16(row6, 1);
-      uint8x8_t p7 = vqrshrun_n_s16(row7, 1);
-
-      // again, these can translate into one instruction, but often don't.
-#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; }
-#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); }
-#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); }
-
-      // sadly can't use interleaved stores here since we only write
-      // 8 bytes to each scan line!
-
-      // 8x8 8-bit transpose pass 1
-      dct_trn8_8(p0, p1);
-      dct_trn8_8(p2, p3);
-      dct_trn8_8(p4, p5);
-      dct_trn8_8(p6, p7);
-
-      // pass 2
-      dct_trn8_16(p0, p2);
-      dct_trn8_16(p1, p3);
-      dct_trn8_16(p4, p6);
-      dct_trn8_16(p5, p7);
-
-      // pass 3
-      dct_trn8_32(p0, p4);
-      dct_trn8_32(p1, p5);
-      dct_trn8_32(p2, p6);
-      dct_trn8_32(p3, p7);
-
-      // store
-      vst1_u8(out, p0); out += out_stride;
-      vst1_u8(out, p1); out += out_stride;
-      vst1_u8(out, p2); out += out_stride;
-      vst1_u8(out, p3); out += out_stride;
-      vst1_u8(out, p4); out += out_stride;
-      vst1_u8(out, p5); out += out_stride;
-      vst1_u8(out, p6); out += out_stride;
-      vst1_u8(out, p7);
-
-#undef dct_trn8_8
-#undef dct_trn8_16
-#undef dct_trn8_32
-   }
-
-#undef dct_long_mul
-#undef dct_long_mac
-#undef dct_widen
-#undef dct_wadd
-#undef dct_wsub
-#undef dct_bfly32o
-#undef dct_pass
-}
-
-#endif // STBI_NEON
-
-#define STBI__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 stbi_uc stbi__get_marker(stbi__jpeg *j)
-{
-   stbi_uc x;
-   if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; }
-   x = stbi__get8(j->s);
-   if (x != 0xff) return STBI__MARKER_none;
-   while (x == 0xff)
-      x = stbi__get8(j->s); // consume repeated 0xff fill bytes
-   return x;
-}
-
-// in each scan, we'll have scan_n components, and the order
-// of the components is specified by order[]
-#define STBI__RESTART(x)     ((x) >= 0xd0 && (x) <= 0xd7)
-
-// after a restart interval, stbi__jpeg_reset the entropy decoder and
-// the dc prediction
-static void stbi__jpeg_reset(stbi__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 = j->img_comp[3].dc_pred = 0;
-   j->marker = STBI__MARKER_none;
-   j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
-   j->eob_run = 0;
-   // 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 stbi__parse_entropy_coded_data(stbi__jpeg *z)
-{
-   stbi__jpeg_reset(z);
-   if (!z->progressive) {
-      if (z->scan_n == 1) {
-         int i,j;
-         STBI_SIMD_ALIGN(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) {
-               int ha = z->img_comp[n].ha;
-               if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
-               z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
-               // every data block is an MCU, so countdown the restart interval
-               if (--z->todo <= 0) {
-                  if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
-                  // if it's NOT a restart, then just bail, so we get corrupt data
-                  // rather than no data
-                  if (!STBI__RESTART(z->marker)) return 1;
-                  stbi__jpeg_reset(z);
-               }
-            }
-         }
-         return 1;
-      } else { // interleaved
-         int i,j,k,x,y;
-         STBI_SIMD_ALIGN(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;
-                        int ha = z->img_comp[n].ha;
-                        if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
-                        z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data);
-                     }
-                  }
-               }
-               // 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) stbi__grow_buffer_unsafe(z);
-                  if (!STBI__RESTART(z->marker)) return 1;
-                  stbi__jpeg_reset(z);
-               }
-            }
-         }
-         return 1;
-      }
-   } else {
-      if (z->scan_n == 1) {
-         int i,j;
-         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) {
-               short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
-               if (z->spec_start == 0) {
-                  if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
-                     return 0;
-               } else {
-                  int ha = z->img_comp[n].ha;
-                  if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha]))
-                     return 0;
-               }
-               // every data block is an MCU, so countdown the restart interval
-               if (--z->todo <= 0) {
-                  if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
-                  if (!STBI__RESTART(z->marker)) return 1;
-                  stbi__jpeg_reset(z);
-               }
-            }
-         }
-         return 1;
-      } else { // interleaved
-         int i,j,k,x,y;
-         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);
-                        int y2 = (j*z->img_comp[n].v + y);
-                        short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w);
-                        if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
-                           return 0;
-                     }
-                  }
-               }
-               // 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) stbi__grow_buffer_unsafe(z);
-                  if (!STBI__RESTART(z->marker)) return 1;
-                  stbi__jpeg_reset(z);
-               }
-            }
-         }
-         return 1;
-      }
-   }
-}
-
-static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant)
-{
-   int i;
-   for (i=0; i < 64; ++i)
-      data[i] *= dequant[i];
-}
-
-static void stbi__jpeg_finish(stbi__jpeg *z)
-{
-   if (z->progressive) {
-      // dequantize and idct the data
-      int i,j,n;
-      for (n=0; n < z->s->img_n; ++n) {
-         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) {
-               short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
-               stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]);
-               z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
-            }
-         }
-      }
-   }
-}
-
-static int stbi__process_marker(stbi__jpeg *z, int m)
-{
-   int L;
-   switch (m) {
-      case STBI__MARKER_none: // no marker found
-         return stbi__err("expected marker","Corrupt JPEG");
-
-      case 0xDD: // DRI - specify restart interval
-         if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG");
-         z->restart_interval = stbi__get16be(z->s);
-         return 1;
-
-      case 0xDB: // DQT - define quantization table
-         L = stbi__get16be(z->s)-2;
-         while (L > 0) {
-            int q = stbi__get8(z->s);
-            int p = q >> 4, sixteen = (p != 0);
-            int t = q & 15,i;
-            if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG");
-            if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG");
-
-            for (i=0; i < 64; ++i)
-               z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s));
-            L -= (sixteen ? 129 : 65);
-         }
-         return L==0;
-
-      case 0xC4: // DHT - define huffman table
-         L = stbi__get16be(z->s)-2;
-         while (L > 0) {
-            stbi_uc *v;
-            int sizes[16],i,n=0;
-            int q = stbi__get8(z->s);
-            int tc = q >> 4;
-            int th = q & 15;
-            if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG");
-            for (i=0; i < 16; ++i) {
-               sizes[i] = stbi__get8(z->s);
-               n += sizes[i];
-            }
-            if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values!
-            L -= 17;
-            if (tc == 0) {
-               if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
-               v = z->huff_dc[th].values;
-            } else {
-               if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0;
-               v = z->huff_ac[th].values;
-            }
-            for (i=0; i < n; ++i)
-               v[i] = stbi__get8(z->s);
-            if (tc != 0)
-               stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th);
-            L -= n;
-         }
-         return L==0;
-   }
-
-   // check for comment block or APP blocks
-   if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
-      L = stbi__get16be(z->s);
-      if (L < 2) {
-         if (m == 0xFE)
-            return stbi__err("bad COM len","Corrupt JPEG");
-         else
-            return stbi__err("bad APP len","Corrupt JPEG");
-      }
-      L -= 2;
-
-      if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
-         static const unsigned char tag[5] = {'J','F','I','F','\0'};
-         int ok = 1;
-         int i;
-         for (i=0; i < 5; ++i)
-            if (stbi__get8(z->s) != tag[i])
-               ok = 0;
-         L -= 5;
-         if (ok)
-            z->jfif = 1;
-      } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
-         static const unsigned char tag[6] = {'A','d','o','b','e','\0'};
-         int ok = 1;
-         int i;
-         for (i=0; i < 6; ++i)
-            if (stbi__get8(z->s) != tag[i])
-               ok = 0;
-         L -= 6;
-         if (ok) {
-            stbi__get8(z->s); // version
-            stbi__get16be(z->s); // flags0
-            stbi__get16be(z->s); // flags1
-            z->app14_color_transform = stbi__get8(z->s); // color transform
-            L -= 6;
-         }
-      }
-
-      stbi__skip(z->s, L);
-      return 1;
-   }
-
-   return stbi__err("unknown marker","Corrupt JPEG");
-}
-
-// after we see SOS
-static int stbi__process_scan_header(stbi__jpeg *z)
-{
-   int i;
-   int Ls = stbi__get16be(z->s);
-   z->scan_n = stbi__get8(z->s);
-   if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG");
-   if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG");
-   for (i=0; i < z->scan_n; ++i) {
-      int id = stbi__get8(z->s), which;
-      int q = stbi__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; // no match
-      z->img_comp[which].hd = q >> 4;   if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG");
-      z->img_comp[which].ha = q & 15;   if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG");
-      z->order[i] = which;
-   }
-
-   {
-      int aa;
-      z->spec_start = stbi__get8(z->s);
-      z->spec_end   = stbi__get8(z->s); // should be 63, but might be 0
-      aa = stbi__get8(z->s);
-      z->succ_high = (aa >> 4);
-      z->succ_low  = (aa & 15);
-      if (z->progressive) {
-         if (z->spec_start > 63 || z->spec_end > 63  || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13)
-            return stbi__err("bad SOS", "Corrupt JPEG");
-      } else {
-         if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG");
-         if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG");
-         z->spec_end = 63;
-      }
-   }
-
-   return 1;
-}
-
-static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why)
-{
-   int i;
-   for (i=0; i < ncomp; ++i) {
-      if (z->img_comp[i].raw_data) {
-         STBI_FREE(z->img_comp[i].raw_data);
-         z->img_comp[i].raw_data = NULL;
-         z->img_comp[i].data = NULL;
-      }
-      if (z->img_comp[i].raw_coeff) {
-         STBI_FREE(z->img_comp[i].raw_coeff);
-         z->img_comp[i].raw_coeff = 0;
-         z->img_comp[i].coeff = 0;
-      }
-      if (z->img_comp[i].linebuf) {
-         STBI_FREE(z->img_comp[i].linebuf);
-         z->img_comp[i].linebuf = NULL;
-      }
-   }
-   return why;
-}
-
-static int stbi__process_frame_header(stbi__jpeg *z, int scan)
-{
-   stbi__context *s = z->s;
-   int Lf,p,i,q, h_max=1,v_max=1,c;
-   Lf = stbi__get16be(s);         if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG
-   p  = stbi__get8(s);            if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
-   s->img_y = stbi__get16be(s);   if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
-   s->img_x = stbi__get16be(s);   if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
-   if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
-   if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
-   c = stbi__get8(s);
-   if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
-   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 stbi__err("bad SOF len","Corrupt JPEG");
-
-   z->rgb = 0;
-   for (i=0; i < s->img_n; ++i) {
-      static const unsigned char rgb[3] = { 'R', 'G', 'B' };
-      z->img_comp[i].id = stbi__get8(s);
-      if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
-         ++z->rgb;
-      q = stbi__get8(s);
-      z->img_comp[i].h = (q >> 4);  if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
-      z->img_comp[i].v = q & 15;    if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
-      z->img_comp[i].tq = stbi__get8(s);  if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG");
-   }
-
-   if (scan != STBI__SCAN_load) return 1;
-
-   if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("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;
-   }
-
-   // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios
-   // and I've never seen a non-corrupted JPEG file actually use them
-   for (i=0; i < s->img_n; ++i) {
-      if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG");
-      if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG");
-   }
-
-   // 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;
-   // these sizes can't be more than 17 bits
-   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
-      //
-      // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier)
-      // so these muls can't overflow with 32-bit ints (which we require)
-      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].coeff = 0;
-      z->img_comp[i].raw_coeff = 0;
-      z->img_comp[i].linebuf = NULL;
-      z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15);
-      if (z->img_comp[i].raw_data == NULL)
-         return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
-      // align blocks for idct using mmx/sse
-      z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15);
-      if (z->progressive) {
-         // w2, h2 are multiples of 8 (see above)
-         z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8;
-         z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8;
-         z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15);
-         if (z->img_comp[i].raw_coeff == NULL)
-            return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
-         z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15);
-      }
-   }
-
-   return 1;
-}
-
-// use comparisons since in some cases we handle more than one case (e.g. SOF)
-#define stbi__DNL(x)         ((x) == 0xdc)
-#define stbi__SOI(x)         ((x) == 0xd8)
-#define stbi__EOI(x)         ((x) == 0xd9)
-#define stbi__SOF(x)         ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2)
-#define stbi__SOS(x)         ((x) == 0xda)
-
-#define stbi__SOF_progressive(x)   ((x) == 0xc2)
-
-static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
-{
-   int m;
-   z->jfif = 0;
-   z->app14_color_transform = -1; // valid values are 0,1,2
-   z->marker = STBI__MARKER_none; // initialize cached marker to empty
-   m = stbi__get_marker(z);
-   if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
-   if (scan == STBI__SCAN_type) return 1;
-   m = stbi__get_marker(z);
-   while (!stbi__SOF(m)) {
-      if (!stbi__process_marker(z,m)) return 0;
-      m = stbi__get_marker(z);
-      while (m == STBI__MARKER_none) {
-         // some files have extra padding after their blocks, so ok, we'll scan
-         if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG");
-         m = stbi__get_marker(z);
-      }
-   }
-   z->progressive = stbi__SOF_progressive(m);
-   if (!stbi__process_frame_header(z, scan)) return 0;
-   return 1;
-}
-
-static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
-{
-   // some JPEGs have junk at end, skip over it but if we find what looks
-   // like a valid marker, resume there
-   while (!stbi__at_eof(j->s)) {
-      stbi_uc x = stbi__get8(j->s);
-      while (x == 0xff) { // might be a marker
-         if (stbi__at_eof(j->s)) return STBI__MARKER_none;
-         x = stbi__get8(j->s);
-         if (x != 0x00 && x != 0xff) {
-            // not a stuffed zero or lead-in to another marker, looks
-            // like an actual marker, return it
-            return x;
-         }
-         // stuffed zero has x=0 now which ends the loop, meaning we go
-         // back to regular scan loop.
-         // repeated 0xff keeps trying to read the next byte of the marker.
-      }
-   }
-   return STBI__MARKER_none;
-}
-
-// decode image to YCbCr format
-static int stbi__decode_jpeg_image(stbi__jpeg *j)
-{
-   int m;
-   for (m = 0; m < 4; m++) {
-      j->img_comp[m].raw_data = NULL;
-      j->img_comp[m].raw_coeff = NULL;
-   }
-   j->restart_interval = 0;
-   if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0;
-   m = stbi__get_marker(j);
-   while (!stbi__EOI(m)) {
-      if (stbi__SOS(m)) {
-         if (!stbi__process_scan_header(j)) return 0;
-         if (!stbi__parse_entropy_coded_data(j)) return 0;
-         if (j->marker == STBI__MARKER_none ) {
-         j->marker = stbi__skip_jpeg_junk_at_end(j);
-            // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
-         }
-         m = stbi__get_marker(j);
-         if (STBI__RESTART(m))
-            m = stbi__get_marker(j);
-      } else if (stbi__DNL(m)) {
-         int Ld = stbi__get16be(j->s);
-         stbi__uint32 NL = stbi__get16be(j->s);
-         if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
-         if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
-         m = stbi__get_marker(j);
-      } else {
-         if (!stbi__process_marker(j, m)) return 1;
-         m = stbi__get_marker(j);
-      }
-   }
-   if (j->progressive)
-      stbi__jpeg_finish(j);
-   return 1;
-}
-
-// static jfif-centered resampling (across block boundaries)
-
-typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1,
-                                    int w, int hs);
-
-#define stbi__div4(x) ((stbi_uc) ((x) >> 2))
-
-static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   STBI_NOTUSED(out);
-   STBI_NOTUSED(in_far);
-   STBI_NOTUSED(w);
-   STBI_NOTUSED(hs);
-   return in_near;
-}
-
-static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *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] = stbi__div4(3*in_near[i] + in_far[i] + 2);
-   return out;
-}
-
-static stbi_uc*  stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   // need to generate two samples horizontally for every one in input
-   int i;
-   stbi_uc *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] = stbi__div4(input[0]*3 + input[1] + 2);
-   for (i=1; i < w-1; ++i) {
-      int n = 3*input[i]+2;
-      out[i*2+0] = stbi__div4(n+input[i-1]);
-      out[i*2+1] = stbi__div4(n+input[i+1]);
-   }
-   out[i*2+0] = stbi__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 stbi__div16(x) ((stbi_uc) ((x) >> 4))
-
-static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *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] = stbi__div4(3*in_near[0] + in_far[0] + 2);
-      return out;
-   }
-
-   t1 = 3*in_near[0] + in_far[0];
-   out[0] = stbi__div4(t1+2);
-   for (i=1; i < w; ++i) {
-      t0 = t1;
-      t1 = 3*in_near[i]+in_far[i];
-      out[i*2-1] = stbi__div16(3*t0 + t1 + 8);
-      out[i*2  ] = stbi__div16(3*t1 + t0 + 8);
-   }
-   out[w*2-1] = stbi__div4(t1+2);
-
-   STBI_NOTUSED(hs);
-
-   return out;
-}
-
-#if defined(STBI_SSE2) || defined(STBI_NEON)
-static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   // need to generate 2x2 samples for every one in input
-   int i=0,t0,t1;
-
-   if (w == 1) {
-      out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2);
-      return out;
-   }
-
-   t1 = 3*in_near[0] + in_far[0];
-   // process groups of 8 pixels for as long as we can.
-   // note we can't handle the last pixel in a row in this loop
-   // because we need to handle the filter boundary conditions.
-   for (; i < ((w-1) & ~7); i += 8) {
-#if defined(STBI_SSE2)
-      // load and perform the vertical filtering pass
-      // this uses 3*x + y = 4*x + (y - x)
-      __m128i zero  = _mm_setzero_si128();
-      __m128i farb  = _mm_loadl_epi64((__m128i *) (in_far + i));
-      __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i));
-      __m128i farw  = _mm_unpacklo_epi8(farb, zero);
-      __m128i nearw = _mm_unpacklo_epi8(nearb, zero);
-      __m128i diff  = _mm_sub_epi16(farw, nearw);
-      __m128i nears = _mm_slli_epi16(nearw, 2);
-      __m128i curr  = _mm_add_epi16(nears, diff); // current row
-
-      // horizontal filter works the same based on shifted vers of current
-      // row. "prev" is current row shifted right by 1 pixel; we need to
-      // insert the previous pixel value (from t1).
-      // "next" is current row shifted left by 1 pixel, with first pixel
-      // of next block of 8 pixels added in.
-      __m128i prv0 = _mm_slli_si128(curr, 2);
-      __m128i nxt0 = _mm_srli_si128(curr, 2);
-      __m128i prev = _mm_insert_epi16(prv0, t1, 0);
-      __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7);
-
-      // horizontal filter, polyphase implementation since it's convenient:
-      // even pixels = 3*cur + prev = cur*4 + (prev - cur)
-      // odd  pixels = 3*cur + next = cur*4 + (next - cur)
-      // note the shared term.
-      __m128i bias  = _mm_set1_epi16(8);
-      __m128i curs = _mm_slli_epi16(curr, 2);
-      __m128i prvd = _mm_sub_epi16(prev, curr);
-      __m128i nxtd = _mm_sub_epi16(next, curr);
-      __m128i curb = _mm_add_epi16(curs, bias);
-      __m128i even = _mm_add_epi16(prvd, curb);
-      __m128i odd  = _mm_add_epi16(nxtd, curb);
-
-      // interleave even and odd pixels, then undo scaling.
-      __m128i int0 = _mm_unpacklo_epi16(even, odd);
-      __m128i int1 = _mm_unpackhi_epi16(even, odd);
-      __m128i de0  = _mm_srli_epi16(int0, 4);
-      __m128i de1  = _mm_srli_epi16(int1, 4);
-
-      // pack and write output
-      __m128i outv = _mm_packus_epi16(de0, de1);
-      _mm_storeu_si128((__m128i *) (out + i*2), outv);
-#elif defined(STBI_NEON)
-      // load and perform the vertical filtering pass
-      // this uses 3*x + y = 4*x + (y - x)
-      uint8x8_t farb  = vld1_u8(in_far + i);
-      uint8x8_t nearb = vld1_u8(in_near + i);
-      int16x8_t diff  = vreinterpretq_s16_u16(vsubl_u8(farb, nearb));
-      int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2));
-      int16x8_t curr  = vaddq_s16(nears, diff); // current row
-
-      // horizontal filter works the same based on shifted vers of current
-      // row. "prev" is current row shifted right by 1 pixel; we need to
-      // insert the previous pixel value (from t1).
-      // "next" is current row shifted left by 1 pixel, with first pixel
-      // of next block of 8 pixels added in.
-      int16x8_t prv0 = vextq_s16(curr, curr, 7);
-      int16x8_t nxt0 = vextq_s16(curr, curr, 1);
-      int16x8_t prev = vsetq_lane_s16(t1, prv0, 0);
-      int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7);
-
-      // horizontal filter, polyphase implementation since it's convenient:
-      // even pixels = 3*cur + prev = cur*4 + (prev - cur)
-      // odd  pixels = 3*cur + next = cur*4 + (next - cur)
-      // note the shared term.
-      int16x8_t curs = vshlq_n_s16(curr, 2);
-      int16x8_t prvd = vsubq_s16(prev, curr);
-      int16x8_t nxtd = vsubq_s16(next, curr);
-      int16x8_t even = vaddq_s16(curs, prvd);
-      int16x8_t odd  = vaddq_s16(curs, nxtd);
-
-      // undo scaling and round, then store with even/odd phases interleaved
-      uint8x8x2_t o;
-      o.val[0] = vqrshrun_n_s16(even, 4);
-      o.val[1] = vqrshrun_n_s16(odd,  4);
-      vst2_u8(out + i*2, o);
-#endif
-
-      // "previous" value for next iter
-      t1 = 3*in_near[i+7] + in_far[i+7];
-   }
-
-   t0 = t1;
-   t1 = 3*in_near[i] + in_far[i];
-   out[i*2] = stbi__div16(3*t1 + t0 + 8);
-
-   for (++i; i < w; ++i) {
-      t0 = t1;
-      t1 = 3*in_near[i]+in_far[i];
-      out[i*2-1] = stbi__div16(3*t0 + t1 + 8);
-      out[i*2  ] = stbi__div16(3*t1 + t0 + 8);
-   }
-   out[w*2-1] = stbi__div4(t1+2);
-
-   STBI_NOTUSED(hs);
-
-   return out;
-}
-#endif
-
-static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   // resample with nearest-neighbor
-   int i,j;
-   STBI_NOTUSED(in_far);
-   for (i=0; i < w; ++i)
-      for (j=0; j < hs; ++j)
-         out[i*hs+j] = in_near[i];
-   return out;
-}
-
-// this is a reduced-precision calculation of YCbCr-to-RGB introduced
-// to make sure the code produces the same results in both SIMD and scalar
-#define stbi__float2fixed(x)  (((int) ((x) * 4096.0f + 0.5f)) << 8)
-static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
-{
-   int i;
-   for (i=0; i < count; ++i) {
-      int y_fixed = (y[i] << 20) + (1<<19); // rounding
-      int r,g,b;
-      int cr = pcr[i] - 128;
-      int cb = pcb[i] - 128;
-      r = y_fixed +  cr* stbi__float2fixed(1.40200f);
-      g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
-      b = y_fixed                                     +   cb* stbi__float2fixed(1.77200f);
-      r >>= 20;
-      g >>= 20;
-      b >>= 20;
-      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] = (stbi_uc)r;
-      out[1] = (stbi_uc)g;
-      out[2] = (stbi_uc)b;
-      out[3] = 255;
-      out += step;
-   }
-}
-
-#if defined(STBI_SSE2) || defined(STBI_NEON)
-static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step)
-{
-   int i = 0;
-
-#ifdef STBI_SSE2
-   // step == 3 is pretty ugly on the final interleave, and i'm not convinced
-   // it's useful in practice (you wouldn't use it for textures, for example).
-   // so just accelerate step == 4 case.
-   if (step == 4) {
-      // this is a fairly straightforward implementation and not super-optimized.
-      __m128i signflip  = _mm_set1_epi8(-0x80);
-      __m128i cr_const0 = _mm_set1_epi16(   (short) ( 1.40200f*4096.0f+0.5f));
-      __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f));
-      __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f));
-      __m128i cb_const1 = _mm_set1_epi16(   (short) ( 1.77200f*4096.0f+0.5f));
-      __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128);
-      __m128i xw = _mm_set1_epi16(255); // alpha channel
-
-      for (; i+7 < count; i += 8) {
-         // load
-         __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i));
-         __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i));
-         __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i));
-         __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128
-         __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128
-
-         // unpack to short (and left-shift cr, cb by 8)
-         __m128i yw  = _mm_unpacklo_epi8(y_bias, y_bytes);
-         __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased);
-         __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased);
-
-         // color transform
-         __m128i yws = _mm_srli_epi16(yw, 4);
-         __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw);
-         __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw);
-         __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1);
-         __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1);
-         __m128i rws = _mm_add_epi16(cr0, yws);
-         __m128i gwt = _mm_add_epi16(cb0, yws);
-         __m128i bws = _mm_add_epi16(yws, cb1);
-         __m128i gws = _mm_add_epi16(gwt, cr1);
-
-         // descale
-         __m128i rw = _mm_srai_epi16(rws, 4);
-         __m128i bw = _mm_srai_epi16(bws, 4);
-         __m128i gw = _mm_srai_epi16(gws, 4);
-
-         // back to byte, set up for transpose
-         __m128i brb = _mm_packus_epi16(rw, bw);
-         __m128i gxb = _mm_packus_epi16(gw, xw);
-
-         // transpose to interleave channels
-         __m128i t0 = _mm_unpacklo_epi8(brb, gxb);
-         __m128i t1 = _mm_unpackhi_epi8(brb, gxb);
-         __m128i o0 = _mm_unpacklo_epi16(t0, t1);
-         __m128i o1 = _mm_unpackhi_epi16(t0, t1);
-
-         // store
-         _mm_storeu_si128((__m128i *) (out + 0), o0);
-         _mm_storeu_si128((__m128i *) (out + 16), o1);
-         out += 32;
-      }
-   }
-#endif
-
-#ifdef STBI_NEON
-   // in this version, step=3 support would be easy to add. but is there demand?
-   if (step == 4) {
-      // this is a fairly straightforward implementation and not super-optimized.
-      uint8x8_t signflip = vdup_n_u8(0x80);
-      int16x8_t cr_const0 = vdupq_n_s16(   (short) ( 1.40200f*4096.0f+0.5f));
-      int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f));
-      int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f));
-      int16x8_t cb_const1 = vdupq_n_s16(   (short) ( 1.77200f*4096.0f+0.5f));
-
-      for (; i+7 < count; i += 8) {
-         // load
-         uint8x8_t y_bytes  = vld1_u8(y + i);
-         uint8x8_t cr_bytes = vld1_u8(pcr + i);
-         uint8x8_t cb_bytes = vld1_u8(pcb + i);
-         int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip));
-         int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip));
-
-         // expand to s16
-         int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4));
-         int16x8_t crw = vshll_n_s8(cr_biased, 7);
-         int16x8_t cbw = vshll_n_s8(cb_biased, 7);
-
-         // color transform
-         int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0);
-         int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0);
-         int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1);
-         int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1);
-         int16x8_t rws = vaddq_s16(yws, cr0);
-         int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1);
-         int16x8_t bws = vaddq_s16(yws, cb1);
-
-         // undo scaling, round, convert to byte
-         uint8x8x4_t o;
-         o.val[0] = vqrshrun_n_s16(rws, 4);
-         o.val[1] = vqrshrun_n_s16(gws, 4);
-         o.val[2] = vqrshrun_n_s16(bws, 4);
-         o.val[3] = vdup_n_u8(255);
-
-         // store, interleaving r/g/b/a
-         vst4_u8(out, o);
-         out += 8*4;
-      }
-   }
-#endif
-
-   for (; i < count; ++i) {
-      int y_fixed = (y[i] << 20) + (1<<19); // rounding
-      int r,g,b;
-      int cr = pcr[i] - 128;
-      int cb = pcb[i] - 128;
-      r = y_fixed + cr* stbi__float2fixed(1.40200f);
-      g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
-      b = y_fixed                                   +   cb* stbi__float2fixed(1.77200f);
-      r >>= 20;
-      g >>= 20;
-      b >>= 20;
-      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] = (stbi_uc)r;
-      out[1] = (stbi_uc)g;
-      out[2] = (stbi_uc)b;
-      out[3] = 255;
-      out += step;
-   }
-}
-#endif
-
-// set up the kernels
-static void stbi__setup_jpeg(stbi__jpeg *j)
-{
-   j->idct_block_kernel = stbi__idct_block;
-   j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row;
-   j->resample_row_hv_2_kernel = stbi__resample_row_hv_2;
-
-#ifdef STBI_SSE2
-   if (stbi__sse2_available()) {
-      j->idct_block_kernel = stbi__idct_simd;
-      j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
-      j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
-   }
-#endif
-
-#ifdef STBI_NEON
-   j->idct_block_kernel = stbi__idct_simd;
-   j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
-   j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
-#endif
-}
-
-// clean up the temporary component buffers
-static void stbi__cleanup_jpeg(stbi__jpeg *j)
-{
-   stbi__free_jpeg_components(j, j->s->img_n, 0);
-}
-
-typedef struct
-{
-   resample_row_func resample;
-   stbi_uc *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;
-
-// fast 0..255 * 0..255 => 0..255 rounded multiplication
-static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y)
-{
-   unsigned int t = x*y + 128;
-   return (stbi_uc) ((t + (t >>8)) >> 8);
-}
-
-static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
-{
-   int n, decode_n, is_rgb;
-   z->s->img_n = 0; // make stbi__cleanup_jpeg safe
-
-   // validate req_comp
-   if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
-
-   // load a jpeg image from whichever source, but leave in YCbCr format
-   if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
-
-   // determine actual number of components to generate
-   n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
-
-   is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
-
-   if (z->s->img_n == 3 && n < 3 && !is_rgb)
-      decode_n = 1;
-   else
-      decode_n = z->s->img_n;
-
-   // nothing to do if no components requested; check this now to avoid
-   // accessing uninitialized coutput[0] later
-   if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; }
-
-   // resample and color-convert
-   {
-      int k;
-      unsigned int i,j;
-      stbi_uc *output;
-      stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL };
-
-      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 = (stbi_uc *) stbi__malloc(z->s->img_x + 3);
-         if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("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 = stbi__resample_row_v_2;
-         else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2;
-         else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel;
-         else                               r->resample = stbi__resample_row_generic;
-      }
-
-      // can't error after this so, this is safe
-      output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1);
-      if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
-
-      // now go ahead and resample
-      for (j=0; j < z->s->img_y; ++j) {
-         stbi_uc *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) {
-            stbi_uc *y = coutput[0];
-            if (z->s->img_n == 3) {
-               if (is_rgb) {
-                  for (i=0; i < z->s->img_x; ++i) {
-                     out[0] = y[i];
-                     out[1] = coutput[1][i];
-                     out[2] = coutput[2][i];
-                     out[3] = 255;
-                     out += n;
-                  }
-               } else {
-                  z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
-               }
-            } else if (z->s->img_n == 4) {
-               if (z->app14_color_transform == 0) { // CMYK
-                  for (i=0; i < z->s->img_x; ++i) {
-                     stbi_uc m = coutput[3][i];
-                     out[0] = stbi__blinn_8x8(coutput[0][i], m);
-                     out[1] = stbi__blinn_8x8(coutput[1][i], m);
-                     out[2] = stbi__blinn_8x8(coutput[2][i], m);
-                     out[3] = 255;
-                     out += n;
-                  }
-               } else if (z->app14_color_transform == 2) { // YCCK
-                  z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
-                  for (i=0; i < z->s->img_x; ++i) {
-                     stbi_uc m = coutput[3][i];
-                     out[0] = stbi__blinn_8x8(255 - out[0], m);
-                     out[1] = stbi__blinn_8x8(255 - out[1], m);
-                     out[2] = stbi__blinn_8x8(255 - out[2], m);
-                     out += n;
-                  }
-               } else { // YCbCr + alpha?  Ignore the fourth channel for now
-                  z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
-               }
-            } 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 {
-            if (is_rgb) {
-               if (n == 1)
-                  for (i=0; i < z->s->img_x; ++i)
-                     *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
-               else {
-                  for (i=0; i < z->s->img_x; ++i, out += 2) {
-                     out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
-                     out[1] = 255;
-                  }
-               }
-            } else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
-               for (i=0; i < z->s->img_x; ++i) {
-                  stbi_uc m = coutput[3][i];
-                  stbi_uc r = stbi__blinn_8x8(coutput[0][i], m);
-                  stbi_uc g = stbi__blinn_8x8(coutput[1][i], m);
-                  stbi_uc b = stbi__blinn_8x8(coutput[2][i], m);
-                  out[0] = stbi__compute_y(r, g, b);
-                  out[1] = 255;
-                  out += n;
-               }
-            } else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
-               for (i=0; i < z->s->img_x; ++i) {
-                  out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
-                  out[1] = 255;
-                  out += n;
-               }
-            } else {
-               stbi_uc *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; }
-            }
-         }
-      }
-      stbi__cleanup_jpeg(z);
-      *out_x = z->s->img_x;
-      *out_y = z->s->img_y;
-      if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
-      return output;
-   }
-}
-
-static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   unsigned char* result;
-   stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
-   if (!j) return stbi__errpuc("outofmem", "Out of memory");
-   memset(j, 0, sizeof(stbi__jpeg));
-   STBI_NOTUSED(ri);
-   j->s = s;
-   stbi__setup_jpeg(j);
-   result = load_jpeg_image(j, x,y,comp,req_comp);
-   STBI_FREE(j);
-   return result;
-}
-
-static int stbi__jpeg_test(stbi__context *s)
-{
-   int r;
-   stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
-   if (!j) return stbi__err("outofmem", "Out of memory");
-   memset(j, 0, sizeof(stbi__jpeg));
-   j->s = s;
-   stbi__setup_jpeg(j);
-   r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
-   stbi__rewind(s);
-   STBI_FREE(j);
-   return r;
-}
-
-static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
-{
-   if (!stbi__decode_jpeg_header(j, STBI__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 >= 3 ? 3 : 1;
-   return 1;
-}
-
-static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   int result;
-   stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
-   if (!j) return stbi__err("outofmem", "Out of memory");
-   memset(j, 0, sizeof(stbi__jpeg));
-   j->s = s;
-   result = stbi__jpeg_info_raw(j, x, y, comp);
-   STBI_FREE(j);
-   return result;
-}
-#endif
-
-// 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
-
-#ifndef STBI_NO_ZLIB
-
-// fast-way is faster to check than jpeg huffman, but slow way is slower
-#define STBI__ZFAST_BITS  9 // accelerate all cases in default tables
-#define STBI__ZFAST_MASK  ((1 << STBI__ZFAST_BITS) - 1)
-#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet
-
-// zlib-style huffman encoding
-// (jpegs packs from left, zlib from right, so can't share code)
-typedef struct
-{
-   stbi__uint16 fast[1 << STBI__ZFAST_BITS];
-   stbi__uint16 firstcode[16];
-   int maxcode[17];
-   stbi__uint16 firstsymbol[16];
-   stbi_uc  size[STBI__ZNSYMS];
-   stbi__uint16 value[STBI__ZNSYMS];
-} stbi__zhuffman;
-
-stbi_inline static int stbi__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 stbi__bit_reverse(int v, int bits)
-{
-   STBI_ASSERT(bits <= 16);
-   // to bit reverse n bits, reverse 16 and shift
-   // e.g. 11 bits, bit reverse and shift away 5
-   return stbi__bitreverse16(v) >> (16-bits);
-}
-
-static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *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, 0, sizeof(z->fast));
-   for (i=0; i < num; ++i)
-      ++sizes[sizelist[i]];
-   sizes[0] = 0;
-   for (i=1; i < 16; ++i)
-      if (sizes[i] > (1 << i))
-         return stbi__err("bad sizes", "Corrupt PNG");
-   code = 0;
-   for (i=1; i < 16; ++i) {
-      next_code[i] = code;
-      z->firstcode[i] = (stbi__uint16) code;
-      z->firstsymbol[i] = (stbi__uint16) k;
-      code = (code + sizes[i]);
-      if (sizes[i])
-         if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG");
-      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];
-         stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i);
-         z->size [c] = (stbi_uc     ) s;
-         z->value[c] = (stbi__uint16) i;
-         if (s <= STBI__ZFAST_BITS) {
-            int j = stbi__bit_reverse(next_code[s],s);
-            while (j < (1 << STBI__ZFAST_BITS)) {
-               z->fast[j] = fastv;
-               j += (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
-{
-   stbi_uc *zbuffer, *zbuffer_end;
-   int num_bits;
-   int hit_zeof_once;
-   stbi__uint32 code_buffer;
-
-   char *zout;
-   char *zout_start;
-   char *zout_end;
-   int   z_expandable;
-
-   stbi__zhuffman z_length, z_distance;
-} stbi__zbuf;
-
-stbi_inline static int stbi__zeof(stbi__zbuf *z)
-{
-   return (z->zbuffer >= z->zbuffer_end);
-}
-
-stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
-{
-   return stbi__zeof(z) ? 0 : *z->zbuffer++;
-}
-
-static void stbi__fill_bits(stbi__zbuf *z)
-{
-   do {
-      if (z->code_buffer >= (1U << z->num_bits)) {
-        z->zbuffer = z->zbuffer_end;  /* treat this as EOF so we fail. */
-        return;
-      }
-      z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
-      z->num_bits += 8;
-   } while (z->num_bits <= 24);
-}
-
-stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n)
-{
-   unsigned int k;
-   if (z->num_bits < n) stbi__fill_bits(z);
-   k = z->code_buffer & ((1 << n) - 1);
-   z->code_buffer >>= n;
-   z->num_bits -= n;
-   return k;
-}
-
-static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
-{
-   int b,s,k;
-   // not resolved by fast table, so compute it the slow way
-   // use jpeg approach, which requires MSbits at top
-   k = stbi__bit_reverse(a->code_buffer, 16);
-   for (s=STBI__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];
-   if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere!
-   if (z->size[b] != s) return -1;  // was originally an assert, but report failure instead.
-   a->code_buffer >>= s;
-   a->num_bits -= s;
-   return z->value[b];
-}
-
-stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
-{
-   int b,s;
-   if (a->num_bits < 16) {
-      if (stbi__zeof(a)) {
-         if (!a->hit_zeof_once) {
-            // This is the first time we hit eof, insert 16 extra padding btis
-            // to allow us to keep going; if we actually consume any of them
-            // though, that is invalid data. This is caught later.
-            a->hit_zeof_once = 1;
-            a->num_bits += 16; // add 16 implicit zero bits
-         } else {
-            // We already inserted our extra 16 padding bits and are again
-            // out, this stream is actually prematurely terminated.
-            return -1;
-         }
-      } else {
-         stbi__fill_bits(a);
-      }
-   }
-   b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
-   if (b) {
-      s = b >> 9;
-      a->code_buffer >>= s;
-      a->num_bits -= s;
-      return b & 511;
-   }
-   return stbi__zhuffman_decode_slowpath(a, z);
-}
-
-static int stbi__zexpand(stbi__zbuf *z, char *zout, int n)  // need to make room for n bytes
-{
-   char *q;
-   unsigned int cur, limit, old_limit;
-   z->zout = zout;
-   if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
-   cur   = (unsigned int) (z->zout - z->zout_start);
-   limit = old_limit = (unsigned) (z->zout_end - z->zout_start);
-   if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory");
-   while (cur + n > limit) {
-      if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory");
-      limit *= 2;
-   }
-   q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
-   STBI_NOTUSED(old_limit);
-   if (q == NULL) return stbi__err("outofmem", "Out of memory");
-   z->zout_start = q;
-   z->zout       = q + cur;
-   z->zout_end   = q + limit;
-   return 1;
-}
-
-static const int stbi__zlength_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 const int stbi__zlength_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 const int stbi__zdist_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 const int stbi__zdist_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 stbi__parse_huffman_block(stbi__zbuf *a)
-{
-   char *zout = a->zout;
-   for(;;) {
-      int z = stbi__zhuffman_decode(a, &a->z_length);
-      if (z < 256) {
-         if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes
-         if (zout >= a->zout_end) {
-            if (!stbi__zexpand(a, zout, 1)) return 0;
-            zout = a->zout;
-         }
-         *zout++ = (char) z;
-      } else {
-         stbi_uc *p;
-         int len,dist;
-         if (z == 256) {
-            a->zout = zout;
-            if (a->hit_zeof_once && a->num_bits < 16) {
-               // The first time we hit zeof, we inserted 16 extra zero bits into our bit
-               // buffer so the decoder can just do its speculative decoding. But if we
-               // actually consumed any of those bits (which is the case when num_bits < 16),
-               // the stream actually read past the end so it is malformed.
-               return stbi__err("unexpected end","Corrupt PNG");
-            }
-            return 1;
-         }
-         if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data
-         z -= 257;
-         len = stbi__zlength_base[z];
-         if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]);
-         z = stbi__zhuffman_decode(a, &a->z_distance);
-         if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data
-         dist = stbi__zdist_base[z];
-         if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
-         if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
-         if (len > a->zout_end - zout) {
-            if (!stbi__zexpand(a, zout, len)) return 0;
-            zout = a->zout;
-         }
-         p = (stbi_uc *) (zout - dist);
-         if (dist == 1) { // run of one byte; common in images.
-            stbi_uc v = *p;
-            if (len) { do *zout++ = v; while (--len); }
-         } else {
-            if (len) { do *zout++ = *p++; while (--len); }
-         }
-      }
-   }
-}
-
-static int stbi__compute_huffman_codes(stbi__zbuf *a)
-{
-   static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
-   stbi__zhuffman z_codelength;
-   stbi_uc lencodes[286+32+137];//padding for maximum single op
-   stbi_uc codelength_sizes[19];
-   int i,n;
-
-   int hlit  = stbi__zreceive(a,5) + 257;
-   int hdist = stbi__zreceive(a,5) + 1;
-   int hclen = stbi__zreceive(a,4) + 4;
-   int ntot  = hlit + hdist;
-
-   memset(codelength_sizes, 0, sizeof(codelength_sizes));
-   for (i=0; i < hclen; ++i) {
-      int s = stbi__zreceive(a,3);
-      codelength_sizes[length_dezigzag[i]] = (stbi_uc) s;
-   }
-   if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0;
-
-   n = 0;
-   while (n < ntot) {
-      int c = stbi__zhuffman_decode(a, &z_codelength);
-      if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG");
-      if (c < 16)
-         lencodes[n++] = (stbi_uc) c;
-      else {
-         stbi_uc fill = 0;
-         if (c == 16) {
-            c = stbi__zreceive(a,2)+3;
-            if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
-            fill = lencodes[n-1];
-         } else if (c == 17) {
-            c = stbi__zreceive(a,3)+3;
-         } else if (c == 18) {
-            c = stbi__zreceive(a,7)+11;
-         } else {
-            return stbi__err("bad codelengths", "Corrupt PNG");
-         }
-         if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
-         memset(lencodes+n, fill, c);
-         n += c;
-      }
-   }
-   if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG");
-   if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0;
-   if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0;
-   return 1;
-}
-
-static int stbi__parse_uncompressed_block(stbi__zbuf *a)
-{
-   stbi_uc header[4];
-   int len,nlen,k;
-   if (a->num_bits & 7)
-      stbi__zreceive(a, a->num_bits & 7); // discard
-   // drain the bit-packed data into header
-   k = 0;
-   while (a->num_bits > 0) {
-      header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check
-      a->code_buffer >>= 8;
-      a->num_bits -= 8;
-   }
-   if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG");
-   // now fill header the normal way
-   while (k < 4)
-      header[k++] = stbi__zget8(a);
-   len  = header[1] * 256 + header[0];
-   nlen = header[3] * 256 + header[2];
-   if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG");
-   if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG");
-   if (a->zout + len > a->zout_end)
-      if (!stbi__zexpand(a, a->zout, len)) return 0;
-   memcpy(a->zout, a->zbuffer, len);
-   a->zbuffer += len;
-   a->zout += len;
-   return 1;
-}
-
-static int stbi__parse_zlib_header(stbi__zbuf *a)
-{
-   int cmf   = stbi__zget8(a);
-   int cm    = cmf & 15;
-   /* int cinfo = cmf >> 4; */
-   int flg   = stbi__zget8(a);
-   if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
-   if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
-   if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
-   if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
-   // window = 1 << (8 + cinfo)... but who cares, we fully buffer output
-   return 1;
-}
-
-static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] =
-{
-   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,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, 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, 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,
-   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8
-};
-static const stbi_uc stbi__zdefault_distance[32] =
-{
-   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
-};
-/*
-Init algorithm:
-{
-   int i;   // use <= to match clearly with spec
-   for (i=0; i <= 143; ++i)     stbi__zdefault_length[i]   = 8;
-   for (   ; i <= 255; ++i)     stbi__zdefault_length[i]   = 9;
-   for (   ; i <= 279; ++i)     stbi__zdefault_length[i]   = 7;
-   for (   ; i <= 287; ++i)     stbi__zdefault_length[i]   = 8;
-
-   for (i=0; i <=  31; ++i)     stbi__zdefault_distance[i] = 5;
-}
-*/
-
-static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
-{
-   int final, type;
-   if (parse_header)
-      if (!stbi__parse_zlib_header(a)) return 0;
-   a->num_bits = 0;
-   a->code_buffer = 0;
-   a->hit_zeof_once = 0;
-   do {
-      final = stbi__zreceive(a,1);
-      type = stbi__zreceive(a,2);
-      if (type == 0) {
-         if (!stbi__parse_uncompressed_block(a)) return 0;
-      } else if (type == 3) {
-         return 0;
-      } else {
-         if (type == 1) {
-            // use fixed code lengths
-            if (!stbi__zbuild_huffman(&a->z_length  , stbi__zdefault_length  , STBI__ZNSYMS)) return 0;
-            if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance,  32)) return 0;
-         } else {
-            if (!stbi__compute_huffman_codes(a)) return 0;
-         }
-         if (!stbi__parse_huffman_block(a)) return 0;
-      }
-   } while (!final);
-   return 1;
-}
-
-static int stbi__do_zlib(stbi__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 stbi__parse_zlib(a, parse_header);
-}
-
-STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen)
-{
-   stbi__zbuf a;
-   char *p = (char *) stbi__malloc(initial_size);
-   if (p == NULL) return NULL;
-   a.zbuffer = (stbi_uc *) buffer;
-   a.zbuffer_end = (stbi_uc *) buffer + len;
-   if (stbi__do_zlib(&a, p, initial_size, 1, 1)) {
-      if (outlen) *outlen = (int) (a.zout - a.zout_start);
-      return a.zout_start;
-   } else {
-      STBI_FREE(a.zout_start);
-      return NULL;
-   }
-}
-
-STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen)
-{
-   return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen);
-}
-
-STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header)
-{
-   stbi__zbuf a;
-   char *p = (char *) stbi__malloc(initial_size);
-   if (p == NULL) return NULL;
-   a.zbuffer = (stbi_uc *) buffer;
-   a.zbuffer_end = (stbi_uc *) buffer + len;
-   if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) {
-      if (outlen) *outlen = (int) (a.zout - a.zout_start);
-      return a.zout_start;
-   } else {
-      STBI_FREE(a.zout_start);
-      return NULL;
-   }
-}
-
-STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen)
-{
-   stbi__zbuf a;
-   a.zbuffer = (stbi_uc *) ibuffer;
-   a.zbuffer_end = (stbi_uc *) ibuffer + ilen;
-   if (stbi__do_zlib(&a, obuffer, olen, 0, 1))
-      return (int) (a.zout - a.zout_start);
-   else
-      return -1;
-}
-
-STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen)
-{
-   stbi__zbuf a;
-   char *p = (char *) stbi__malloc(16384);
-   if (p == NULL) return NULL;
-   a.zbuffer = (stbi_uc *) buffer;
-   a.zbuffer_end = (stbi_uc *) buffer+len;
-   if (stbi__do_zlib(&a, p, 16384, 1, 0)) {
-      if (outlen) *outlen = (int) (a.zout - a.zout_start);
-      return a.zout_start;
-   } else {
-      STBI_FREE(a.zout_start);
-      return NULL;
-   }
-}
-
-STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen)
-{
-   stbi__zbuf a;
-   a.zbuffer = (stbi_uc *) ibuffer;
-   a.zbuffer_end = (stbi_uc *) ibuffer + ilen;
-   if (stbi__do_zlib(&a, obuffer, olen, 0, 0))
-      return (int) (a.zout - a.zout_start);
-   else
-      return -1;
-}
-#endif
-
-// 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
-
-#ifndef STBI_NO_PNG
-typedef struct
-{
-   stbi__uint32 length;
-   stbi__uint32 type;
-} stbi__pngchunk;
-
-static stbi__pngchunk stbi__get_chunk_header(stbi__context *s)
-{
-   stbi__pngchunk c;
-   c.length = stbi__get32be(s);
-   c.type   = stbi__get32be(s);
-   return c;
-}
-
-static int stbi__check_png_header(stbi__context *s)
-{
-   static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 };
-   int i;
-   for (i=0; i < 8; ++i)
-      if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG");
-   return 1;
-}
-
-typedef struct
-{
-   stbi__context *s;
-   stbi_uc *idata, *expanded, *out;
-   int depth;
-} stbi__png;
-
-
-enum {
-   STBI__F_none=0,
-   STBI__F_sub=1,
-   STBI__F_up=2,
-   STBI__F_avg=3,
-   STBI__F_paeth=4,
-   // synthetic filter used for first scanline to avoid needing a dummy row of 0s
-   STBI__F_avg_first
-};
-
-static stbi_uc first_row_filter[5] =
-{
-   STBI__F_none,
-   STBI__F_sub,
-   STBI__F_none,
-   STBI__F_avg_first,
-   STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub
-};
-
-static int stbi__paeth(int a, int b, int c)
-{
-   // This formulation looks very different from the reference in the PNG spec, but is
-   // actually equivalent and has favorable data dependencies and admits straightforward
-   // generation of branch-free code, which helps performance significantly.
-   int thresh = c*3 - (a + b);
-   int lo = a < b ? a : b;
-   int hi = a < b ? b : a;
-   int t0 = (hi <= thresh) ? lo : c;
-   int t1 = (thresh <= lo) ? hi : t0;
-   return t1;
-}
-
-static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
-
-// adds an extra all-255 alpha channel
-// dest == src is legal
-// img_n must be 1 or 3
-static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n)
-{
-   int i;
-   // must process data backwards since we allow dest==src
-   if (img_n == 1) {
-      for (i=x-1; i >= 0; --i) {
-         dest[i*2+1] = 255;
-         dest[i*2+0] = src[i];
-      }
-   } else {
-      STBI_ASSERT(img_n == 3);
-      for (i=x-1; i >= 0; --i) {
-         dest[i*4+3] = 255;
-         dest[i*4+2] = src[i*3+2];
-         dest[i*4+1] = src[i*3+1];
-         dest[i*4+0] = src[i*3+0];
-      }
-   }
-}
-
-// create the png data from post-deflated data
-static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
-{
-   int bytes = (depth == 16 ? 2 : 1);
-   stbi__context *s = a->s;
-   stbi__uint32 i,j,stride = x*out_n*bytes;
-   stbi__uint32 img_len, img_width_bytes;
-   stbi_uc *filter_buf;
-   int all_ok = 1;
-   int k;
-   int img_n = s->img_n; // copy it into a local for later
-
-   int output_bytes = out_n*bytes;
-   int filter_bytes = img_n*bytes;
-   int width = x;
-
-   STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
-   a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
-   if (!a->out) return stbi__err("outofmem", "Out of memory");
-
-   // note: error exits here don't need to clean up a->out individually,
-   // stbi__do_png always does on error.
-   if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
-   img_width_bytes = (((img_n * x * depth) + 7) >> 3);
-   if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG");
-   img_len = (img_width_bytes + 1) * y;
-
-   // we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
-   // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros),
-   // so just check for raw_len < img_len always.
-   if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
-
-   // Allocate two scan lines worth of filter workspace buffer.
-   filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0);
-   if (!filter_buf) return stbi__err("outofmem", "Out of memory");
-
-   // Filtering for low-bit-depth images
-   if (depth < 8) {
-      filter_bytes = 1;
-      width = img_width_bytes;
-   }
-
-   for (j=0; j < y; ++j) {
-      // cur/prior filter buffers alternate
-      stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes;
-      stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes;
-      stbi_uc *dest = a->out + stride*j;
-      int nk = width * filter_bytes;
-      int filter = *raw++;
-
-      // check filter type
-      if (filter > 4) {
-         all_ok = stbi__err("invalid filter","Corrupt PNG");
-         break;
-      }
-
-      // if first row, use special filter that doesn't sample previous row
-      if (j == 0) filter = first_row_filter[filter];
-
-      // perform actual filtering
-      switch (filter) {
-      case STBI__F_none:
-         memcpy(cur, raw, nk);
-         break;
-      case STBI__F_sub:
-         memcpy(cur, raw, filter_bytes);
-         for (k = filter_bytes; k < nk; ++k)
-            cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]);
-         break;
-      case STBI__F_up:
-         for (k = 0; k < nk; ++k)
-            cur[k] = STBI__BYTECAST(raw[k] + prior[k]);
-         break;
-      case STBI__F_avg:
-         for (k = 0; k < filter_bytes; ++k)
-            cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1));
-         for (k = filter_bytes; k < nk; ++k)
-            cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1));
-         break;
-      case STBI__F_paeth:
-         for (k = 0; k < filter_bytes; ++k)
-            cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0)
-         for (k = filter_bytes; k < nk; ++k)
-            cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes]));
-         break;
-      case STBI__F_avg_first:
-         memcpy(cur, raw, filter_bytes);
-         for (k = filter_bytes; k < nk; ++k)
-            cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1));
-         break;
-      }
-
-      raw += nk;
-
-      // expand decoded bits in cur to dest, also adding an extra alpha channel if desired
-      if (depth < 8) {
-         stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
-         stbi_uc *in = cur;
-         stbi_uc *out = dest;
-         stbi_uc inb = 0;
-         stbi__uint32 nsmp = x*img_n;
-
-         // expand bits to bytes first
-         if (depth == 4) {
-            for (i=0; i < nsmp; ++i) {
-               if ((i & 1) == 0) inb = *in++;
-               *out++ = scale * (inb >> 4);
-               inb <<= 4;
-            }
-         } else if (depth == 2) {
-            for (i=0; i < nsmp; ++i) {
-               if ((i & 3) == 0) inb = *in++;
-               *out++ = scale * (inb >> 6);
-               inb <<= 2;
-            }
-         } else {
-            STBI_ASSERT(depth == 1);
-            for (i=0; i < nsmp; ++i) {
-               if ((i & 7) == 0) inb = *in++;
-               *out++ = scale * (inb >> 7);
-               inb <<= 1;
-            }
-         }
-
-         // insert alpha=255 values if desired
-         if (img_n != out_n)
-            stbi__create_png_alpha_expand8(dest, dest, x, img_n);
-      } else if (depth == 8) {
-         if (img_n == out_n)
-            memcpy(dest, cur, x*img_n);
-         else
-            stbi__create_png_alpha_expand8(dest, cur, x, img_n);
-      } else if (depth == 16) {
-         // convert the image data from big-endian to platform-native
-         stbi__uint16 *dest16 = (stbi__uint16*)dest;
-         stbi__uint32 nsmp = x*img_n;
-
-         if (img_n == out_n) {
-            for (i = 0; i < nsmp; ++i, ++dest16, cur += 2)
-               *dest16 = (cur[0] << 8) | cur[1];
-         } else {
-            STBI_ASSERT(img_n+1 == out_n);
-            if (img_n == 1) {
-               for (i = 0; i < x; ++i, dest16 += 2, cur += 2) {
-                  dest16[0] = (cur[0] << 8) | cur[1];
-                  dest16[1] = 0xffff;
-               }
-            } else {
-               STBI_ASSERT(img_n == 3);
-               for (i = 0; i < x; ++i, dest16 += 4, cur += 6) {
-                  dest16[0] = (cur[0] << 8) | cur[1];
-                  dest16[1] = (cur[2] << 8) | cur[3];
-                  dest16[2] = (cur[4] << 8) | cur[5];
-                  dest16[3] = 0xffff;
-               }
-            }
-         }
-      }
-   }
-
-   STBI_FREE(filter_buf);
-   if (!all_ok) return 0;
-
-   return 1;
-}
-
-static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced)
-{
-   int bytes = (depth == 16 ? 2 : 1);
-   int out_bytes = out_n * bytes;
-   stbi_uc *final;
-   int p;
-   if (!interlaced)
-      return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color);
-
-   // de-interlacing
-   final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
-   if (!final) return stbi__err("outofmem", "Out of memory");
-   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) {
-         stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y;
-         if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) {
-            STBI_FREE(final);
-            return 0;
-         }
-         for (j=0; j < y; ++j) {
-            for (i=0; i < x; ++i) {
-               int out_y = j*yspc[p]+yorig[p];
-               int out_x = i*xspc[p]+xorig[p];
-               memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes,
-                      a->out + (j*x+i)*out_bytes, out_bytes);
-            }
-         }
-         STBI_FREE(a->out);
-         image_data += img_len;
-         image_data_len -= img_len;
-      }
-   }
-   a->out = final;
-
-   return 1;
-}
-
-static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
-{
-   stbi__context *s = z->s;
-   stbi__uint32 i, pixel_count = s->img_x * s->img_y;
-   stbi_uc *p = z->out;
-
-   // compute color-based transparency, assuming we've
-   // already got 255 as the alpha value in the output
-   STBI_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 stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n)
-{
-   stbi__context *s = z->s;
-   stbi__uint32 i, pixel_count = s->img_x * s->img_y;
-   stbi__uint16 *p = (stbi__uint16*) z->out;
-
-   // compute color-based transparency, assuming we've
-   // already got 65535 as the alpha value in the output
-   STBI_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 : 65535);
-         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 stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n)
-{
-   stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
-   stbi_uc *p, *temp_out, *orig = a->out;
-
-   p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0);
-   if (p == NULL) return stbi__err("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;
-      }
-   }
-   STBI_FREE(a->out);
-   a->out = temp_out;
-
-   STBI_NOTUSED(len);
-
-   return 1;
-}
-
-static int stbi__unpremultiply_on_load_global = 0;
-static int stbi__de_iphone_flag_global = 0;
-
-STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
-{
-   stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply;
-}
-
-STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
-{
-   stbi__de_iphone_flag_global = flag_true_if_should_convert;
-}
-
-#ifndef STBI_THREAD_LOCAL
-#define stbi__unpremultiply_on_load  stbi__unpremultiply_on_load_global
-#define stbi__de_iphone_flag  stbi__de_iphone_flag_global
-#else
-static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set;
-static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set;
-
-STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
-{
-   stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply;
-   stbi__unpremultiply_on_load_set = 1;
-}
-
-STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert)
-{
-   stbi__de_iphone_flag_local = flag_true_if_should_convert;
-   stbi__de_iphone_flag_set = 1;
-}
-
-#define stbi__unpremultiply_on_load  (stbi__unpremultiply_on_load_set           \
-                                       ? stbi__unpremultiply_on_load_local      \
-                                       : stbi__unpremultiply_on_load_global)
-#define stbi__de_iphone_flag  (stbi__de_iphone_flag_set                         \
-                                ? stbi__de_iphone_flag_local                    \
-                                : stbi__de_iphone_flag_global)
-#endif // STBI_THREAD_LOCAL
-
-static void stbi__de_iphone(stbi__png *z)
-{
-   stbi__context *s = z->s;
-   stbi__uint32 i, pixel_count = s->img_x * s->img_y;
-   stbi_uc *p = z->out;
-
-   if (s->img_out_n == 3) {  // convert bgr to rgb
-      for (i=0; i < pixel_count; ++i) {
-         stbi_uc t = p[0];
-         p[0] = p[2];
-         p[2] = t;
-         p += 3;
-      }
-   } else {
-      STBI_ASSERT(s->img_out_n == 4);
-      if (stbi__unpremultiply_on_load) {
-         // convert bgr to rgb and unpremultiply
-         for (i=0; i < pixel_count; ++i) {
-            stbi_uc a = p[3];
-            stbi_uc t = p[0];
-            if (a) {
-               stbi_uc half = a / 2;
-               p[0] = (p[2] * 255 + half) / a;
-               p[1] = (p[1] * 255 + half) / a;
-               p[2] = ( t   * 255 + half) / a;
-            } else {
-               p[0] = p[2];
-               p[2] = t;
-            }
-            p += 4;
-         }
-      } else {
-         // convert bgr to rgb
-         for (i=0; i < pixel_count; ++i) {
-            stbi_uc t = p[0];
-            p[0] = p[2];
-            p[2] = t;
-            p += 4;
-         }
-      }
-   }
-}
-
-#define STBI__PNG_TYPE(a,b,c,d)  (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d))
-
-static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
-{
-   stbi_uc palette[1024], pal_img_n=0;
-   stbi_uc has_trans=0, tc[3]={0};
-   stbi__uint16 tc16[3];
-   stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
-   int first=1,k,interlace=0, color=0, is_iphone=0;
-   stbi__context *s = z->s;
-
-   z->expanded = NULL;
-   z->idata = NULL;
-   z->out = NULL;
-
-   if (!stbi__check_png_header(s)) return 0;
-
-   if (scan == STBI__SCAN_type) return 1;
-
-   for (;;) {
-      stbi__pngchunk c = stbi__get_chunk_header(s);
-      switch (c.type) {
-         case STBI__PNG_TYPE('C','g','B','I'):
-            is_iphone = 1;
-            stbi__skip(s, c.length);
-            break;
-         case STBI__PNG_TYPE('I','H','D','R'): {
-            int comp,filter;
-            if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
-            first = 0;
-            if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
-            s->img_x = stbi__get32be(s);
-            s->img_y = stbi__get32be(s);
-            if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
-            if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
-            z->depth = stbi__get8(s);  if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16)  return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
-            color = stbi__get8(s);  if (color > 6)         return stbi__err("bad ctype","Corrupt PNG");
-            if (color == 3 && z->depth == 16)                  return stbi__err("bad ctype","Corrupt PNG");
-            if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
-            comp  = stbi__get8(s);  if (comp) return stbi__err("bad comp method","Corrupt PNG");
-            filter= stbi__get8(s);  if (filter) return stbi__err("bad filter method","Corrupt PNG");
-            interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG");
-            if (!s->img_x || !s->img_y) return stbi__err("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 stbi__err("too large", "Image too large to decode");
-            } 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 stbi__err("too large","Corrupt PNG");
-            }
-            // even with SCAN_header, have to scan to see if we have a tRNS
-            break;
-         }
-
-         case STBI__PNG_TYPE('P','L','T','E'):  {
-            if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-            if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG");
-            pal_len = c.length / 3;
-            if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG");
-            for (i=0; i < pal_len; ++i) {
-               palette[i*4+0] = stbi__get8(s);
-               palette[i*4+1] = stbi__get8(s);
-               palette[i*4+2] = stbi__get8(s);
-               palette[i*4+3] = 255;
-            }
-            break;
-         }
-
-         case STBI__PNG_TYPE('t','R','N','S'): {
-            if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-            if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG");
-            if (pal_img_n) {
-               if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; }
-               if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG");
-               if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG");
-               pal_img_n = 4;
-               for (i=0; i < c.length; ++i)
-                  palette[i*4+3] = stbi__get8(s);
-            } else {
-               if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
-               if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
-               has_trans = 1;
-               // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now.
-               if (scan == STBI__SCAN_header) { ++s->img_n; return 1; }
-               if (z->depth == 16) {
-                  for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning
-                     tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
-               } else {
-                  for (k = 0; k < s->img_n && k < 3; ++k)
-                     tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
-               }
-            }
-            break;
-         }
-
-         case STBI__PNG_TYPE('I','D','A','T'): {
-            if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-            if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
-            if (scan == STBI__SCAN_header) {
-               // header scan definitely stops at first IDAT
-               if (pal_img_n)
-                  s->img_n = pal_img_n;
-               return 1;
-            }
-            if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes");
-            if ((int)(ioff + c.length) < (int)ioff) return 0;
-            if (ioff + c.length > idata_limit) {
-               stbi__uint32 idata_limit_old = idata_limit;
-               stbi_uc *p;
-               if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
-               while (ioff + c.length > idata_limit)
-                  idata_limit *= 2;
-               STBI_NOTUSED(idata_limit_old);
-               p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
-               z->idata = p;
-            }
-            if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG");
-            ioff += c.length;
-            break;
-         }
-
-         case STBI__PNG_TYPE('I','E','N','D'): {
-            stbi__uint32 raw_len, bpl;
-            if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-            if (scan != STBI__SCAN_load) return 1;
-            if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
-            // initial guess for decoded data size to avoid unnecessary reallocs
-            bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
-            raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
-            z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
-            if (z->expanded == NULL) return 0; // zlib should set error
-            STBI_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 (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
-            if (has_trans) {
-               if (z->depth == 16) {
-                  if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0;
-               } else {
-                  if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
-               }
-            }
-            if (is_iphone && stbi__de_iphone_flag && 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 (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n))
-                  return 0;
-            } else if (has_trans) {
-               // non-paletted image with tRNS -> source image has (constant) alpha
-               ++s->img_n;
-            }
-            STBI_FREE(z->expanded); z->expanded = NULL;
-            // end of PNG chunk, read and skip CRC
-            stbi__get32be(s);
-            return 1;
-         }
-
-         default:
-            // if critical, fail
-            if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-            if ((c.type & (1 << 29)) == 0) {
-               #ifndef STBI_NO_FAILURE_STRINGS
-               // not threadsafe
-               static char invalid_chunk[] = "XXXX PNG chunk not known";
-               invalid_chunk[0] = STBI__BYTECAST(c.type >> 24);
-               invalid_chunk[1] = STBI__BYTECAST(c.type >> 16);
-               invalid_chunk[2] = STBI__BYTECAST(c.type >>  8);
-               invalid_chunk[3] = STBI__BYTECAST(c.type >>  0);
-               #endif
-               return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type");
-            }
-            stbi__skip(s, c.length);
-            break;
-      }
-      // end of PNG chunk, read and skip CRC
-      stbi__get32be(s);
-   }
-}
-
-static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri)
-{
-   void *result=NULL;
-   if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
-   if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
-      if (p->depth <= 8)
-         ri->bits_per_channel = 8;
-      else if (p->depth == 16)
-         ri->bits_per_channel = 16;
-      else
-         return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth");
-      result = p->out;
-      p->out = NULL;
-      if (req_comp && req_comp != p->s->img_out_n) {
-         if (ri->bits_per_channel == 8)
-            result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
-         else
-            result = stbi__convert_format16((stbi__uint16 *) 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;
-   }
-   STBI_FREE(p->out);      p->out      = NULL;
-   STBI_FREE(p->expanded); p->expanded = NULL;
-   STBI_FREE(p->idata);    p->idata    = NULL;
-
-   return result;
-}
-
-static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   stbi__png p;
-   p.s = s;
-   return stbi__do_png(&p, x,y,comp,req_comp, ri);
-}
-
-static int stbi__png_test(stbi__context *s)
-{
-   int r;
-   r = stbi__check_png_header(s);
-   stbi__rewind(s);
-   return r;
-}
-
-static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp)
-{
-   if (!stbi__parse_png_file(p, STBI__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__context *s, int *x, int *y, int *comp)
-{
-   stbi__png p;
-   p.s = s;
-   return stbi__png_info_raw(&p, x, y, comp);
-}
-
-static int stbi__png_is16(stbi__context *s)
-{
-   stbi__png p;
-   p.s = s;
-   if (!stbi__png_info_raw(&p, NULL, NULL, NULL))
-	   return 0;
-   if (p.depth != 16) {
-      stbi__rewind(p.s);
-      return 0;
-   }
-   return 1;
-}
-#endif
-
-// Microsoft/Windows BMP image
-
-#ifndef STBI_NO_BMP
-static int stbi__bmp_test_raw(stbi__context *s)
-{
-   int r;
-   int sz;
-   if (stbi__get8(s) != 'B') return 0;
-   if (stbi__get8(s) != 'M') return 0;
-   stbi__get32le(s); // discard filesize
-   stbi__get16le(s); // discard reserved
-   stbi__get16le(s); // discard reserved
-   stbi__get32le(s); // discard data offset
-   sz = stbi__get32le(s);
-   r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124);
-   return r;
-}
-
-static int stbi__bmp_test(stbi__context *s)
-{
-   int r = stbi__bmp_test_raw(s);
-   stbi__rewind(s);
-   return r;
-}
-
-
-// returns 0..31 for the highest set bit
-static int stbi__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;/* >>=  1;*/ }
-   return n;
-}
-
-static int stbi__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;
-}
-
-// extract an arbitrarily-aligned N-bit value (N=bits)
-// from v, and then make it 8-bits long and fractionally
-// extend it to full full range.
-static int stbi__shiftsigned(unsigned int v, int shift, int bits)
-{
-   static unsigned int mul_table[9] = {
-      0,
-      0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/,
-      0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/,
-   };
-   static unsigned int shift_table[9] = {
-      0, 0,0,1,0,2,4,6,0,
-   };
-   if (shift < 0)
-      v <<= -shift;
-   else
-      v >>= shift;
-   STBI_ASSERT(v < 256);
-   v >>= (8-bits);
-   STBI_ASSERT(bits >= 0 && bits <= 8);
-   return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
-}
-
-typedef struct
-{
-   int bpp, offset, hsz;
-   unsigned int mr,mg,mb,ma, all_a;
-   int extra_read;
-} stbi__bmp_data;
-
-static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress)
-{
-   // BI_BITFIELDS specifies masks explicitly, don't override
-   if (compress == 3)
-      return 1;
-
-   if (compress == 0) {
-      if (info->bpp == 16) {
-         info->mr = 31u << 10;
-         info->mg = 31u <<  5;
-         info->mb = 31u <<  0;
-      } else if (info->bpp == 32) {
-         info->mr = 0xffu << 16;
-         info->mg = 0xffu <<  8;
-         info->mb = 0xffu <<  0;
-         info->ma = 0xffu << 24;
-         info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
-      } else {
-         // otherwise, use defaults, which is all-0
-         info->mr = info->mg = info->mb = info->ma = 0;
-      }
-      return 1;
-   }
-   return 0; // error
-}
-
-static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
-{
-   int hsz;
-   if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP");
-   stbi__get32le(s); // discard filesize
-   stbi__get16le(s); // discard reserved
-   stbi__get16le(s); // discard reserved
-   info->offset = stbi__get32le(s);
-   info->hsz = hsz = stbi__get32le(s);
-   info->mr = info->mg = info->mb = info->ma = 0;
-   info->extra_read = 14;
-
-   if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP");
-
-   if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
-   if (hsz == 12) {
-      s->img_x = stbi__get16le(s);
-      s->img_y = stbi__get16le(s);
-   } else {
-      s->img_x = stbi__get32le(s);
-      s->img_y = stbi__get32le(s);
-   }
-   if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP");
-   info->bpp = stbi__get16le(s);
-   if (hsz != 12) {
-      int compress = stbi__get32le(s);
-      if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
-      if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes
-      if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel
-      stbi__get32le(s); // discard sizeof
-      stbi__get32le(s); // discard hres
-      stbi__get32le(s); // discard vres
-      stbi__get32le(s); // discard colorsused
-      stbi__get32le(s); // discard max important
-      if (hsz == 40 || hsz == 56) {
-         if (hsz == 56) {
-            stbi__get32le(s);
-            stbi__get32le(s);
-            stbi__get32le(s);
-            stbi__get32le(s);
-         }
-         if (info->bpp == 16 || info->bpp == 32) {
-            if (compress == 0) {
-               stbi__bmp_set_mask_defaults(info, compress);
-            } else if (compress == 3) {
-               info->mr = stbi__get32le(s);
-               info->mg = stbi__get32le(s);
-               info->mb = stbi__get32le(s);
-               info->extra_read += 12;
-               // not documented, but generated by photoshop and handled by mspaint
-               if (info->mr == info->mg && info->mg == info->mb) {
-                  // ?!?!?
-                  return stbi__errpuc("bad BMP", "bad BMP");
-               }
-            } else
-               return stbi__errpuc("bad BMP", "bad BMP");
-         }
-      } else {
-         // V4/V5 header
-         int i;
-         if (hsz != 108 && hsz != 124)
-            return stbi__errpuc("bad BMP", "bad BMP");
-         info->mr = stbi__get32le(s);
-         info->mg = stbi__get32le(s);
-         info->mb = stbi__get32le(s);
-         info->ma = stbi__get32le(s);
-         if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs
-            stbi__bmp_set_mask_defaults(info, compress);
-         stbi__get32le(s); // discard color space
-         for (i=0; i < 12; ++i)
-            stbi__get32le(s); // discard color space parameters
-         if (hsz == 124) {
-            stbi__get32le(s); // discard rendering intent
-            stbi__get32le(s); // discard offset of profile data
-            stbi__get32le(s); // discard size of profile data
-            stbi__get32le(s); // discard reserved
-         }
-      }
-   }
-   return (void *) 1;
-}
-
-
-static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   stbi_uc *out;
-   unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
-   stbi_uc pal[256][4];
-   int psize=0,i,j,width;
-   int flip_vertically, pad, target;
-   stbi__bmp_data info;
-   STBI_NOTUSED(ri);
-
-   info.all_a = 255;
-   if (stbi__bmp_parse_header(s, &info) == NULL)
-      return NULL; // error code already set
-
-   flip_vertically = ((int) s->img_y) > 0;
-   s->img_y = abs((int) s->img_y);
-
-   if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-   if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-
-   mr = info.mr;
-   mg = info.mg;
-   mb = info.mb;
-   ma = info.ma;
-   all_a = info.all_a;
-
-   if (info.hsz == 12) {
-      if (info.bpp < 24)
-         psize = (info.offset - info.extra_read - 24) / 3;
-   } else {
-      if (info.bpp < 16)
-         psize = (info.offset - info.extra_read - info.hsz) >> 2;
-   }
-   if (psize == 0) {
-      // accept some number of extra bytes after the header, but if the offset points either to before
-      // the header ends or implies a large amount of extra data, reject the file as malformed
-      int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original);
-      int header_limit = 1024; // max we actually read is below 256 bytes currently.
-      int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size.
-      if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) {
-         return stbi__errpuc("bad header", "Corrupt BMP");
-      }
-      // we established that bytes_read_so_far is positive and sensible.
-      // the first half of this test rejects offsets that are either too small positives, or
-      // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn
-      // ensures the number computed in the second half of the test can't overflow.
-      if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) {
-         return stbi__errpuc("bad offset", "Corrupt BMP");
-      } else {
-         stbi__skip(s, info.offset - bytes_read_so_far);
-      }
-   }
-
-   if (info.bpp == 24 && ma == 0xff000000)
-      s->img_n = 3;
-   else
-      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
-
-   // sanity-check size
-   if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0))
-      return stbi__errpuc("too large", "Corrupt BMP");
-
-   out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0);
-   if (!out) return stbi__errpuc("outofmem", "Out of memory");
-   if (info.bpp < 16) {
-      int z=0;
-      if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); }
-      for (i=0; i < psize; ++i) {
-         pal[i][2] = stbi__get8(s);
-         pal[i][1] = stbi__get8(s);
-         pal[i][0] = stbi__get8(s);
-         if (info.hsz != 12) stbi__get8(s);
-         pal[i][3] = 255;
-      }
-      stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
-      if (info.bpp == 1) width = (s->img_x + 7) >> 3;
-      else if (info.bpp == 4) width = (s->img_x + 1) >> 1;
-      else if (info.bpp == 8) width = s->img_x;
-      else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); }
-      pad = (-width)&3;
-      if (info.bpp == 1) {
-         for (j=0; j < (int) s->img_y; ++j) {
-            int bit_offset = 7, v = stbi__get8(s);
-            for (i=0; i < (int) s->img_x; ++i) {
-               int color = (v>>bit_offset)&0x1;
-               out[z++] = pal[color][0];
-               out[z++] = pal[color][1];
-               out[z++] = pal[color][2];
-               if (target == 4) out[z++] = 255;
-               if (i+1 == (int) s->img_x) break;
-               if((--bit_offset) < 0) {
-                  bit_offset = 7;
-                  v = stbi__get8(s);
-               }
-            }
-            stbi__skip(s, pad);
-         }
-      } else {
-         for (j=0; j < (int) s->img_y; ++j) {
-            for (i=0; i < (int) s->img_x; i += 2) {
-               int v=stbi__get8(s),v2=0;
-               if (info.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 = (info.bpp == 8) ? stbi__get8(s) : v2;
-               out[z++] = pal[v][0];
-               out[z++] = pal[v][1];
-               out[z++] = pal[v][2];
-               if (target == 4) out[z++] = 255;
-            }
-            stbi__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;
-      stbi__skip(s, info.offset - info.extra_read - info.hsz);
-      if (info.bpp == 24) width = 3 * s->img_x;
-      else if (info.bpp == 16) width = 2*s->img_x;
-      else /* bpp = 32 and pad = 0 */ width=0;
-      pad = (-width) & 3;
-      if (info.bpp == 24) {
-         easy = 1;
-      } else if (info.bpp == 32) {
-         if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
-            easy = 2;
-      }
-      if (!easy) {
-         if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
-         // right shift amt to put high bit in position #7
-         rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr);
-         gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
-         bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
-         ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
-         if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
-      }
-      for (j=0; j < (int) s->img_y; ++j) {
-         if (easy) {
-            for (i=0; i < (int) s->img_x; ++i) {
-               unsigned char a;
-               out[z+2] = stbi__get8(s);
-               out[z+1] = stbi__get8(s);
-               out[z+0] = stbi__get8(s);
-               z += 3;
-               a = (easy == 2 ? stbi__get8(s) : 255);
-               all_a |= a;
-               if (target == 4) out[z++] = a;
-            }
-         } else {
-            int bpp = info.bpp;
-            for (i=0; i < (int) s->img_x; ++i) {
-               stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
-               unsigned int a;
-               out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
-               out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
-               out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount));
-               a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255);
-               all_a |= a;
-               if (target == 4) out[z++] = STBI__BYTECAST(a);
-            }
-         }
-         stbi__skip(s, pad);
-      }
-   }
-
-   // if alpha channel is all 0s, replace with all 255s
-   if (target == 4 && all_a == 0)
-      for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
-         out[i] = 255;
-
-   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 = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y);
-      if (out == NULL) return out; // stbi__convert_format frees input on failure
-   }
-
-   *x = s->img_x;
-   *y = s->img_y;
-   if (comp) *comp = s->img_n;
-   return out;
-}
-#endif
-
-// Targa Truevision - TGA
-// by Jonathan Dummer
-#ifndef STBI_NO_TGA
-// returns STBI_rgb or whatever, 0 on error
-static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
-{
-   // only RGB or RGBA (incl. 16bit) or grey allowed
-   if (is_rgb16) *is_rgb16 = 0;
-   switch(bits_per_pixel) {
-      case 8:  return STBI_grey;
-      case 16: if(is_grey) return STBI_grey_alpha;
-               // fallthrough
-      case 15: if(is_rgb16) *is_rgb16 = 1;
-               return STBI_rgb;
-      case 24: // fallthrough
-      case 32: return bits_per_pixel/8;
-      default: return 0;
-   }
-}
-
-static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
-{
-    int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
-    int sz, tga_colormap_type;
-    stbi__get8(s);                   // discard Offset
-    tga_colormap_type = stbi__get8(s); // colormap type
-    if( tga_colormap_type > 1 ) {
-        stbi__rewind(s);
-        return 0;      // only RGB or indexed allowed
-    }
-    tga_image_type = stbi__get8(s); // image type
-    if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
-        if (tga_image_type != 1 && tga_image_type != 9) {
-            stbi__rewind(s);
-            return 0;
-        }
-        stbi__skip(s,4);       // skip index of first colormap entry and number of entries
-        sz = stbi__get8(s);    //   check bits per palette color entry
-        if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) {
-            stbi__rewind(s);
-            return 0;
-        }
-        stbi__skip(s,4);       // skip image x and y origin
-        tga_colormap_bpp = sz;
-    } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
-        if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) {
-            stbi__rewind(s);
-            return 0; // only RGB or grey allowed, +/- RLE
-        }
-        stbi__skip(s,9); // skip colormap specification and image x/y origin
-        tga_colormap_bpp = 0;
-    }
-    tga_w = stbi__get16le(s);
-    if( tga_w < 1 ) {
-        stbi__rewind(s);
-        return 0;   // test width
-    }
-    tga_h = stbi__get16le(s);
-    if( tga_h < 1 ) {
-        stbi__rewind(s);
-        return 0;   // test height
-    }
-    tga_bits_per_pixel = stbi__get8(s); // bits per pixel
-    stbi__get8(s); // ignore alpha bits
-    if (tga_colormap_bpp != 0) {
-        if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
-            // when using a colormap, tga_bits_per_pixel is the size of the indexes
-            // I don't think anything but 8 or 16bit indexes makes sense
-            stbi__rewind(s);
-            return 0;
-        }
-        tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
-    } else {
-        tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
-    }
-    if(!tga_comp) {
-      stbi__rewind(s);
-      return 0;
-    }
-    if (x) *x = tga_w;
-    if (y) *y = tga_h;
-    if (comp) *comp = tga_comp;
-    return 1;                   // seems to have passed everything
-}
-
-static int stbi__tga_test(stbi__context *s)
-{
-   int res = 0;
-   int sz, tga_color_type;
-   stbi__get8(s);      //   discard Offset
-   tga_color_type = stbi__get8(s);   //   color type
-   if ( tga_color_type > 1 ) goto errorEnd;   //   only RGB or indexed allowed
-   sz = stbi__get8(s);   //   image type
-   if ( tga_color_type == 1 ) { // colormapped (paletted) image
-      if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
-      stbi__skip(s,4);       // skip index of first colormap entry and number of entries
-      sz = stbi__get8(s);    //   check bits per palette color entry
-      if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
-      stbi__skip(s,4);       // skip image x and y origin
-   } else { // "normal" image w/o colormap
-      if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE
-      stbi__skip(s,9); // skip colormap specification and image x/y origin
-   }
-   if ( stbi__get16le(s) < 1 ) goto errorEnd;      //   test width
-   if ( stbi__get16le(s) < 1 ) goto errorEnd;      //   test height
-   sz = stbi__get8(s);   //   bits per pixel
-   if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
-   if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
-
-   res = 1; // if we got this far, everything's good and we can return 1 instead of 0
-
-errorEnd:
-   stbi__rewind(s);
-   return res;
-}
-
-// read 16bit value and convert to 24bit RGB
-static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
-{
-   stbi__uint16 px = (stbi__uint16)stbi__get16le(s);
-   stbi__uint16 fiveBitMask = 31;
-   // we have 3 channels with 5bits each
-   int r = (px >> 10) & fiveBitMask;
-   int g = (px >> 5) & fiveBitMask;
-   int b = px & fiveBitMask;
-   // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
-   out[0] = (stbi_uc)((r * 255)/31);
-   out[1] = (stbi_uc)((g * 255)/31);
-   out[2] = (stbi_uc)((b * 255)/31);
-
-   // some people claim that the most significant bit might be used for alpha
-   // (possibly if an alpha-bit is set in the "image descriptor byte")
-   // but that only made 16bit test images completely translucent..
-   // so let's treat all 15 and 16bit TGAs as RGB with no alpha.
-}
-
-static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   //   read in the TGA header stuff
-   int tga_offset = stbi__get8(s);
-   int tga_indexed = stbi__get8(s);
-   int tga_image_type = stbi__get8(s);
-   int tga_is_RLE = 0;
-   int tga_palette_start = stbi__get16le(s);
-   int tga_palette_len = stbi__get16le(s);
-   int tga_palette_bits = stbi__get8(s);
-   int tga_x_origin = stbi__get16le(s);
-   int tga_y_origin = stbi__get16le(s);
-   int tga_width = stbi__get16le(s);
-   int tga_height = stbi__get16le(s);
-   int tga_bits_per_pixel = stbi__get8(s);
-   int tga_comp, tga_rgb16=0;
-   int tga_inverted = stbi__get8(s);
-   // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
-   //   image data
-   unsigned char *tga_data;
-   unsigned char *tga_palette = NULL;
-   int i, j;
-   unsigned char raw_data[4] = {0};
-   int RLE_count = 0;
-   int RLE_repeating = 0;
-   int read_next_pixel = 1;
-   STBI_NOTUSED(ri);
-   STBI_NOTUSED(tga_x_origin); // @TODO
-   STBI_NOTUSED(tga_y_origin); // @TODO
-
-   if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-   if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-
-   //   do a tiny bit of precessing
-   if ( tga_image_type >= 8 )
-   {
-      tga_image_type -= 8;
-      tga_is_RLE = 1;
-   }
-   tga_inverted = 1 - ((tga_inverted >> 5) & 1);
-
-   //   If I'm paletted, then I'll use the number of bits from the palette
-   if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
-   else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
-
-   if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
-      return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
-
-   //   tga info
-   *x = tga_width;
-   *y = tga_height;
-   if (comp) *comp = tga_comp;
-
-   if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0))
-      return stbi__errpuc("too large", "Corrupt TGA");
-
-   tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
-   if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
-
-   // skip to the data's starting position (offset usually = 0)
-   stbi__skip(s, tga_offset );
-
-   if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) {
-      for (i=0; i < tga_height; ++i) {
-         int row = tga_inverted ? tga_height -i - 1 : i;
-         stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
-         stbi__getn(s, tga_row, tga_width * tga_comp);
-      }
-   } else  {
-      //   do I need to load a palette?
-      if ( tga_indexed)
-      {
-         if (tga_palette_len == 0) {  /* you have to have at least one entry! */
-            STBI_FREE(tga_data);
-            return stbi__errpuc("bad palette", "Corrupt TGA");
-         }
-
-         //   any data to skip? (offset usually = 0)
-         stbi__skip(s, tga_palette_start );
-         //   load the palette
-         tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);
-         if (!tga_palette) {
-            STBI_FREE(tga_data);
-            return stbi__errpuc("outofmem", "Out of memory");
-         }
-         if (tga_rgb16) {
-            stbi_uc *pal_entry = tga_palette;
-            STBI_ASSERT(tga_comp == STBI_rgb);
-            for (i=0; i < tga_palette_len; ++i) {
-               stbi__tga_read_rgb16(s, pal_entry);
-               pal_entry += tga_comp;
-            }
-         } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
-               STBI_FREE(tga_data);
-               STBI_FREE(tga_palette);
-               return stbi__errpuc("bad palette", "Corrupt TGA");
-         }
-      }
-      //   load the data
-      for (i=0; i < tga_width * tga_height; ++i)
-      {
-         //   if I'm in RLE mode, do I need to get a RLE stbi__pngchunk?
-         if ( tga_is_RLE )
-         {
-            if ( RLE_count == 0 )
-            {
-               //   yep, get the next byte as a RLE command
-               int RLE_cmd = stbi__get8(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 index, then perform the lookup
-               int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
-               if ( pal_idx >= tga_palette_len ) {
-                  // invalid index
-                  pal_idx = 0;
-               }
-               pal_idx *= tga_comp;
-               for (j = 0; j < tga_comp; ++j) {
-                  raw_data[j] = tga_palette[pal_idx+j];
-               }
-            } else if(tga_rgb16) {
-               STBI_ASSERT(tga_comp == STBI_rgb);
-               stbi__tga_read_rgb16(s, raw_data);
-            } else {
-               //   read in the data raw
-               for (j = 0; j < tga_comp; ++j) {
-                  raw_data[j] = stbi__get8(s);
-               }
-            }
-            //   clear the reading flag for the next pixel
-            read_next_pixel = 0;
-         } // end of reading a pixel
-
-         // copy data
-         for (j = 0; j < tga_comp; ++j)
-           tga_data[i*tga_comp+j] = raw_data[j];
-
-         //   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 * tga_comp;
-            int index2 = (tga_height - 1 - j) * tga_width * tga_comp;
-            for (i = tga_width * tga_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 )
-      {
-         STBI_FREE( tga_palette );
-      }
-   }
-
-   // swap RGB - if the source data was RGB16, it already is in the right order
-   if (tga_comp >= 3 && !tga_rgb16)
-   {
-      unsigned char* tga_pixel = tga_data;
-      for (i=0; i < tga_width * tga_height; ++i)
-      {
-         unsigned char temp = tga_pixel[0];
-         tga_pixel[0] = tga_pixel[2];
-         tga_pixel[2] = temp;
-         tga_pixel += tga_comp;
-      }
-   }
-
-   // convert to target component count
-   if (req_comp && req_comp != tga_comp)
-      tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height);
-
-   //   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;
-   STBI_NOTUSED(tga_palette_start);
-   //   OK, done
-   return tga_data;
-}
-#endif
-
-// *************************************************************************************************
-// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB
-
-#ifndef STBI_NO_PSD
-static int stbi__psd_test(stbi__context *s)
-{
-   int r = (stbi__get32be(s) == 0x38425053);
-   stbi__rewind(s);
-   return r;
-}
-
-static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount)
-{
-   int count, nleft, len;
-
-   count = 0;
-   while ((nleft = pixelCount - count) > 0) {
-      len = stbi__get8(s);
-      if (len == 128) {
-         // No-op.
-      } else if (len < 128) {
-         // Copy next len+1 bytes literally.
-         len++;
-         if (len > nleft) return 0; // corrupt data
-         count += len;
-         while (len) {
-            *p = stbi__get8(s);
-            p += 4;
-            len--;
-         }
-      } else if (len > 128) {
-         stbi_uc   val;
-         // Next -len+1 bytes in the dest are replicated from next source byte.
-         // (Interpret len as a negative 8-bit int.)
-         len = 257 - len;
-         if (len > nleft) return 0; // corrupt data
-         val = stbi__get8(s);
-         count += len;
-         while (len) {
-            *p = val;
-            p += 4;
-            len--;
-         }
-      }
-   }
-
-   return 1;
-}
-
-static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
-{
-   int pixelCount;
-   int channelCount, compression;
-   int channel, i;
-   int bitdepth;
-   int w,h;
-   stbi_uc *out;
-   STBI_NOTUSED(ri);
-
-   // Check identifier
-   if (stbi__get32be(s) != 0x38425053)   // "8BPS"
-      return stbi__errpuc("not PSD", "Corrupt PSD image");
-
-   // Check file type version.
-   if (stbi__get16be(s) != 1)
-      return stbi__errpuc("wrong version", "Unsupported version of PSD image");
-
-   // Skip 6 reserved bytes.
-   stbi__skip(s, 6 );
-
-   // Read the number of channels (R, G, B, A, etc).
-   channelCount = stbi__get16be(s);
-   if (channelCount < 0 || channelCount > 16)
-      return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image");
-
-   // Read the rows and columns of the image.
-   h = stbi__get32be(s);
-   w = stbi__get32be(s);
-
-   if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-   if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-
-   // Make sure the depth is 8 bits.
-   bitdepth = stbi__get16be(s);
-   if (bitdepth != 8 && bitdepth != 16)
-      return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 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 (stbi__get16be(s) != 3)
-      return stbi__errpuc("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.)
-   stbi__skip(s,stbi__get32be(s) );
-
-   // Skip the image resources.  (resolution, pen tool paths, etc)
-   stbi__skip(s, stbi__get32be(s) );
-
-   // Skip the reserved data.
-   stbi__skip(s, stbi__get32be(s) );
-
-   // Find out if the data is compressed.
-   // Known values:
-   //   0: no compression
-   //   1: RLE compressed
-   compression = stbi__get16be(s);
-   if (compression > 1)
-      return stbi__errpuc("bad compression", "PSD has an unknown compression format");
-
-   // Check size
-   if (!stbi__mad3sizes_valid(4, w, h, 0))
-      return stbi__errpuc("too large", "Corrupt PSD");
-
-   // Create the destination image.
-
-   if (!compression && bitdepth == 16 && bpc == 16) {
-      out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0);
-      ri->bits_per_channel = 16;
-   } else
-      out = (stbi_uc *) stbi__malloc(4 * w*h);
-
-   if (!out) return stbi__errpuc("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 preceded by a 2-byte data count for each row in the data,
-      // which we're going to just skip.
-      stbi__skip(s, h * channelCount * 2 );
-
-      // Read the RLE data by channel.
-      for (channel = 0; channel < 4; channel++) {
-         stbi_uc *p;
-
-         p = out+channel;
-         if (channel >= channelCount) {
-            // Fill this channel with default data.
-            for (i = 0; i < pixelCount; i++, p += 4)
-               *p = (channel == 3 ? 255 : 0);
-         } else {
-            // Read the RLE data.
-            if (!stbi__psd_decode_rle(s, p, pixelCount)) {
-               STBI_FREE(out);
-               return stbi__errpuc("corrupt", "bad RLE data");
-            }
-         }
-      }
-
-   } 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 (or 16-bit) value for each pixel in the image.
-
-      // Read the data by channel.
-      for (channel = 0; channel < 4; channel++) {
-         if (channel >= channelCount) {
-            // Fill this channel with default data.
-            if (bitdepth == 16 && bpc == 16) {
-               stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
-               stbi__uint16 val = channel == 3 ? 65535 : 0;
-               for (i = 0; i < pixelCount; i++, q += 4)
-                  *q = val;
-            } else {
-               stbi_uc *p = out+channel;
-               stbi_uc val = channel == 3 ? 255 : 0;
-               for (i = 0; i < pixelCount; i++, p += 4)
-                  *p = val;
-            }
-         } else {
-            if (ri->bits_per_channel == 16) {    // output bpc
-               stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
-               for (i = 0; i < pixelCount; i++, q += 4)
-                  *q = (stbi__uint16) stbi__get16be(s);
-            } else {
-               stbi_uc *p = out+channel;
-               if (bitdepth == 16) {  // input bpc
-                  for (i = 0; i < pixelCount; i++, p += 4)
-                     *p = (stbi_uc) (stbi__get16be(s) >> 8);
-               } else {
-                  for (i = 0; i < pixelCount; i++, p += 4)
-                     *p = stbi__get8(s);
-               }
-            }
-         }
-      }
-   }
-
-   // remove weird white matte from PSD
-   if (channelCount >= 4) {
-      if (ri->bits_per_channel == 16) {
-         for (i=0; i < w*h; ++i) {
-            stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i;
-            if (pixel[3] != 0 && pixel[3] != 65535) {
-               float a = pixel[3] / 65535.0f;
-               float ra = 1.0f / a;
-               float inv_a = 65535.0f * (1 - ra);
-               pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a);
-               pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a);
-               pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a);
-            }
-         }
-      } else {
-         for (i=0; i < w*h; ++i) {
-            unsigned char *pixel = out + 4*i;
-            if (pixel[3] != 0 && pixel[3] != 255) {
-               float a = pixel[3] / 255.0f;
-               float ra = 1.0f / a;
-               float inv_a = 255.0f * (1 - ra);
-               pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
-               pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
-               pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
-            }
-         }
-      }
-   }
-
-   // convert to desired output format
-   if (req_comp && req_comp != 4) {
-      if (ri->bits_per_channel == 16)
-         out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h);
-      else
-         out = stbi__convert_format(out, 4, req_comp, w, h);
-      if (out == NULL) return out; // stbi__convert_format frees input on failure
-   }
-
-   if (comp) *comp = 4;
-   *y = h;
-   *x = w;
-
-   return out;
-}
-#endif
-
-// *************************************************************************************************
-// 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/
-
-#ifndef STBI_NO_PIC
-static int stbi__pic_is4(stbi__context *s,const char *str)
-{
-   int i;
-   for (i=0; i<4; ++i)
-      if (stbi__get8(s) != (stbi_uc)str[i])
-         return 0;
-
-   return 1;
-}
-
-static int stbi__pic_test_core(stbi__context *s)
-{
-   int i;
-
-   if (!stbi__pic_is4(s,"\x53\x80\xF6\x34"))
-      return 0;
-
-   for(i=0;i<84;++i)
-      stbi__get8(s);
-
-   if (!stbi__pic_is4(s,"PICT"))
-      return 0;
-
-   return 1;
-}
-
-typedef struct
-{
-   stbi_uc size,type,channel;
-} stbi__pic_packet;
-
-static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest)
-{
-   int mask=0x80, i;
-
-   for (i=0; i<4; ++i, mask>>=1) {
-      if (channel & mask) {
-         if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short");
-         dest[i]=stbi__get8(s);
-      }
-   }
-
-   return dest;
-}
-
-static void stbi__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 *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result)
-{
-   int act_comp=0,num_packets=0,y,chained;
-   stbi__pic_packet packets[10];
-
-   // this will (should...) cater for even some bizarre stuff like having data
-    // for the same channel in multiple packets.
-   do {
-      stbi__pic_packet *packet;
-
-      if (num_packets==sizeof(packets)/sizeof(packets[0]))
-         return stbi__errpuc("bad format","too many packets");
-
-      packet = &packets[num_packets++];
-
-      chained = stbi__get8(s);
-      packet->size    = stbi__get8(s);
-      packet->type    = stbi__get8(s);
-      packet->channel = stbi__get8(s);
-
-      act_comp |= packet->channel;
-
-      if (stbi__at_eof(s))          return stbi__errpuc("bad file","file too short (reading packets)");
-      if (packet->size != 8)  return stbi__errpuc("bad format","packet isn't 8bpp");
-   } while (chained);
-
-   *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel?
-
-   for(y=0; y<height; ++y) {
-      int packet_idx;
-
-      for(packet_idx=0; packet_idx < num_packets; ++packet_idx) {
-         stbi__pic_packet *packet = &packets[packet_idx];
-         stbi_uc *dest = result+y*width*4;
-
-         switch (packet->type) {
-            default:
-               return stbi__errpuc("bad format","packet has bad compression type");
-
-            case 0: {//uncompressed
-               int x;
-
-               for(x=0;x<width;++x, dest+=4)
-                  if (!stbi__readval(s,packet->channel,dest))
-                     return 0;
-               break;
-            }
-
-            case 1://Pure RLE
-               {
-                  int left=width, i;
-
-                  while (left>0) {
-                     stbi_uc count,value[4];
-
-                     count=stbi__get8(s);
-                     if (stbi__at_eof(s))   return stbi__errpuc("bad file","file too short (pure read count)");
-
-                     if (count > left)
-                        count = (stbi_uc) left;
-
-                     if (!stbi__readval(s,packet->channel,value))  return 0;
-
-                     for(i=0; i<count; ++i,dest+=4)
-                        stbi__copyval(packet->channel,dest,value);
-                     left -= count;
-                  }
-               }
-               break;
-
-            case 2: {//Mixed RLE
-               int left=width;
-               while (left>0) {
-                  int count = stbi__get8(s), i;
-                  if (stbi__at_eof(s))  return stbi__errpuc("bad file","file too short (mixed read count)");
-
-                  if (count >= 128) { // Repeated
-                     stbi_uc value[4];
-
-                     if (count==128)
-                        count = stbi__get16be(s);
-                     else
-                        count -= 127;
-                     if (count > left)
-                        return stbi__errpuc("bad file","scanline overrun");
-
-                     if (!stbi__readval(s,packet->channel,value))
-                        return 0;
-
-                     for(i=0;i<count;++i, dest += 4)
-                        stbi__copyval(packet->channel,dest,value);
-                  } else { // Raw
-                     ++count;
-                     if (count>left) return stbi__errpuc("bad file","scanline overrun");
-
-                     for(i=0;i<count;++i, dest+=4)
-                        if (!stbi__readval(s,packet->channel,dest))
-                           return 0;
-                  }
-                  left-=count;
-               }
-               break;
-            }
-         }
-      }
-   }
-
-   return result;
-}
-
-static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri)
-{
-   stbi_uc *result;
-   int i, x,y, internal_comp;
-   STBI_NOTUSED(ri);
-
-   if (!comp) comp = &internal_comp;
-
-   for (i=0; i<92; ++i)
-      stbi__get8(s);
-
-   x = stbi__get16be(s);
-   y = stbi__get16be(s);
-
-   if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-   if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-
-   if (stbi__at_eof(s))  return stbi__errpuc("bad file","file too short (pic header)");
-   if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
-
-   stbi__get32be(s); //skip `ratio'
-   stbi__get16be(s); //skip `fields'
-   stbi__get16be(s); //skip `pad'
-
-   // intermediate buffer is RGBA
-   result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0);
-   if (!result) return stbi__errpuc("outofmem", "Out of memory");
-   memset(result, 0xff, x*y*4);
-
-   if (!stbi__pic_load_core(s,x,y,comp, result)) {
-      STBI_FREE(result);
-      result=0;
-   }
-   *px = x;
-   *py = y;
-   if (req_comp == 0) req_comp = *comp;
-   result=stbi__convert_format(result,4,req_comp,x,y);
-
-   return result;
-}
-
-static int stbi__pic_test(stbi__context *s)
-{
-   int r = stbi__pic_test_core(s);
-   stbi__rewind(s);
-   return r;
-}
-#endif
-
-// *************************************************************************************************
-// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
-
-#ifndef STBI_NO_GIF
-typedef struct
-{
-   stbi__int16 prefix;
-   stbi_uc first;
-   stbi_uc suffix;
-} stbi__gif_lzw;
-
-typedef struct
-{
-   int w,h;
-   stbi_uc *out;                 // output buffer (always 4 components)
-   stbi_uc *background;          // The current "background" as far as a gif is concerned
-   stbi_uc *history;
-   int flags, bgindex, ratio, transparent, eflags;
-   stbi_uc  pal[256][4];
-   stbi_uc lpal[256][4];
-   stbi__gif_lzw codes[8192];
-   stbi_uc *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;
-   int delay;
-} stbi__gif;
-
-static int stbi__gif_test_raw(stbi__context *s)
-{
-   int sz;
-   if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0;
-   sz = stbi__get8(s);
-   if (sz != '9' && sz != '7') return 0;
-   if (stbi__get8(s) != 'a') return 0;
-   return 1;
-}
-
-static int stbi__gif_test(stbi__context *s)
-{
-   int r = stbi__gif_test_raw(s);
-   stbi__rewind(s);
-   return r;
-}
-
-static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp)
-{
-   int i;
-   for (i=0; i < num_entries; ++i) {
-      pal[i][2] = stbi__get8(s);
-      pal[i][1] = stbi__get8(s);
-      pal[i][0] = stbi__get8(s);
-      pal[i][3] = transp == i ? 0 : 255;
-   }
-}
-
-static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info)
-{
-   stbi_uc version;
-   if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8')
-      return stbi__err("not GIF", "Corrupt GIF");
-
-   version = stbi__get8(s);
-   if (version != '7' && version != '9')    return stbi__err("not GIF", "Corrupt GIF");
-   if (stbi__get8(s) != 'a')                return stbi__err("not GIF", "Corrupt GIF");
-
-   stbi__g_failure_reason = "";
-   g->w = stbi__get16le(s);
-   g->h = stbi__get16le(s);
-   g->flags = stbi__get8(s);
-   g->bgindex = stbi__get8(s);
-   g->ratio = stbi__get8(s);
-   g->transparent = -1;
-
-   if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
-   if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
-
-   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__context *s, int *x, int *y, int *comp)
-{
-   stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
-   if (!g) return stbi__err("outofmem", "Out of memory");
-   if (!stbi__gif_header(s, g, comp, 1)) {
-      STBI_FREE(g);
-      stbi__rewind( s );
-      return 0;
-   }
-   if (x) *x = g->w;
-   if (y) *y = g->h;
-   STBI_FREE(g);
-   return 1;
-}
-
-static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
-{
-   stbi_uc *p, *c;
-   int idx;
-
-   // 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;
-
-   idx = g->cur_x + g->cur_y;
-   p = &g->out[idx];
-   g->history[idx / 4] = 1;
-
-   c = &g->color_table[g->codes[code].suffix * 4];
-   if (c[3] > 128) { // don't render transparent pixels;
-      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 stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
-{
-   stbi_uc lzw_cs;
-   stbi__int32 len, init_code;
-   stbi__uint32 first;
-   stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear;
-   stbi__gif_lzw *p;
-
-   lzw_cs = stbi__get8(s);
-   if (lzw_cs > 12) return NULL;
-   clear = 1 << lzw_cs;
-   first = 1;
-   codesize = lzw_cs + 1;
-   codemask = (1 << codesize) - 1;
-   bits = 0;
-   valid_bits = 0;
-   for (init_code = 0; init_code < clear; init_code++) {
-      g->codes[init_code].prefix = -1;
-      g->codes[init_code].first = (stbi_uc) init_code;
-      g->codes[init_code].suffix = (stbi_uc) init_code;
-   }
-
-   // support no starting clear code
-   avail = clear+2;
-   oldcode = -1;
-
-   len = 0;
-   for(;;) {
-      if (valid_bits < codesize) {
-         if (len == 0) {
-            len = stbi__get8(s); // start new block
-            if (len == 0)
-               return g->out;
-         }
-         --len;
-         bits |= (stbi__int32) stbi__get8(s) << valid_bits;
-         valid_bits += 8;
-      } else {
-         stbi__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
-            stbi__skip(s, len);
-            while ((len = stbi__get8(s)) > 0)
-               stbi__skip(s,len);
-            return g->out;
-         } else if (code <= avail) {
-            if (first) {
-               return stbi__errpuc("no clear code", "Corrupt GIF");
-            }
-
-            if (oldcode >= 0) {
-               p = &g->codes[avail++];
-               if (avail > 8192) {
-                  return stbi__errpuc("too many codes", "Corrupt GIF");
-               }
-
-               p->prefix = (stbi__int16) oldcode;
-               p->first = g->codes[oldcode].first;
-               p->suffix = (code == avail) ? p->first : g->codes[code].first;
-            } else if (code == avail)
-               return stbi__errpuc("illegal code in raster", "Corrupt GIF");
-
-            stbi__out_gif_code(g, (stbi__uint16) code);
-
-            if ((avail & codemask) == 0 && avail <= 0x0FFF) {
-               codesize++;
-               codemask = (1 << codesize) - 1;
-            }
-
-            oldcode = code;
-         } else {
-            return stbi__errpuc("illegal code in raster", "Corrupt GIF");
-         }
-      }
-   }
-}
-
-// this function is designed to support animated gifs, although stb_image doesn't support it
-// two back is the image from two frames ago, used for a very specific disposal format
-static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back)
-{
-   int dispose;
-   int first_frame;
-   int pi;
-   int pcount;
-   STBI_NOTUSED(req_comp);
-
-   // on first frame, any non-written pixels get the background colour (non-transparent)
-   first_frame = 0;
-   if (g->out == 0) {
-      if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
-      if (!stbi__mad3sizes_valid(4, g->w, g->h, 0))
-         return stbi__errpuc("too large", "GIF image is too large");
-      pcount = g->w * g->h;
-      g->out = (stbi_uc *) stbi__malloc(4 * pcount);
-      g->background = (stbi_uc *) stbi__malloc(4 * pcount);
-      g->history = (stbi_uc *) stbi__malloc(pcount);
-      if (!g->out || !g->background || !g->history)
-         return stbi__errpuc("outofmem", "Out of memory");
-
-      // image is treated as "transparent" at the start - ie, nothing overwrites the current background;
-      // background colour is only used for pixels that are not rendered first frame, after that "background"
-      // color refers to the color that was there the previous frame.
-      memset(g->out, 0x00, 4 * pcount);
-      memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent)
-      memset(g->history, 0x00, pcount);        // pixels that were affected previous frame
-      first_frame = 1;
-   } else {
-      // second frame - how do we dispose of the previous one?
-      dispose = (g->eflags & 0x1C) >> 2;
-      pcount = g->w * g->h;
-
-      if ((dispose == 3) && (two_back == 0)) {
-         dispose = 2; // if I don't have an image to revert back to, default to the old background
-      }
-
-      if (dispose == 3) { // use previous graphic
-         for (pi = 0; pi < pcount; ++pi) {
-            if (g->history[pi]) {
-               memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 );
-            }
-         }
-      } else if (dispose == 2) {
-         // restore what was changed last frame to background before that frame;
-         for (pi = 0; pi < pcount; ++pi) {
-            if (g->history[pi]) {
-               memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 );
-            }
-         }
-      } else {
-         // This is a non-disposal case eithe way, so just
-         // leave the pixels as is, and they will become the new background
-         // 1: do not dispose
-         // 0:  not specified.
-      }
-
-      // background is what out is after the undoing of the previou frame;
-      memcpy( g->background, g->out, 4 * g->w * g->h );
-   }
-
-   // clear my history;
-   memset( g->history, 0x00, g->w * g->h );        // pixels that were affected previous frame
-
-   for (;;) {
-      int tag = stbi__get8(s);
-      switch (tag) {
-         case 0x2C: /* Image Descriptor */
-         {
-            stbi__int32 x, y, w, h;
-            stbi_uc *o;
-
-            x = stbi__get16le(s);
-            y = stbi__get16le(s);
-            w = stbi__get16le(s);
-            h = stbi__get16le(s);
-            if (((x + w) > (g->w)) || ((y + h) > (g->h)))
-               return stbi__errpuc("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;
-
-            // if the width of the specified rectangle is 0, that means
-            // we may not see *any* pixels or the image is malformed;
-            // to make sure this is caught, move the current y down to
-            // max_y (which is what out_gif_code checks).
-            if (w == 0)
-               g->cur_y = g->max_y;
-
-            g->lflags = stbi__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 = (stbi_uc *) g->lpal;
-            } else if (g->flags & 0x80) {
-               g->color_table = (stbi_uc *) g->pal;
-            } else
-               return stbi__errpuc("missing color table", "Corrupt GIF");
-
-            o = stbi__process_gif_raster(s, g);
-            if (!o) return NULL;
-
-            // if this was the first frame,
-            pcount = g->w * g->h;
-            if (first_frame && (g->bgindex > 0)) {
-               // if first frame, any pixel not drawn to gets the background color
-               for (pi = 0; pi < pcount; ++pi) {
-                  if (g->history[pi] == 0) {
-                     g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be;
-                     memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 );
-                  }
-               }
-            }
-
-            return o;
-         }
-
-         case 0x21: // Comment Extension.
-         {
-            int len;
-            int ext = stbi__get8(s);
-            if (ext == 0xF9) { // Graphic Control Extension.
-               len = stbi__get8(s);
-               if (len == 4) {
-                  g->eflags = stbi__get8(s);
-                  g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths.
-
-                  // unset old transparent
-                  if (g->transparent >= 0) {
-                     g->pal[g->transparent][3] = 255;
-                  }
-                  if (g->eflags & 0x01) {
-                     g->transparent = stbi__get8(s);
-                     if (g->transparent >= 0) {
-                        g->pal[g->transparent][3] = 0;
-                     }
-                  } else {
-                     // don't need transparent
-                     stbi__skip(s, 1);
-                     g->transparent = -1;
-                  }
-               } else {
-                  stbi__skip(s, len);
-                  break;
-               }
-            }
-            while ((len = stbi__get8(s)) != 0) {
-               stbi__skip(s, len);
-            }
-            break;
-         }
-
-         case 0x3B: // gif stream termination code
-            return (stbi_uc *) s; // using '1' causes warning on some compilers
-
-         default:
-            return stbi__errpuc("unknown code", "Corrupt GIF");
-      }
-   }
-}
-
-static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays)
-{
-   STBI_FREE(g->out);
-   STBI_FREE(g->history);
-   STBI_FREE(g->background);
-
-   if (out) STBI_FREE(out);
-   if (delays && *delays) STBI_FREE(*delays);
-   return stbi__errpuc("outofmem", "Out of memory");
-}
-
-static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
-{
-   if (stbi__gif_test(s)) {
-      int layers = 0;
-      stbi_uc *u = 0;
-      stbi_uc *out = 0;
-      stbi_uc *two_back = 0;
-      stbi__gif g;
-      int stride;
-      int out_size = 0;
-      int delays_size = 0;
-
-      STBI_NOTUSED(out_size);
-      STBI_NOTUSED(delays_size);
-
-      memset(&g, 0, sizeof(g));
-      if (delays) {
-         *delays = 0;
-      }
-
-      do {
-         u = stbi__gif_load_next(s, &g, comp, req_comp, two_back);
-         if (u == (stbi_uc *) s) u = 0;  // end of animated gif marker
-
-         if (u) {
-            *x = g.w;
-            *y = g.h;
-            ++layers;
-            stride = g.w * g.h * 4;
-
-            if (out) {
-               void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
-               if (!tmp)
-                  return stbi__load_gif_main_outofmem(&g, out, delays);
-               else {
-                   out = (stbi_uc*) tmp;
-                   out_size = layers * stride;
-               }
-
-               if (delays) {
-                  int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
-                  if (!new_delays)
-                     return stbi__load_gif_main_outofmem(&g, out, delays);
-                  *delays = new_delays;
-                  delays_size = layers * sizeof(int);
-               }
-            } else {
-               out = (stbi_uc*)stbi__malloc( layers * stride );
-               if (!out)
-                  return stbi__load_gif_main_outofmem(&g, out, delays);
-               out_size = layers * stride;
-               if (delays) {
-                  *delays = (int*) stbi__malloc( layers * sizeof(int) );
-                  if (!*delays)
-                     return stbi__load_gif_main_outofmem(&g, out, delays);
-                  delays_size = layers * sizeof(int);
-               }
-            }
-            memcpy( out + ((layers - 1) * stride), u, stride );
-            if (layers >= 2) {
-               two_back = out - 2 * stride;
-            }
-
-            if (delays) {
-               (*delays)[layers - 1U] = g.delay;
-            }
-         }
-      } while (u != 0);
-
-      // free temp buffer;
-      STBI_FREE(g.out);
-      STBI_FREE(g.history);
-      STBI_FREE(g.background);
-
-      // do the final conversion after loading everything;
-      if (req_comp && req_comp != 4)
-         out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h);
-
-      *z = layers;
-      return out;
-   } else {
-      return stbi__errpuc("not GIF", "Image was not as a gif type.");
-   }
-}
-
-static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   stbi_uc *u = 0;
-   stbi__gif g;
-   memset(&g, 0, sizeof(g));
-   STBI_NOTUSED(ri);
-
-   u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
-   if (u == (stbi_uc *) s) u = 0;  // end of animated gif marker
-   if (u) {
-      *x = g.w;
-      *y = g.h;
-
-      // moved conversion to after successful load so that the same
-      // can be done for multiple frames.
-      if (req_comp && req_comp != 4)
-         u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
-   } else if (g.out) {
-      // if there was an error and we allocated an image buffer, free it!
-      STBI_FREE(g.out);
-   }
-
-   // free buffers needed for multiple frame loading;
-   STBI_FREE(g.history);
-   STBI_FREE(g.background);
-
-   return u;
-}
-
-static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   return stbi__gif_info_raw(s,x,y,comp);
-}
-#endif
-
-// *************************************************************************************************
-// Radiance RGBE HDR loader
-// originally by Nicolas Schulz
-#ifndef STBI_NO_HDR
-static int stbi__hdr_test_core(stbi__context *s, const char *signature)
-{
-   int i;
-   for (i=0; signature[i]; ++i)
-      if (stbi__get8(s) != signature[i])
-          return 0;
-   stbi__rewind(s);
-   return 1;
-}
-
-static int stbi__hdr_test(stbi__context* s)
-{
-   int r = stbi__hdr_test_core(s, "#?RADIANCE\n");
-   stbi__rewind(s);
-   if(!r) {
-       r = stbi__hdr_test_core(s, "#?RGBE\n");
-       stbi__rewind(s);
-   }
-   return r;
-}
-
-#define STBI__HDR_BUFLEN  1024
-static char *stbi__hdr_gettoken(stbi__context *z, char *buffer)
-{
-   int len=0;
-   char c = '\0';
-
-   c = (char) stbi__get8(z);
-
-   while (!stbi__at_eof(z) && c != '\n') {
-      buffer[len++] = c;
-      if (len == STBI__HDR_BUFLEN-1) {
-         // flush to end of line
-         while (!stbi__at_eof(z) && stbi__get8(z) != '\n')
-            ;
-         break;
-      }
-      c = (char) stbi__get8(z);
-   }
-
-   buffer[len] = 0;
-   return buffer;
-}
-
-static void stbi__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 *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   char buffer[STBI__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;
-   const char *headerToken;
-   STBI_NOTUSED(ri);
-
-   // Check identifier
-   headerToken = stbi__hdr_gettoken(s,buffer);
-   if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0)
-      return stbi__errpf("not HDR", "Corrupt HDR image");
-
-   // Parse header
-   for(;;) {
-      token = stbi__hdr_gettoken(s,buffer);
-      if (token[0] == 0) break;
-      if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
-   }
-
-   if (!valid)    return stbi__errpf("unsupported format", "Unsupported HDR format");
-
-   // Parse width and height
-   // can't use sscanf() if we're not using stdio!
-   token = stbi__hdr_gettoken(s,buffer);
-   if (strncmp(token, "-Y ", 3))  return stbi__errpf("unsupported data layout", "Unsupported HDR format");
-   token += 3;
-   height = (int) strtol(token, &token, 10);
-   while (*token == ' ') ++token;
-   if (strncmp(token, "+X ", 3))  return stbi__errpf("unsupported data layout", "Unsupported HDR format");
-   token += 3;
-   width = (int) strtol(token, NULL, 10);
-
-   if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
-   if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
-
-   *x = width;
-   *y = height;
-
-   if (comp) *comp = 3;
-   if (req_comp == 0) req_comp = 3;
-
-   if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0))
-      return stbi__errpf("too large", "HDR image is too large");
-
-   // Read data
-   hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0);
-   if (!hdr_data)
-      return stbi__errpf("outofmem", "Out of memory");
-
-   // 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:
-            stbi__getn(s, rgbe, 4);
-            stbi__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 = stbi__get8(s);
-         c2 = stbi__get8(s);
-         len = stbi__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)
-            stbi_uc rgbe[4];
-            rgbe[0] = (stbi_uc) c1;
-            rgbe[1] = (stbi_uc) c2;
-            rgbe[2] = (stbi_uc) len;
-            rgbe[3] = (stbi_uc) stbi__get8(s);
-            stbi__hdr_convert(hdr_data, rgbe, req_comp);
-            i = 1;
-            j = 0;
-            STBI_FREE(scanline);
-            goto main_decode_loop; // yes, this makes no sense
-         }
-         len <<= 8;
-         len |= stbi__get8(s);
-         if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
-         if (scanline == NULL) {
-            scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0);
-            if (!scanline) {
-               STBI_FREE(hdr_data);
-               return stbi__errpf("outofmem", "Out of memory");
-            }
-         }
-
-         for (k = 0; k < 4; ++k) {
-            int nleft;
-            i = 0;
-            while ((nleft = width - i) > 0) {
-               count = stbi__get8(s);
-               if (count > 128) {
-                  // Run
-                  value = stbi__get8(s);
-                  count -= 128;
-                  if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
-                  for (z = 0; z < count; ++z)
-                     scanline[i++ * 4 + k] = value;
-               } else {
-                  // Dump
-                  if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
-                  for (z = 0; z < count; ++z)
-                     scanline[i++ * 4 + k] = stbi__get8(s);
-               }
-            }
-         }
-         for (i=0; i < width; ++i)
-            stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
-      }
-      if (scanline)
-         STBI_FREE(scanline);
-   }
-
-   return hdr_data;
-}
-
-static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   char buffer[STBI__HDR_BUFLEN];
-   char *token;
-   int valid = 0;
-   int dummy;
-
-   if (!x) x = &dummy;
-   if (!y) y = &dummy;
-   if (!comp) comp = &dummy;
-
-   if (stbi__hdr_test(s) == 0) {
-       stbi__rewind( s );
-       return 0;
-   }
-
-   for(;;) {
-      token = stbi__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 = stbi__hdr_gettoken(s,buffer);
-   if (strncmp(token, "-Y ", 3)) {
-       stbi__rewind( s );
-       return 0;
-   }
-   token += 3;
-   *y = (int) strtol(token, &token, 10);
-   while (*token == ' ') ++token;
-   if (strncmp(token, "+X ", 3)) {
-       stbi__rewind( s );
-       return 0;
-   }
-   token += 3;
-   *x = (int) strtol(token, NULL, 10);
-   *comp = 3;
-   return 1;
-}
-#endif // STBI_NO_HDR
-
-#ifndef STBI_NO_BMP
-static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   void *p;
-   stbi__bmp_data info;
-
-   info.all_a = 255;
-   p = stbi__bmp_parse_header(s, &info);
-   if (p == NULL) {
-      stbi__rewind( s );
-      return 0;
-   }
-   if (x) *x = s->img_x;
-   if (y) *y = s->img_y;
-   if (comp) {
-      if (info.bpp == 24 && info.ma == 0xff000000)
-         *comp = 3;
-      else
-         *comp = info.ma ? 4 : 3;
-   }
-   return 1;
-}
-#endif
-
-#ifndef STBI_NO_PSD
-static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   int channelCount, dummy, depth;
-   if (!x) x = &dummy;
-   if (!y) y = &dummy;
-   if (!comp) comp = &dummy;
-   if (stbi__get32be(s) != 0x38425053) {
-       stbi__rewind( s );
-       return 0;
-   }
-   if (stbi__get16be(s) != 1) {
-       stbi__rewind( s );
-       return 0;
-   }
-   stbi__skip(s, 6);
-   channelCount = stbi__get16be(s);
-   if (channelCount < 0 || channelCount > 16) {
-       stbi__rewind( s );
-       return 0;
-   }
-   *y = stbi__get32be(s);
-   *x = stbi__get32be(s);
-   depth = stbi__get16be(s);
-   if (depth != 8 && depth != 16) {
-       stbi__rewind( s );
-       return 0;
-   }
-   if (stbi__get16be(s) != 3) {
-       stbi__rewind( s );
-       return 0;
-   }
-   *comp = 4;
-   return 1;
-}
-
-static int stbi__psd_is16(stbi__context *s)
-{
-   int channelCount, depth;
-   if (stbi__get32be(s) != 0x38425053) {
-       stbi__rewind( s );
-       return 0;
-   }
-   if (stbi__get16be(s) != 1) {
-       stbi__rewind( s );
-       return 0;
-   }
-   stbi__skip(s, 6);
-   channelCount = stbi__get16be(s);
-   if (channelCount < 0 || channelCount > 16) {
-       stbi__rewind( s );
-       return 0;
-   }
-   STBI_NOTUSED(stbi__get32be(s));
-   STBI_NOTUSED(stbi__get32be(s));
-   depth = stbi__get16be(s);
-   if (depth != 16) {
-       stbi__rewind( s );
-       return 0;
-   }
-   return 1;
-}
-#endif
-
-#ifndef STBI_NO_PIC
-static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   int act_comp=0,num_packets=0,chained,dummy;
-   stbi__pic_packet packets[10];
-
-   if (!x) x = &dummy;
-   if (!y) y = &dummy;
-   if (!comp) comp = &dummy;
-
-   if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
-      stbi__rewind(s);
-      return 0;
-   }
-
-   stbi__skip(s, 88);
-
-   *x = stbi__get16be(s);
-   *y = stbi__get16be(s);
-   if (stbi__at_eof(s)) {
-      stbi__rewind( s);
-      return 0;
-   }
-   if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) {
-      stbi__rewind( s );
-      return 0;
-   }
-
-   stbi__skip(s, 8);
-
-   do {
-      stbi__pic_packet *packet;
-
-      if (num_packets==sizeof(packets)/sizeof(packets[0]))
-         return 0;
-
-      packet = &packets[num_packets++];
-      chained = stbi__get8(s);
-      packet->size    = stbi__get8(s);
-      packet->type    = stbi__get8(s);
-      packet->channel = stbi__get8(s);
-      act_comp |= packet->channel;
-
-      if (stbi__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;
-}
-#endif
-
-// *************************************************************************************************
-// Portable Gray Map and Portable Pixel Map loader
-// by Ken Miller
-//
-// PGM: http://netpbm.sourceforge.net/doc/pgm.html
-// PPM: http://netpbm.sourceforge.net/doc/ppm.html
-//
-// Known limitations:
-//    Does not support comments in the header section
-//    Does not support ASCII image data (formats P2 and P3)
-
-#ifndef STBI_NO_PNM
-
-static int      stbi__pnm_test(stbi__context *s)
-{
-   char p, t;
-   p = (char) stbi__get8(s);
-   t = (char) stbi__get8(s);
-   if (p != 'P' || (t != '5' && t != '6')) {
-       stbi__rewind( s );
-       return 0;
-   }
-   return 1;
-}
-
-static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   stbi_uc *out;
-   STBI_NOTUSED(ri);
-
-   ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n);
-   if (ri->bits_per_channel == 0)
-      return 0;
-
-   if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-   if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
-
-   *x = s->img_x;
-   *y = s->img_y;
-   if (comp) *comp = s->img_n;
-
-   if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0))
-      return stbi__errpuc("too large", "PNM too large");
-
-   out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0);
-   if (!out) return stbi__errpuc("outofmem", "Out of memory");
-   if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) {
-      STBI_FREE(out);
-      return stbi__errpuc("bad PNM", "PNM file truncated");
-   }
-
-   if (req_comp && req_comp != s->img_n) {
-      if (ri->bits_per_channel == 16) {
-         out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y);
-      } else {
-         out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
-      }
-      if (out == NULL) return out; // stbi__convert_format frees input on failure
-   }
-   return out;
-}
-
-static int      stbi__pnm_isspace(char c)
-{
-   return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
-}
-
-static void     stbi__pnm_skip_whitespace(stbi__context *s, char *c)
-{
-   for (;;) {
-      while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
-         *c = (char) stbi__get8(s);
-
-      if (stbi__at_eof(s) || *c != '#')
-         break;
-
-      while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' )
-         *c = (char) stbi__get8(s);
-   }
-}
-
-static int      stbi__pnm_isdigit(char c)
-{
-   return c >= '0' && c <= '9';
-}
-
-static int      stbi__pnm_getinteger(stbi__context *s, char *c)
-{
-   int value = 0;
-
-   while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
-      value = value*10 + (*c - '0');
-      *c = (char) stbi__get8(s);
-      if((value > 214748364) || (value == 214748364 && *c > '7'))
-          return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int");
-   }
-
-   return value;
-}
-
-static int      stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   int maxv, dummy;
-   char c, p, t;
-
-   if (!x) x = &dummy;
-   if (!y) y = &dummy;
-   if (!comp) comp = &dummy;
-
-   stbi__rewind(s);
-
-   // Get identifier
-   p = (char) stbi__get8(s);
-   t = (char) stbi__get8(s);
-   if (p != 'P' || (t != '5' && t != '6')) {
-       stbi__rewind(s);
-       return 0;
-   }
-
-   *comp = (t == '6') ? 3 : 1;  // '5' is 1-component .pgm; '6' is 3-component .ppm
-
-   c = (char) stbi__get8(s);
-   stbi__pnm_skip_whitespace(s, &c);
-
-   *x = stbi__pnm_getinteger(s, &c); // read width
-   if(*x == 0)
-       return stbi__err("invalid width", "PPM image header had zero or overflowing width");
-   stbi__pnm_skip_whitespace(s, &c);
-
-   *y = stbi__pnm_getinteger(s, &c); // read height
-   if (*y == 0)
-       return stbi__err("invalid width", "PPM image header had zero or overflowing width");
-   stbi__pnm_skip_whitespace(s, &c);
-
-   maxv = stbi__pnm_getinteger(s, &c);  // read max value
-   if (maxv > 65535)
-      return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images");
-   else if (maxv > 255)
-      return 16;
-   else
-      return 8;
-}
-
-static int stbi__pnm_is16(stbi__context *s)
-{
-   if (stbi__pnm_info(s, NULL, NULL, NULL) == 16)
-	   return 1;
-   return 0;
-}
-#endif
-
-static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
-{
-   #ifndef STBI_NO_JPEG
-   if (stbi__jpeg_info(s, x, y, comp)) return 1;
-   #endif
-
-   #ifndef STBI_NO_PNG
-   if (stbi__png_info(s, x, y, comp))  return 1;
-   #endif
-
-   #ifndef STBI_NO_GIF
-   if (stbi__gif_info(s, x, y, comp))  return 1;
-   #endif
-
-   #ifndef STBI_NO_BMP
-   if (stbi__bmp_info(s, x, y, comp))  return 1;
-   #endif
-
-   #ifndef STBI_NO_PSD
-   if (stbi__psd_info(s, x, y, comp))  return 1;
-   #endif
-
-   #ifndef STBI_NO_PIC
-   if (stbi__pic_info(s, x, y, comp))  return 1;
-   #endif
-
-   #ifndef STBI_NO_PNM
-   if (stbi__pnm_info(s, x, y, comp))  return 1;
-   #endif
-
-   #ifndef STBI_NO_HDR
-   if (stbi__hdr_info(s, x, y, comp))  return 1;
-   #endif
-
-   // test tga last because it's a crappy test!
-   #ifndef STBI_NO_TGA
-   if (stbi__tga_info(s, x, y, comp))
-       return 1;
-   #endif
-   return stbi__err("unknown image type", "Image not of any known type, or corrupt");
-}
-
-static int stbi__is_16_main(stbi__context *s)
-{
-   #ifndef STBI_NO_PNG
-   if (stbi__png_is16(s))  return 1;
-   #endif
-
-   #ifndef STBI_NO_PSD
-   if (stbi__psd_is16(s))  return 1;
-   #endif
-
-   #ifndef STBI_NO_PNM
-   if (stbi__pnm_is16(s))  return 1;
-   #endif
-   return 0;
-}
-
-#ifndef STBI_NO_STDIO
-STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp)
-{
-    FILE *f = stbi__fopen(filename, "rb");
-    int result;
-    if (!f) return stbi__err("can't fopen", "Unable to open file");
-    result = stbi_info_from_file(f, x, y, comp);
-    fclose(f);
-    return result;
-}
-
-STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
-{
-   int r;
-   stbi__context s;
-   long pos = ftell(f);
-   stbi__start_file(&s, f);
-   r = stbi__info_main(&s,x,y,comp);
-   fseek(f,pos,SEEK_SET);
-   return r;
-}
-
-STBIDEF int stbi_is_16_bit(char const *filename)
-{
-    FILE *f = stbi__fopen(filename, "rb");
-    int result;
-    if (!f) return stbi__err("can't fopen", "Unable to open file");
-    result = stbi_is_16_bit_from_file(f);
-    fclose(f);
-    return result;
-}
-
-STBIDEF int stbi_is_16_bit_from_file(FILE *f)
-{
-   int r;
-   stbi__context s;
-   long pos = ftell(f);
-   stbi__start_file(&s, f);
-   r = stbi__is_16_main(&s);
-   fseek(f,pos,SEEK_SET);
-   return r;
-}
-#endif // !STBI_NO_STDIO
-
-STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__info_main(&s,x,y,comp);
-}
-
-STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
-   return stbi__info_main(&s,x,y,comp);
-}
-
-STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__is_16_main(&s);
-}
-
-STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
-   return stbi__is_16_main(&s);
-}
-
-#endif // STB_IMAGE_IMPLEMENTATION
-
-/*
-   revision history:
-      2.20  (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
-      2.19  (2018-02-11) fix warning
-      2.18  (2018-01-30) fix warnings
-      2.17  (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
-                         1-bit BMP
-                         *_is_16_bit api
-                         avoid warnings
-      2.16  (2017-07-23) all functions have 16-bit variants;
-                         STBI_NO_STDIO works again;
-                         compilation fixes;
-                         fix rounding in unpremultiply;
-                         optimize vertical flip;
-                         disable raw_len validation;
-                         documentation fixes
-      2.15  (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
-                         warning fixes; disable run-time SSE detection on gcc;
-                         uniform handling of optional "return" values;
-                         thread-safe initialization of zlib tables
-      2.14  (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
-      2.13  (2016-11-29) add 16-bit API, only supported for PNG right now
-      2.12  (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
-      2.11  (2016-04-02) allocate large structures on the stack
-                         remove white matting for transparent PSD
-                         fix reported channel count for PNG & BMP
-                         re-enable SSE2 in non-gcc 64-bit
-                         support RGB-formatted JPEG
-                         read 16-bit PNGs (only as 8-bit)
-      2.10  (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
-      2.09  (2016-01-16) allow comments in PNM files
-                         16-bit-per-pixel TGA (not bit-per-component)
-                         info() for TGA could break due to .hdr handling
-                         info() for BMP to shares code instead of sloppy parse
-                         can use STBI_REALLOC_SIZED if allocator doesn't support realloc
-                         code cleanup
-      2.08  (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
-      2.07  (2015-09-13) fix compiler warnings
-                         partial animated GIF support
-                         limited 16-bpc PSD support
-                         #ifdef unused functions
-                         bug with < 92 byte PIC,PNM,HDR,TGA
-      2.06  (2015-04-19) fix bug where PSD returns wrong '*comp' value
-      2.05  (2015-04-19) fix bug in progressive JPEG handling, fix warning
-      2.04  (2015-04-15) try to re-enable SIMD on MinGW 64-bit
-      2.03  (2015-04-12) extra corruption checking (mmozeiko)
-                         stbi_set_flip_vertically_on_load (nguillemot)
-                         fix NEON support; fix mingw support
-      2.02  (2015-01-19) fix incorrect assert, fix warning
-      2.01  (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2
-      2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
-      2.00  (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg)
-                         progressive JPEG (stb)
-                         PGM/PPM support (Ken Miller)
-                         STBI_MALLOC,STBI_REALLOC,STBI_FREE
-                         GIF bugfix -- seemingly never worked
-                         STBI_NO_*, STBI_ONLY_*
-      1.48  (2014-12-14) fix incorrectly-named assert()
-      1.47  (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb)
-                         optimize PNG (ryg)
-                         fix bug in interlaced PNG with user-specified channel count (stb)
-      1.46  (2014-08-26)
-              fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG
-      1.45  (2014-08-16)
-              fix MSVC-ARM internal compiler error by wrapping malloc
-      1.44  (2014-08-07)
-              various warning fixes from Ronny Chevalier
-      1.43  (2014-07-15)
-              fix MSVC-only compiler problem in code changed in 1.42
-      1.42  (2014-07-09)
-              don't define _CRT_SECURE_NO_WARNINGS (affects user code)
-              fixes to stbi__cleanup_jpeg path
-              added STBI_ASSERT to avoid requiring assert.h
-      1.41  (2014-06-25)
-              fix search&replace from 1.36 that messed up comments/error messages
-      1.40  (2014-06-22)
-              fix gcc struct-initialization warning
-      1.39  (2014-06-15)
-              fix to TGA optimization when req_comp != number of components in TGA;
-              fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite)
-              add support for BMP version 5 (more ignored fields)
-      1.38  (2014-06-06)
-              suppress MSVC warnings on integer casts truncating values
-              fix accidental rename of 'skip' field of I/O
-      1.37  (2014-06-04)
-              remove duplicate typedef
-      1.36  (2014-06-03)
-              convert to header file single-file library
-              if de-iphone isn't set, load iphone images color-swapped instead of returning NULL
-      1.35  (2014-05-27)
-              various warnings
-              fix broken STBI_SIMD path
-              fix bug where stbi_load_from_file no longer left file pointer in correct place
-              fix broken non-easy path for 32-bit BMP (possibly never used)
-              TGA optimization by Arseny Kapoulkine
-      1.34  (unknown)
-              use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case
-      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-stbi_uc 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.stbi__err. Janez (U+017D)emva)
-      1.21    fix use of 'stbi_uc' 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 - stbi__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  (2006-11-19)
-              first released version
-*/
-
-
-/*
-------------------------------------------------------------------------------
-This software is available under 2 licenses -- choose whichever you prefer.
-------------------------------------------------------------------------------
-ALTERNATIVE A - MIT License
-Copyright (c) 2017 Sean Barrett
-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.
-------------------------------------------------------------------------------
-ALTERNATIVE B - Public Domain (www.unlicense.org)
-This is free and unencumbered software released into the public domain.
-Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
-software, either in source code form or as a compiled binary, for any purpose,
-commercial or non-commercial, and by any means.
-In jurisdictions that recognize copyright laws, the author or authors of this
-software dedicate any and all copyright interest in the software to the public
-domain. We make this dedication for the benefit of the public at large and to
-the detriment of our heirs and successors. We intend this dedication to be an
-overt act of relinquishment in perpetuity of all present and future rights to
-this software under copyright law.
-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 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.
-------------------------------------------------------------------------------
-*/

+ 0 - 526
src/RasterIver/kernels/master_kernel.cl

@@ -1,526 +0,0 @@
-static inline float minnn(float a, float b) {
-    return (a < b) ? a : b;
-}
-
-static inline float maxxx(float a, float b) {
-    return (a > b) ? a : b;
-}
-
-float clamppp_float(float x, float lower, float upper) {
-    return x < lower ? lower : (x > upper ? upper : x);
-}
-
-typedef enum {
-    RI_MATERIAL_UNLIT = ((ulong)1 << 0), // should calculate lighting
-    RI_MATERIAL_DONT_CAST_SHADOW = ((ulong)1 << 1), // should cast shadow on other objects
-    RI_MATERIAL_HAS_TEXTURE = ((ulong)1 << 2), // has a texture
-    RI_MATERIAL_HAS_NORMAL_MAP = ((ulong)1 << 3), // has a normal map
-    RI_MATERIAL_HAS_BUMP_MAP = ((ulong)1 << 4), // has a bump map
-    RI_MATERIAL_TRANSPARENT = ((ulong)1 << 5), // has transparency
-    RI_MATERIAL_WIREFRAME = ((ulong)1 << 6), // render as wireframe
-    RI_MATERIAL_DONT_RECEIVE_SHADOW = ((ulong)1 << 7), // should shadows render on it
-    RI_MATERIAL_DONT_DEPTH_TEST = ((ulong)1 << 8), // should check Z buffer (if 1, render on top of everything)
-    RI_MATERIAL_DONT_DEPTH_WRITE = ((ulong)1 << 9), // should write to the Z buffer (if 1, render behind everything)
-    RI_MATERIAL_DOUBLE_SIDED = ((ulong)1 << 10), // ignore backface culling
-} RI_material_properties_enum;
-
-typedef struct {
-    float x;
-    float y;
-} Vec2;
-
-typedef struct {
-    float x;
-    float y;
-    float z;
-    float _pad0;
-} Vec3;
-
-typedef struct {
-    float w;
-    float x;
-    float y;
-    float z;
-} Vec4;
-
-typedef struct {
-    uchar a;
-    uchar r;
-    uchar g;
-    uchar b;
-} ColorARGB;
-
-typedef struct {
-    ColorARGB albedo;
-    int textureOffset;
-    int normalMapOffset;
-    int bumpMapOffset;
-    ulong properties;
-} Material;
-
-typedef struct {
-    Vec3 position;
-    Vec3 scale;
-    Vec4 rotation;
-} Transform;
-
-typedef struct {
-    int transformedVertexOffset;
-    int transformedNormalOffset;
-    int triangleCount;
-    int vertexCount;
-    int normalCount;
-    int uvCount;
-    int triangleOffset;
-    int vertexOffset;
-    int normalOffset;
-    int uvOffset;
-} ModelInfo;
-
-typedef struct {
-    Transform transform;
-    ModelInfo modelInfo;
-    int id;
-    int _pad1;
-    Material material;
-    int _pad2;
-    int _pad3;
-} Object;
-
-int is_intersecting(float a, float b, float c, float d, float p, float q, float r, float s) { 
-    float det, gamma, lambda; 
-    
-    det = (c - a) * (s - q) - (r - p) * (d - b); 
-    
-    if (det == 0) { 
-        return 1; 
-    }  
-    else { 
-        lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; 
-        gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; 
-        return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1); 
-    } 
-} 
-
-void norm(float dest[2], float a[2]){ 
-    float magnitude = sqrt(a[0] * a[0] + a[1] * a[1]); 
-    
-    dest[0] = a[0] / magnitude; 
-    dest[1] = a[1] / magnitude; 
-    } 
-    
-    void sub(float dest[2], float a[2], float b[2]){ 
-    dest[0] = a[0] - b[0]; 
-    dest[1] = a[1] - b[1]; 
-    } 
-    
-    void add(float dest[2], float a[2], float b[2]){ 
-    dest[0] = a[0] + b[0]; 
-    dest[1] = a[1] + b[1]; 
-} 
-
-inline int clamppp(int x, int lower, int upper) {
-    return x < lower ? lower : (x > upper ? upper : x);
-}
-
-void rotate_quaternion(float *x, float *y, float *z, float r_x, float r_y, float r_z){
-
-};
-
-void rotate_euler(float *x, float *y, float *z, float r_x, float r_y, float r_z){
-    float cx = cos(r_x), sx = sin(r_x);
-    float cy = cos(r_y), sy = sin(r_y);
-    float cz = cos(r_z), sz = sin(r_z);
-
-    float matrix[3][3] = {
-        {
-            cy * cz,
-            -cy * sz,
-            sy
-        },
-        {
-            sx * sy * cz + cx * sz,
-            -sx * sy * sz + cx * cz,
-            -sx * cy
-        },
-        {
-            -cx * sy * cz + sx * sz,
-            cx * sy * sz + sx * cz,
-            cx * cy
-        }
-    };
-    
-    float temp_x = matrix[0][0] * *x + matrix[0][1] * *y + matrix[0][2] * *z;
-    float temp_y = matrix[1][0] * *x + matrix[1][1] * *y + matrix[1][2] * *z;
-    float temp_z = matrix[2][0] * *x + matrix[2][1] * *y + matrix[2][2] * *z;
-
-    *x = temp_x;
-    *y = temp_y;
-    *z = temp_z;
-};
-
-Vec2 lerp(Vec2 pos1, Vec2 pos2, float fraction){
-    Vec2 result;
-
-    float w0 = 1.0 - fraction;
-    float w1 = fraction;
-
-    result.x = pos1.x * w0 + pos2.x * w1;
-    result.y = pos1.y * w0 + pos2.y * w1;
-
-    return result;
-
-}
-
-__kernel void raster_kernel(__global Object* objects, __global float* transformed_verticies, __global float* transformed_normals, __global float* uvs, __global int* triangles, __global uint* frame_buffer, __global uchar* textures, __global int* texture_info, int object_count, int ri_width, int ri_height, int show_buffer, int frame, float fov, int total_triangle_count, int total_vertex_count, int h_width, int h_height, float wireframe_width){ 
-    frame_buffer[sizeof(Object)] = 0xFF00FFFF;int id_x = get_global_id(0) - h_width; 
-    int id_y = get_global_id(1) - h_height; 
-    
-    float z_pixel = INFINITY; 
-                    unsigned int frame_pixel = 0x22222222; 
-                    
-                    float highest_z = 800;
-                    float lowest_z = 0;
-                    
-                    int has_normals = 1;
-                    int has_uvs = 1;
-                    
-                    float w0;
-                    float w1;
-                    float w2;
-                    
-
-                    for (int i_object = 0; i_object < object_count; i_object++){ 
-                        int base = i_object;
-
-                        ulong material_flags = objects[base].material.properties;
-                        ColorARGB albedo = objects[base].material.albedo;
-
-                        int triangle_count = objects[base].modelInfo.triangleCount;
-                        int triangle_index = objects[base].modelInfo.triangleOffset;
-                        int vertex_index =   objects[base].modelInfo.vertexOffset;
-                        int normal_index =   objects[base].modelInfo.normalOffset;
-                        int uv_index =       objects[base].modelInfo.uvOffset;
-                        int texture_index =  objects[base].material.textureOffset;
-                        int transformed_vertex_index = objects[base].modelInfo.transformedVertexOffset;
-                        int transformed_normal_index =   objects[base].modelInfo.transformedNormalOffset;
-                        
-                        float near_clip = 90;
-
-                        for (int i_triangle = 0; i_triangle < triangle_count; i_triangle++){
-                            int triangle_base = (i_triangle + triangle_index) * 9; 
-
-                            int i0 = (transformed_vertex_index + triangles[triangle_base + 0]) * 3;
-                            int i1 = (transformed_vertex_index + triangles[triangle_base + 1]) * 3;
-                            int i2 = (transformed_vertex_index + triangles[triangle_base + 2]) * 3;
-
-                            int i3 = (transformed_normal_index + triangles[triangle_base + 3]) * 3;
-                            int i4 = (transformed_normal_index + triangles[triangle_base + 4]) * 3;
-                            int i5 = (transformed_normal_index + triangles[triangle_base + 5]) * 3;
-
-                            int i6 = (uv_index + triangles[triangle_base + 6]) * 3;
-                            int i7 = (uv_index + triangles[triangle_base + 7]) * 3;
-                            int i8 = (uv_index + triangles[triangle_base + 8]) * 3;
-                            
-                            float x0 = transformed_verticies[i0 + 0];
-                            
-                            float z0 = transformed_verticies[i0 + 2];   
-                            float z1 = transformed_verticies[i1 + 2];
-                            float z2 = transformed_verticies[i2 + 2];
-                            
-                            float y0 = transformed_verticies[i0 + 1];
-                            float x1 = transformed_verticies[i1 + 0];
-                            float y1 = transformed_verticies[i1 + 1];
-                            float y2 = transformed_verticies[i2 + 1];
-                            float x2 = transformed_verticies[i2 + 0]; 
-                            int clip_z0 = z0 <= near_clip;
-                            int clip_z1 = z1 <= near_clip;
-                            int clip_z2 = z2 <= near_clip;
-                            
-                            int clip_count = clip_z0 + clip_z1 + clip_z2;
-
-                            switch (clip_count){
-                                case 0:{ // do nothing, they are all okay >w<
-                                    break;}
-                                
-                                case 1:{ // split triangle into 2
-continue;
-                                    if (clip_z0){
-
-                                    }
-
-                                    break;
-                                }
-
-                                case 2:{ // shrink triangle into 1
-                                    if (!clip_z0){ // z0 is fine
-                                        float percent_clipped_0 = (near_clip - z0) / (z1 - z0);
-                                        float percent_clipped_1 = (near_clip - z0) / (z2 - z0);
-                                        
-                                        Vec2 pos1 = {x0, y0};
-                                        Vec2 pos2 = {x1, y1};
-
-                                        Vec2 p1 = lerp(pos1, pos2, percent_clipped_0);
-
-                                        pos1.x = x2;
-                                        pos1.y = y2;
-
-                                        Vec2 p2 = lerp(pos1, pos2, percent_clipped_1);
-
-                                        x1 = p1.x;
-                                        y1 = p1.y;
-
-                                        x2 = p2.x;
-                                        y2 = p2.y;
-
-                                        z1 = near_clip;
-                                        z2 = near_clip;
-
-                                        break;
-                                    }
-                                    
-                                    if (!clip_z1){
-                                        float percent_clipped_0 = (near_clip - z1) / (z0 - z1);
-                                        float percent_clipped_1 = (near_clip - z1) / (z2 - z1);
-                                        
-                                        Vec2 pos1 = {x1, y1};
-                                        Vec2 pos2 = {x0, y0};
-                                        
-                                        Vec2 p1 = lerp(pos1, pos2, percent_clipped_0);
-                                        
-                                        pos1.x = x2;
-                                        pos1.y = y2;
-                                        
-                                        Vec2 p2 = lerp(pos1, pos2, percent_clipped_1);
-                                        
-                                        x0 = p1.x;
-                                        y0 = p1.y;
-                                        
-                                        x2 = p2.x;
-                                        y2 = p2.y;
-                                        
-                                        z0 = near_clip;
-                                        z2 = near_clip;
-                                        material_flags = 0;
-                                        break;
-                                    }
-
-                                    if (!clip_z2){
-                                        float percent_clipped_0 = (near_clip - z2) / (z1 - z2);
-                                        float percent_clipped_1 = (near_clip - z2) / (z0 - z2);
-                                        
-                                        Vec2 pos1 = {x2, y2};
-                                        Vec2 pos2 = {x1, y1};
-
-                                        Vec2 p1 = lerp(pos1, pos2, percent_clipped_0);
-
-                                        pos1.x = x0;
-                                        pos1.y = y0;
-
-                                        Vec2 p2 = lerp(pos1, pos2, percent_clipped_1);
-
-                                        x1 = p1.x;
-                                        y1 = p1.y;
-
-                                        x0 = p2.x;
-                                        y0 = p2.y;
-
-                                        z1 = near_clip;
-                                        z0 = near_clip;
-                                        break;
-                                    }
-                                }
-
-                                case 3:{ // lost cause, exit
-                                    continue;
-                                }
-
-                                default: { // shouldn't happen
-                                    continue;
-                                }
-                            }
-                            
-                            
-                            if (i3 < 0 || i4 < 0 || i5 < 0){
-                                has_normals = 0;
-                            }
-                            if (i6 < 0 || i7 < 0 || i8 < 0){
-                                has_uvs = 0;
-                            }
-                            
-                            if (isinf(x0) || isinf(y0) || isinf(z0) || isinf(x1) || isinf(y1) || isinf(z1) || isinf(x2) || isinf(y2) || isinf(z2)){
-                                continue;
-                            }
-                            
-                            float smallest_x = x0; 
-                            float largest_x = x0; 
-                            float smallest_y = y0; 
-                            float largest_y = y0; 
-                            
-                            if (x0 > largest_x) largest_x = x0;
-                            if (x1 > largest_x) largest_x = x1;
-                            if (x2 > largest_x) largest_x = x2;
-                            
-                            if (x0 < smallest_x) smallest_x = x0;
-                            if (x1 < smallest_x) smallest_x = x1;
-                            if (x2 < smallest_x) smallest_x = x2;
-                            
-                            if (y0 > largest_y) largest_y = y0;
-                            if (y1 > largest_y) largest_y = y1;
-                            if (y2 > largest_y) largest_y = y2;
-                            
-                            if (y0 < smallest_y) smallest_y = y0;
-                            if (y1 < smallest_y) smallest_y = y1;
-                            if (y2 < smallest_y) smallest_y = y2;
-                            
-                            smallest_x = minnn(smallest_x, 0); 
-                            largest_x = maxxx(largest_x, ri_width);  
-                            smallest_y = minnn(smallest_y, 0); 
-                            largest_y = maxxx(largest_y, ri_height); 
-                            
-                            if (id_x >= smallest_x && id_x <= largest_x && id_y >= smallest_y && id_y <= largest_y){ 
-                                float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2); 
-                                
-                                if (!(material_flags & RI_MATERIAL_DOUBLE_SIDED) && denominator >= 0) { 
-                                    continue; 
-                                } 
-                                
-                                w0 = ((y1 - y2) * (id_x - x2) + (x2 - x1) * (id_y - y2)) / denominator; 
-                                w1 = ((y2 - y0) * (id_x - x0) + (x0 - x2) * (id_y - y0)) / denominator; 
-                                w2 = 1.0 - w0 - w1; 
-                                
-                                if (!(w0 > 0 && w1 > 0 && w2 > 0)){
-                                    continue;
-                                }
-
-                                if (material_flags & RI_MATERIAL_WIREFRAME && (w0 >= wireframe_width && w1 >= wireframe_width && w2 >= wireframe_width)){
-                                    continue;
-                                }
-
-                                float w_over_z = (w0 / z0 + w1 / z1 + w2 / z2); 
-                                float z = 1.0 / w_over_z;
-
-                                if (z < z_pixel){ 
-                                    z_pixel = z; 
-                                    
-                                    float n_x0 = transformed_normals[i3 + 0];
-                                    float n_y0 = transformed_normals[i3 + 1];
-                                    float n_z0 = transformed_normals[i3 + 2];
-                                    
-                                    float n_x1 = transformed_normals[i4 + 0];
-                                    float n_y1 = transformed_normals[i4 + 1];
-                                    float n_z1 = transformed_normals[i4 + 2];
-                                    
-                                    float n_x2 = transformed_normals[i5 + 0];
-                                    float n_y2 = transformed_normals[i5 + 1];
-                                    float n_z2 = transformed_normals[i5 + 2];
-                                    
-                                    float u_x0 = uvs[i6 + 0];
-                                    float u_y0 = uvs[i6 + 1];
-                                    float u_z0 = uvs[i6 + 2];
-                                    
-                                    float u_x1 = uvs[i7 + 0];
-                                    float u_y1 = uvs[i7 + 1];
-                                    float u_z1 = uvs[i7 + 2];
-                                    
-                                    float u_x2 = uvs[i8 + 0];
-                                    float u_y2 = uvs[i8 + 1];
-                                    float u_z2 = uvs[i8 + 2];
-                                    
-                                    switch (show_buffer){
-                                        case 0:{
-                                            if (!(material_flags & RI_MATERIAL_HAS_TEXTURE)){
-                                                frame_pixel = (albedo.a << 24) | (albedo.r << 16) | (albedo.g << 8) | albedo.b;
-                                            
-                                                break;
-                                            }
-
-                                            double ux = (w0 * (u_x0 / z0) + w1 * (u_x1 / z1) + w2 * (u_x2 / z2)) / w_over_z;
-                                            double uy = (w0 * (u_y0 / z0) + w1 * (u_y1 / z1) + w2 * (u_y2 / z2)) / w_over_z;
-                                            
-                                            int texture_width = texture_info[texture_index * 3];
-                                            int texture_height = texture_info[texture_index * 3 + 1];
-                                            int texture_value_offset = texture_info[texture_index * 3 + 2];
-                                            
-                                            int ix = maxxx((int)(ux * texture_width), 0);
-                                            int iy = maxxx((int)(uy * texture_height), 0);
-                                            
-                                            int uv_pixel = (iy * texture_width + ix) * 4 + texture_value_offset;
-
-                                            if (uv_pixel >= texture_width * texture_height * 4 + texture_value_offset)break;
-                                            
-                                            unsigned char r = textures[uv_pixel + 0];
-                                            unsigned char g = textures[uv_pixel + 1];
-                                            unsigned char b = textures[uv_pixel + 2];
-                                            unsigned char a = textures[uv_pixel + 3];
-                                            
-                                            frame_pixel = (a << 24) | (r << 16) | (g << 8) | b;
-                                            
-                                            break;}
-                                        case 1:{
-                                            float z = clamppp_float(z_pixel, 0.0f, highest_z);
-                                            
-                                            float norm_z = z / highest_z;
-                                            
-                                            unsigned char intensity = (unsigned char)(norm_z * 255.0f);
-                                            
-                                            frame_pixel = 0xFF000000 | (intensity << 16) | (intensity << 8) | intensity;
-                                            
-                                            break;}
-                                        case 2:{
-                                            float nx = (w0 * (n_x0 / z0) + w1 * (n_x1 / z1) + w2 * (n_x2 / z2)) / w_over_z;
-                                            float ny = (w0 * (n_y0 / z0) + w1 * (n_y1 / z1) + w2 * (n_y2 / z2)) / w_over_z;
-                                            float nz = (w0 * (n_z0 / z0) + w1 * (n_z1 / z1) + w2 * (n_z2 / z2)) / w_over_z;
-                                            
-                                            nx = clamppp_float((nx * 0.5f + 0.5f) * 255.0f, 0.0f, 255.0f);
-                                            ny = clamppp_float((ny * 0.5f + 0.5f) * 255.0f, 0.0f, 255.0f);
-                                            nz = clamppp_float((nz * 0.5f + 0.5f) * 255.0f, 0.0f, 255.0f);
-                                            
-                                            unsigned char r = (unsigned char)nx;
-                                            unsigned char g = (unsigned char)ny;
-                                            unsigned char b = (unsigned char)nz;
-                                            
-                                            if (!has_normals){
-                                                r = 20;
-                                                g = 20;
-                                                b = 20;
-                                            }
-                                            
-                                            frame_pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
-                                            
-                                            break;}
-                                        case 3:{
-                                            float ux = w0 * u_x0 + w1 * u_x1 + w2 * u_x2;
-                                            float uy = w0 * u_y0 + w1 * u_y1 + w2 * u_y2;
-                                            
-                                            unsigned char r = (unsigned char)clamppp_float(ux * 255.0f, 0.0f, 255.0f);
-                                            unsigned char g = (unsigned char)clamppp_float(uy * 255.0f, 0.0f, 255.0f);
-                                            unsigned char b = 0;
-                                            
-                                            if (!has_uvs){
-                                                r = 20;
-                                                g = 20;
-                                                b = 20;
-                                            }
-                                            
-                                            frame_pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
-                                            
-                                            break;}
-                                        default:{
-                                            frame_pixel = 0xFF00FFFF;
-                                            
-                                            break;}
-                                    }
-                                } 
-                            }
-                        }
-                    }
-                    
-                    int pixel_coord = (ri_height * 0.5 - id_y) * ri_width + id_x + ri_width * 0.5;
-                    
-                    if (pixel_coord >= ri_width * ri_height || pixel_coord < 0){
-                        return;
-                    }
-                    
-                    frame_buffer[pixel_coord] = frame_pixel; 
-                }

+ 0 - 152
src/RasterIver/kernels/non_master_kernel.cl

@@ -1,152 +0,0 @@
-static inline float minnn(float a, float b) {
-    return (a < b) ? a : b;
-}
-
-static inline float maxxx(float a, float b) {
-    return (a > b) ? a : b;
-}
-
-
-int is_intersecting(float a, float b, float c, float d, float p, float q, float r, float s) { 
-    float det, gamma, lambda; 
-    
-    det = (c - a) * (s - q) - (r - p) * (d - b); 
-    
-    if (det == 0) { 
-        return 1; 
-    }  
-    else { 
-        lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; 
-        gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; 
-        return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1); 
-    } 
-} 
-
-void norm(float dest[2], float a[2]){ 
-    float magnitude = sqrt(a[0] * a[0] + a[1] * a[1]); 
-    
-    dest[0] = a[0] / magnitude; 
-    dest[1] = a[1] / magnitude; 
-    } 
-    
-    void sub(float dest[2], float a[2], float b[2]){ 
-    dest[0] = a[0] - b[0]; 
-    dest[1] = a[1] - b[1]; 
-    } 
-    
-    void add(float dest[2], float a[2], float b[2]){ 
-    dest[0] = a[0] + b[0]; 
-    dest[1] = a[1] + b[1]; 
-} 
-
-__kernel void raster_kernel(__global float* polygons, __global uint* frame_buffer, int polygon_count, int width, int height, int show_z_buffer, float highest_z){ 
-    int id_x = get_global_id(0); 
-    int id_y = get_global_id(1); 
-    
-    float z_pixel = 0; 
-    uint frame_pixel = 0x22222222; 
-    
-    float biggest_z = 0;
-    
-    for (int polygon = 0; polygon < polygon_count; polygon++){ 
-        int base = polygon * 9; 
-        float x0 = polygons[base]; 
-        float y0 = polygons[base + 1]; 
-        float z0 = polygons[base + 2]; 
-        float x1 = polygons[base + 3]; 
-        float y1 = polygons[base + 4]; 
-        float z1 = polygons[base + 5]; 
-        float x2 = polygons[base + 6]; 
-        float y2 = polygons[base + 7]; 
-        float z2 = polygons[base + 8]; 
-        
-        if (isinf(x0) || isinf(y0) || isinf(z0) || isinf(x1) || isinf(y1) || isinf(z1) || isinf(x2) || isinf(y2) || isinf(z2)){
-            return;
-        }
-        
-        float smallest_x = x0; 
-        float largest_x = x0; 
-        float smallest_y = y0; 
-        float largest_y = y0; 
-        
-        for (int point = 0; point < 3; point++){ 
-            float x = polygons[base + point * 3]; 
-            float y = polygons[base + point * 3 + 1]; 
-            
-            if (x > largest_x){ 
-                largest_x = x; 
-            } 
-            
-            if (x < smallest_x){ 
-                smallest_x = x; 
-            } 
-            
-            if (y > largest_y){ 
-                largest_y = y; 
-            } 
-            
-            if (y < smallest_y){
-                smallest_y = y;
-            } 
-        } 
-        
-        smallest_x = minnn(smallest_x, 0); 
-        largest_x = maxxx(largest_x, width); 
-        smallest_y = minnn(smallest_y, 0); 
-        largest_y = maxxx(largest_y, height); 
-        
-        if (id_x >= smallest_x && id_x <= largest_x && id_y >= smallest_y && id_y <= largest_y){ 
-            int intersections = 0; 
-            
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x0, y0, x1, y1); 
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x1, y1, x2, y2); 
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x2, y2, x0, y0); 
-            
-            if (intersections % 2 == 0){ 
-                continue; 
-            } 
-            
-            float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2); 
-            float w0 = ((y1 - y2) * (id_x - x2) + (x2 - x1) * (id_y - y2)) / denominator; 
-            float w1 = ((y2 - y0) * (id_x - x0) + (x0 - x2) * (id_y - y2)) / denominator; 
-            float w2 = 1.0 - w0 - w1; 
-            
-            if (denominator < 0) { 
-                w0 = -w0; 
-                w1 = -w1; 
-                w2 = -w2; 
-                denominator = -denominator; 
-            } 
-            
-            float z = w0 * z0 + w1 * z1 + w2 * z2; 
-            
-            if (z < 0){ 
-                z *= -1; 
-            } 
-            
-            if (z > z_pixel){ 
-                z_pixel = z; 
-            } 
-             
-            else { 
-                continue; 
-            } 
-            
-            frame_pixel = 0xFFFFFFFF / polygon_count * (polygon + 1); 
-        } 
-    } 
-    
-    if (id_y * width + id_x > width * height){
-    return;
-    }
-    frame_buffer[id_y * width + id_x] = frame_pixel; 
-    
-    if (!show_z_buffer){return;}
-    
-    float z = clamp(z_pixel, 0.0f, highest_z);
-    
-    float norm_z = z / highest_z;
-    
-    uchar intensity = (uchar)(norm_z * 255.0f);
-    
-    frame_buffer[id_y * width + id_x] = 0xFF000000 | (intensity << 16) | (intensity << 8) | intensity;}

+ 0 - 215
src/RasterIver/kernels/transformer.cl

@@ -1,215 +0,0 @@
-static inline float minnn(float a, float b) {
-    return (a < b) ? a : b;
-}
-
-static inline float maxxx(float a, float b) {
-    return (a > b) ? a : b;
-}
-
-typedef struct {
-    float x;
-    float y;
-    float z;
-    float _pad0;
-} Vec3;
-
-typedef struct {
-    float w;
-    float x;
-    float y;
-    float z;
-} Vec4;
-
-typedef struct {
-    uchar a;
-    uchar r;
-    uchar g;
-    uchar b;
-} ColorARGB;
-
-typedef struct {
-    ColorARGB albedo;
-    int textureOffset;
-    int normalMapOffset;
-    int bumpMapOffset;
-    ulong properties;
-} Material;
-
-typedef struct {
-    Vec3 position;
-    Vec3 scale;
-    Vec4 rotation;
-} Transform;
-
-typedef struct {
-    int transformedVertexOffset;
-    int transformedNormalOffset;
-    int triangleCount;
-    int vertexCount;
-    int normalCount;
-    int uvCount;
-    int triangleOffset;
-    int vertexOffset;
-    int normalOffset;
-    int uvOffset;
-} ModelInfo;
-
-typedef struct {
-    Transform transform;
-    ModelInfo modelInfo;
-    int id;
-    int _pad1;
-    Material material;
-    int _pad2;
-    int _pad3;
-} Object;
-
-inline int clamppp(int x, int lower, int upper) {
-    return x < lower ? lower : (x > upper ? upper : x);
-}
-
-void rotate_quaternion(float *x, float *y, float *z, float r_x, float r_y, float r_z){
-
-};
-
-void rotate_euler(float *x, float *y, float *z, float r_x, float r_y, float r_z){
-    float cx = cos(r_x), sx = sin(r_x);
-    float cy = cos(r_y), sy = sin(r_y);
-    float cz = cos(r_z), sz = sin(r_z);
-
-    float matrix[3][3] = {
-        {
-            cy * cz,
-            -cy * sz,
-            sy
-        },
-        {
-            sx * sy * cz + cx * sz,
-            -sx * sy * sz + cx * cz,
-            -sx * cy
-        },
-        {
-            -cx * sy * cz + sx * sz,
-            cx * sy * sz + sx * cz,
-            cx * cy
-        }
-    };
-    
-    float temp_x = matrix[0][0] * *x + matrix[0][1] * *y + matrix[0][2] * *z;
-    float temp_y = matrix[1][0] * *x + matrix[1][1] * *y + matrix[1][2] * *z;
-    float temp_z = matrix[2][0] * *x + matrix[2][1] * *y + matrix[2][2] * *z;
-
-    *x = temp_x;
-    *y = temp_y;
-    *z = temp_z;
-};
-
-__kernel void transformer_kernel(__global Object* objects, __global float* verticies, __global float* normals, __global int* triangles, __global float* transformed_verticies, __global float* transformed_normals, float fov, int width, int height, __global uint* frame_buffer, int ri_h_width, int ri_h_height){ 
-    frame_buffer[sizeof(Object)] = 0xFFFFFFFF;int id_x = get_global_id(0);
-    
-    float vertical_fov_factor = height / tan(0.5 * fov);
-    float horizontal_fov_factor = width / tan(0.5 * fov);
-    
-    int has_normals = 1;
-    int base = id_x;
-
-
-float object_x =   objects[base].transform.position.x;
-float object_y =   objects[base].transform.position.y;
-float object_z =   objects[base].transform.position.z;
-float object_r_x = objects[base].transform.rotation.w;
-float object_r_y = objects[base].transform.rotation.x;
-float object_r_z = objects[base].transform.rotation.y;
-float object_r_w = objects[base].transform.rotation.z;
-float object_s_x = objects[base].transform.scale.x; 
-float object_s_y = objects[base].transform.scale.y; 
-float object_s_z = objects[base].transform.scale.z; 
-
-int triangle_count = objects[base].modelInfo.triangleCount;
-int triangle_index = objects[base].modelInfo.triangleOffset;
-int vertex_index =   objects[base].modelInfo.vertexOffset;
-int transformed_vertex_index = objects[base].modelInfo.transformedVertexOffset;
-int normal_index =   objects[base].modelInfo.normalOffset;
-int transformed_normal_index =   objects[base].modelInfo.transformedNormalOffset;
-
-for (int triangle = 0; triangle < triangle_count; triangle++){
-int triangle_base = (triangle + triangle_index) * 9; 
-
-int i0 = (vertex_index + triangles[triangle_base + 0]) * 3;
-int i1 = (vertex_index + triangles[triangle_base + 1]) * 3;
-int i2 = (vertex_index + triangles[triangle_base + 2]) * 3;
-
-int i3 = (normal_index + triangles[triangle_base + 3]) * 3;
-int i4 = (normal_index + triangles[triangle_base + 4]) * 3;
-int i5 = (normal_index + triangles[triangle_base + 5]) * 3;
-
-float x0 = verticies[i0 + 0] * object_s_x;
-float y0 = verticies[i0 + 1] * object_s_y;
-float z0 = verticies[i0 + 2] * object_s_z;
-float x1 = verticies[i1 + 0] * object_s_x;
-float y1 = verticies[i1 + 1] * object_s_y;
-float z1 = verticies[i1 + 2] * object_s_z;
-float x2 = verticies[i2 + 0] * object_s_x;
-float y2 = verticies[i2 + 1] * object_s_y;
-float z2 = verticies[i2 + 2] * object_s_z;
-float n_x0 = normals[i3 + 0];
-float n_y0 = normals[i3 + 1];
-float n_z0 = normals[i3 + 2];
-float n_x1 = normals[i4 + 0];
-float n_y1 = normals[i4 + 1];
-float n_z1 = normals[i4 + 2];
-float n_x2 = normals[i5 + 0];
-float n_y2 = normals[i5 + 1];
-float n_z2 = normals[i5 + 2];
-
-if (i3 < 0 || i4 < 0 || i5 < 0){
- //   has_normals = 0;
-}
-
-if (isinf(x0) || isinf(y0) || isinf(z0) || isinf(x1) || isinf(y1) || isinf(z1) || isinf(x2) || isinf(y2) || isinf(z2)){
-continue;
-}
-
-rotate_euler(&x0, &y0, &z0, object_r_x, object_r_y, object_r_z);
-rotate_euler(&x1, &y1, &z1, object_r_x, object_r_y, object_r_z);
-rotate_euler(&x2, &y2, &z2, object_r_x, object_r_y, object_r_z);
-
-rotate_euler(&n_x0, &n_y0, &n_z0, object_r_x, object_r_y, object_r_z);
-rotate_euler(&n_x1, &n_y1, &n_z1, object_r_x, object_r_y, object_r_z);
-rotate_euler(&n_x2, &n_y2, &n_z2, object_r_x, object_r_y, object_r_z);
-
-z0 = (z0 + object_z);
-x0 = (x0 + object_x) / z0 * horizontal_fov_factor;
-y0 = (y0 + object_y) / z0 * vertical_fov_factor;
-z1 = (z1 + object_z);
-x1 = (x1 + object_x) / z1 * horizontal_fov_factor;
-y1 = (y1 + object_y) / z1 * vertical_fov_factor;
-z2 = (z2 + object_z);
-y2 = (y2 + object_y) / z2 * horizontal_fov_factor;
-x2 = (x2 + object_x) / z2 * vertical_fov_factor;
-
-// if ((x0 < -ri_h_width && x1 < -ri_h_width && x2 < -ri_h_width) || (y0 < -ri_h_height && y1 < -ri_h_height && y2 < -ri_h_height) || (x0 >= ri_h_width && x1 >= ri_h_width && x2 >= ri_h_width) || (y0 >= ri_h_height && y1 >= ri_h_height && y2 >= ri_h_height)){
-    // transformed_verticies[(triangles[triangle_base + 0] + transformed_vertex_index) * 3 + 0] = 999999;
-// }
-// else{
-    transformed_verticies[(triangles[triangle_base + 0] + transformed_vertex_index) * 3 + 0] = x0;
-    transformed_verticies[(triangles[triangle_base + 0] + transformed_vertex_index) * 3 + 1] = y0;
-    transformed_verticies[(triangles[triangle_base + 0] + transformed_vertex_index) * 3 + 2] = z0;
-    transformed_verticies[(triangles[triangle_base + 1] + transformed_vertex_index) * 3 + 0] = x1;
-    transformed_verticies[(triangles[triangle_base + 1] + transformed_vertex_index) * 3 + 1] = y1;
-    transformed_verticies[(triangles[triangle_base + 1] + transformed_vertex_index) * 3 + 2] = z1;
-    transformed_verticies[(triangles[triangle_base + 2] + transformed_vertex_index) * 3 + 0] = x2;
-    transformed_verticies[(triangles[triangle_base + 2] + transformed_vertex_index) * 3 + 1] = y2;
-    transformed_verticies[(triangles[triangle_base + 2] + transformed_vertex_index) * 3 + 2] = z2;
-    
-    transformed_normals[(triangles[triangle_base + 0] + transformed_normal_index) * 3 + 0] = n_x0;
-    transformed_normals[(triangles[triangle_base + 0] + transformed_normal_index) * 3 + 1] = n_y0;
-    transformed_normals[(triangles[triangle_base + 0] + transformed_normal_index) * 3 + 2] = n_z0;
-    transformed_normals[(triangles[triangle_base + 1] + transformed_normal_index) * 3 + 0] = n_x1;
-    transformed_normals[(triangles[triangle_base + 1] + transformed_normal_index) * 3 + 1] = n_y1;
-    transformed_normals[(triangles[triangle_base + 1] + transformed_normal_index) * 3 + 2] = n_z1;
-    transformed_normals[(triangles[triangle_base + 2] + transformed_normal_index) * 3 + 0] = n_x2;
-    transformed_normals[(triangles[triangle_base + 2] + transformed_normal_index) * 3 + 1] = n_y2;
-    transformed_normals[(triangles[triangle_base + 2] + transformed_normal_index) * 3 + 2] = n_z2;
-// }
-}}

+ 0 - 196
src/RasterIver/source code/non-lib src/main_CPU.c

@@ -1,196 +0,0 @@
-#include "stdlib.h"
-#include "SDL2/SDL.h"
-#include "math.h"
-#include "time.h"
-#include <CL/cl.h>
-
-const int WIDTH = 800;
-const int HEIGHT = 800;
-const int POLYGON_SIZE = sizeof(float) * 3 * 3;
-const int POLYGONS = 10;
-
-int is_intersecting(int a, int b, int c, int d, int p, int q, int r, int s) {
-    float det, gamma, lambda;
-    
-    det = (c - a) * (s - q) - (r - p) * (d - b);
-    
-    if (det == 0) {
-        return 1;
-    } 
-    else {
-        lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det;
-        gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det;
-        return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1);
-    }
-}
-
-void norm(float dest[2], float a[2]){
-    float magnitude = sqrt((pow(a[0], 2) + pow(a[1], 2)));
-    
-    dest[0] = a[0] / magnitude;
-    dest[1] = a[1] / magnitude;
-}
-
-void sub(float dest[2], float a[2], float b[2]){
-    dest[0] = a[0] - b[0];
-    dest[1] = a[1] - b[1];
-}
-
-void add(float dest[2], float a[2], float b[2]){
-    dest[0] = a[0] + b[0];
-    dest[1] = a[1] + b[1];
-}
-
-int main(){
-    srand(time(NULL));
-
-    float polygons[POLYGONS][3][3];
-
-    SDL_Init(SDL_INIT_VIDEO);
-    SDL_Window* window = SDL_CreateWindow("Rasterizer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
-    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
-    SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
-
-    int running = 1;
-
-    Uint32 frame_buffer[WIDTH * HEIGHT];
-    float z_buffer[WIDTH * HEIGHT];
-
-    int frame = 0;
-
-    Uint32 start_time, frame_time;
-    float fps;
-
-    while (running) {
-        start_time = SDL_GetTicks();
-
-        //if (frame % 1 == 0){
-            for (int p = 0; p < POLYGONS; p++){
-                for (int point = 0; point < 3; point++){
-                    for (int i = 0; i < 3; i++){
-                        polygons[p][point][i] = rand() % WIDTH + 1;
-                    }
-                }
-            }
-        //}
-
-        for (int i = 0; i < WIDTH * HEIGHT; ++i) {
-            frame_buffer[i] = 0x22222222;
-        }
-
-        memset(&z_buffer, 0, sizeof(float) * WIDTH * HEIGHT);
-
-        SDL_Event event;
-        while (SDL_PollEvent(&event)){
-            switch (event.type){
-                case SDL_QUIT:
-                running = 0;
-            }
-        }
-        
-        for (int polygon = 0; polygon < POLYGONS; polygon++){
-            float x0 = polygons[polygon][0][0];
-            float y0 = polygons[polygon][0][1];
-            float z0 = polygons[polygon][0][2];
-            float x1 = polygons[polygon][1][0];
-            float y1 = polygons[polygon][1][1];
-            float z1 = polygons[polygon][1][2];
-            float x2 = polygons[polygon][2][0];
-            float y2 = polygons[polygon][2][1];
-            float z2 = polygons[polygon][2][2];
-            
-            float smallest_x = x0;
-            float largest_x = x0;
-            float smallest_y = y0;
-            float largest_y = y0;
-            
-            for (int point = 0; point < 3; point++){
-                float x = polygons[polygon][point][0];
-                float y = polygons[polygon][point][1];
-                
-                if (x > largest_x){
-                    largest_x = x;
-                }
-                
-                if (x < smallest_x){
-                    smallest_x = x;
-                }
-                
-                if (y > largest_y){
-                    largest_y = y;
-                }
-                
-                if (y < smallest_y){
-                    smallest_y = y;
-                }
-            }
-            
-            smallest_x = fmin(smallest_x, 0);
-            largest_x = fmax(largest_x, WIDTH);
-            smallest_y = fmin(smallest_y, 0);
-            largest_y = fmax(largest_y, HEIGHT);
-
-            // test every pixel in a rect around the triangle. If it's inside, color it.
-            for (int x = (int)smallest_x; x < largest_x; x++){
-                for (int y = (int)smallest_y; y < largest_y; y++){
-                    int intersections = 0;
-                    
-                    for (int i = 0; i < 3; i++){
-                        intersections += is_intersecting(x, y, 10000, 100000, polygons[polygon][i][0], polygons[polygon][i][1], polygons[polygon][(i + 1) % 3][0], polygons[polygon][(i + 1) % 3][1]);
-                    }
-
-                    if (intersections % 2 == 0){
-                        continue;
-                    }
-
-                    float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2);
-                    float w0 = ((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2)) / denominator;
-                    float w1 = ((y2 - y0) * (x - x0) + (x0 - x2) * (y - y2)) / denominator;
-                    float w2 = 1.0 - w0 - w1;
-
-                    if (denominator < 0) {
-                        w0 = -w0;
-                        w1 = -w1;
-                        w2 = -w2;
-                        denominator = -denominator;
-                    }                    
-
-                    float z = w0 * z0 + w1 * z1 + w2 * z2;
-
-                    
-                                        if (z < 0){
-                                            z *= -1;
-                                        }
-                //    printf("%f\n", z);
-
-                    if (z > z_buffer[y * WIDTH + x]){
-                        z_buffer[y * WIDTH + x] = z;
-                    }
-                    else {
-                        continue;
-                    }
-
-                   frame_buffer[y * WIDTH + x] = 0xFFFFFFFF / POLYGONS * (polygon + 1);
-                }
-            }
-        }
-        
-        SDL_UpdateTexture(texture, NULL, frame_buffer, WIDTH * sizeof(Uint32));
-        
-        SDL_RenderClear(renderer);
-        SDL_RenderCopy(renderer, texture, NULL, NULL);
-        SDL_RenderPresent(renderer);
-        
-        frame++;
-
-        frame_time = SDL_GetTicks()-start_time;
-        fps = (frame_time > 0) ? 1000.0f / frame_time : 0.0f;
-        printf("%f fps\n", fps);
-        printf("%d polygons\n", POLYGONS);
-    }
-    
-    SDL_DestroyTexture(texture);
-    SDL_DestroyRenderer(renderer);
-    SDL_DestroyWindow(window);
-    SDL_Quit();
-}

+ 0 - 292
src/RasterIver/source code/non-lib src/main_GPU_fixed_polygons.c

@@ -1,292 +0,0 @@
-// RasterIver static polygons & not a lib
-
-#include "stdlib.h"
-#include "SDL2/SDL.h"
-#include "math.h"
-#include "time.h"
-#include <CL/cl.h>
-
-const char* kernel_source = " \
-int is_intersecting(float a, float b, float c, float d, float p, float q, float r, float s) { \
-    float det, gamma, lambda; \
-    \
-    det = (c - a) * (s - q) - (r - p) * (d - b); \
-    \
-    if (det == 0) { \
-        return 1; \
-    }  \
-    else { \
-        lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; \
-        gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; \
-        return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1); \
-    } \
-} \
-\
-void norm(float dest[2], float a[2]){ \
-    float magnitude = sqrt(a[0] * a[0] + a[1] * a[1]); \
-    \
-    dest[0] = a[0] / magnitude; \
-    dest[1] = a[1] / magnitude; \
-    } \
-    \
-    void sub(float dest[2], float a[2], float b[2]){ \
-    dest[0] = a[0] - b[0]; \
-    dest[1] = a[1] - b[1]; \
-    } \
-    \
-    void add(float dest[2], float a[2], float b[2]){ \
-    dest[0] = a[0] + b[0]; \
-    dest[1] = a[1] + b[1]; \
-} \
-\
-__kernel void raster_kernel(__global float* polygons, __global uint* frame_buffer, int POLYGONS, int WIDTH, int HEIGHT, int SHOW_Z_BUFFER){ \
-    int id_x = get_global_id(0); \
-    int id_y = get_global_id(1); \
-    \
-    float z_pixel = 0; \
-    uint frame_pixel = 0x22222222; \
-    \
-    for (int polygon = 0; polygon < POLYGONS; polygon++){ \
-        int base = polygon * 9; \
-        float x0 = polygons[base]; \
-        float y0 = polygons[base + 1]; \
-        float z0 = polygons[base + 2]; \
-        float x1 = polygons[base + 3]; \
-        float y1 = polygons[base + 4]; \
-        float z1 = polygons[base + 5]; \
-        float x2 = polygons[base + 6]; \
-        float y2 = polygons[base + 7]; \
-        float z2 = polygons[base + 8]; \
-        \
-        float smallest_x = x0; \
-        float largest_x = x0; \
-        float smallest_y = y0; \
-        float largest_y = y0; \
-        \
-        for (int point = 0; point < 3; point++){ \
-            float x = polygons[base + point * 3]; \
-            float y = polygons[base + point * 3 + 1]; \
-            \
-            if (x > largest_x){ \
-                largest_x = x; \
-            } \
-            \
-            if (x < smallest_x){ \
-                smallest_x = x; \
-            } \
-            \
-            if (y > largest_y){ \
-                largest_y = y; \
-            } \
-            \
-            if (y < smallest_y){\
-                smallest_y = y;\
-            } \
-        } \
-        \
-        smallest_x = fmin(smallest_x, 0); \
-        largest_x = fmax(largest_x, WIDTH); \
-        smallest_y = fmin(smallest_y, 0); \
-        largest_y = fmax(largest_y, HEIGHT); \
-        \
-        if (id_x >= smallest_x && id_x <= largest_x && id_y >= smallest_y && id_y <= largest_y){ \
-            int intersections = 0; \
-            \
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x0, y0, x1, y1); \
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x1, y1, x2, y2); \
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x2, y2, x0, y0); \
-            \
-            if (intersections % 2 == 0){ \
-                continue; \
-            } \
-            \
-            float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2); \
-            float w0 = ((y1 - y2) * (id_x - x2) + (x2 - x1) * (id_y - y2)) / denominator; \
-            float w1 = ((y2 - y0) * (id_x - x0) + (x0 - x2) * (id_y - y2)) / denominator; \
-            float w2 = 1.0 - w0 - w1; \
-            \
-            if (denominator < 0) { \
-                w0 = -w0; \
-                w1 = -w1; \
-                w2 = -w2; \
-                denominator = -denominator; \
-            } \
-            \
-            float z = w0 * z0 + w1 * z1 + w2 * z2; \
-            \
-            if (z < 0){ \
-                z *= -1; \
-            } \
-            \
-            if (z > z_pixel){ \
-                z_pixel = z; \
-            } \
-            else { \
-                continue; \
-            } \
-            \
-            frame_pixel = 0xFFFFFFFF / POLYGONS * (polygon + 1); \
-        } \
-    } \
-    \
-    frame_buffer[id_y * WIDTH + id_x] = frame_pixel; \
-    \
-    if (!SHOW_Z_BUFFER){return;}\
-    \
-    float z = clamp(z_pixel, 0.0f, 800.0f);\
-    \
-    float norm_z = z / 800.0f;\
-    \
-    uchar intensity = (uchar)(norm_z * 255.0f);\
-    \
-    frame_buffer[id_y * WIDTH + id_x] = 0xFF000000 | (intensity << 16) | (intensity << 8) | intensity;\
-}\n";
-
-void erchk_func(cl_int error, int line, char *file){
-    if (error != CL_SUCCESS){
-        printf("ERROR :O   %d, line %d at file %s\n", error, line, file);
-        exit(1);
-    }
-}
-
-#define erchk(error) erchk_func(error, __LINE__, __FILE__)
-
-const int WIDTH = 800;
-const int HEIGHT = 800;
-const int POLYGONS = 20000;
-const int SHOW_Z_BUFFER = 0;
-
-int main(){
-    srand(time(NULL));
-
-    float polygons[POLYGONS][3][3];
-
-    cl_uint frame_buffer[WIDTH * HEIGHT];
-    float z_buffer[WIDTH * HEIGHT];
-
-    // ----- Check for Valid Platforms & GPUs
-    cl_platform_id platform;
-    cl_device_id device;
-    cl_uint number_of_platforms, number_of_devices;
-
-    clGetPlatformIDs(1, &platform, &number_of_platforms);
-
-    if(number_of_platforms == 0){
-        printf("No OpenCL Platforms");
-    }
-
-    clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, &number_of_devices);
-
-    if (number_of_devices == 0){
-        printf("No GPU's Found");
-    }
-    // -----
-
-    // ----- Setup OpenCL
-    cl_int error;
-
-    cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
-    cl_command_queue queue = clCreateCommandQueue(context, device, 0, NULL);
-
-    cl_mem input_memory_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float) * 3 * 3 * POLYGONS, polygons, &error);
-    erchk(error);
-
-    cl_mem output_memory_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_uint) * WIDTH * HEIGHT, NULL, &error);
-    erchk(error);
-
-    printf("%ld bytes\n", sizeof(float) * 3 * 3 * POLYGONS + WIDTH * HEIGHT * sizeof(cl_uint));
-
-    cl_program kernel_program = clCreateProgramWithSource(context, 1, &kernel_source, NULL, &error);
-    erchk(error);
-
-    error = clBuildProgram(kernel_program, 1, &device, NULL, NULL, NULL);
-    erchk(error);
-
-    cl_kernel compiled_kernel = clCreateKernel(kernel_program, "raster_kernel", &error);
-    erchk(error);
-
-    erchk(clSetKernelArg(compiled_kernel, 0, sizeof(cl_mem), &input_memory_buffer));
-    erchk(clSetKernelArg(compiled_kernel, 1, sizeof(cl_mem), &output_memory_buffer));
-    erchk(clSetKernelArg(compiled_kernel, 2, sizeof(int), &POLYGONS));
-    erchk(clSetKernelArg(compiled_kernel, 3, sizeof(int), &WIDTH));
-    erchk(clSetKernelArg(compiled_kernel, 4, sizeof(int), &HEIGHT));
-    erchk(clSetKernelArg(compiled_kernel, 5, sizeof(int), &SHOW_Z_BUFFER));
-
-    size_t size_2d[2] = {WIDTH, HEIGHT};
-
-    cl_uint pattern = 0x22222222;
-    // -----
-
-    SDL_Init(SDL_INIT_VIDEO);
-    SDL_Window* window = SDL_CreateWindow("Rasterizer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
-    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
-    SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
-
-    int running = 1;
-
-    int frame = 0;
-
-    Uint64 start_time;
-    double frame_time_ms;
-    double fps;
-
-    while (running) {
-        start_time = SDL_GetPerformanceCounter();
-
-        if (frame % 1 == 0){
-            for (int p = 0; p < POLYGONS; p++){
-                for (int point = 0; point < 3; point++){
-                    for (int i = 0; i < 3; i++){
-                        polygons[p][point][i] = rand() % WIDTH + 1;
-                    }
-                }
-            }
-        }
-
-        memset(&z_buffer, 0, sizeof(float) * WIDTH * HEIGHT);
-
-        erchk(clEnqueueWriteBuffer(queue, input_memory_buffer, CL_TRUE, 0, sizeof(float) * 3 * 3 * POLYGONS, polygons, 0, NULL, NULL));
-
-        erchk(clEnqueueFillBuffer(queue, output_memory_buffer, &pattern, sizeof(cl_uint), 0, sizeof(cl_uint) * WIDTH * HEIGHT, 0, NULL, NULL));
-
-        erchk(clEnqueueNDRangeKernel(queue, compiled_kernel, 2, NULL, size_2d, NULL, 0, NULL, NULL));
-
-        erchk(clFinish(queue));
-
-        erchk(clEnqueueReadBuffer(queue, output_memory_buffer, CL_TRUE, 0, sizeof(cl_uint) * WIDTH * HEIGHT, &frame_buffer, 0, NULL, NULL));
-
-        SDL_Event event;
-        while (SDL_PollEvent(&event)){
-            switch (event.type){
-                case SDL_QUIT:
-                running = 0;
-            }
-        }
-        
-        SDL_UpdateTexture(texture, NULL, frame_buffer, WIDTH * sizeof(cl_uint));
-        
-        SDL_RenderClear(renderer);
-        SDL_RenderCopy(renderer, texture, NULL, NULL);
-        SDL_RenderPresent(renderer);
-        
-        frame++;
-
-        double delta_time = (double)(SDL_GetPerformanceCounter() - start_time) / (double)SDL_GetPerformanceFrequency();
-        double fps = 1.0 / delta_time;
-
-        printf("%lf fps\n", fps);
-        printf("%d polygons\n", POLYGONS);
-    }
-    
-    clReleaseMemObject(input_memory_buffer);
-    clReleaseMemObject(output_memory_buffer);
-    clReleaseKernel(compiled_kernel);
-    clReleaseProgram(kernel_program);
-    clReleaseCommandQueue(queue);
-    clReleaseContext(context);
-
-    SDL_DestroyTexture(texture);
-    SDL_DestroyRenderer(renderer);
-    SDL_DestroyWindow(window);
-    SDL_Quit();
-}

+ 0 - 253
src/RasterIver/source code/non-lib src/main_test.c

@@ -1,253 +0,0 @@
-#include "stdlib.h"
-#include "SDL2/SDL.h"
-#include "math.h"
-#include "time.h"
-#include <CL/cl.h>
-
-const int WIDTH = 800;
-const int HEIGHT = 800;
-const int POLYGON_SIZE = sizeof(float) * 3 * 3;
-const int POLYGONS = 5;
-
-int is_intersecting(int a, int b, int c, int d, int p, int q, int r, int s) {
-    float det, gamma, lambda;
-    
-    det = (c - a) * (s - q) - (r - p) * (d - b);
-    
-    if (det == 0) {
-        return 1;
-    } 
-    else {
-        lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det;
-        gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det;
-        return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1);
-    }
-}
-
-void norm(float dest[2], float a[2]){
-    float magnitude = sqrt((pow(a[0], 2) + pow(a[1], 2)));
-    
-    dest[0] = a[0] / magnitude;
-    dest[1] = a[1] / magnitude;
-}
-
-void sub(float dest[2], float a[2], float b[2]){
-    dest[0] = a[0] - b[0];
-    dest[1] = a[1] - b[1];
-}
-
-void add(float dest[2], float a[2], float b[2]){
-    dest[0] = a[0] + b[0];
-    dest[1] = a[1] + b[1];
-}
-
-const char* kernel_source = 
-"__kernel void raster_kernel(__global float* polygons, __global uint* frame_buffer)\n"
-"int id = get_global_id(0); \n"
-" \n"
-" \n"
-"frame_buffer[id] = 80085; \n"
-" \n"
-"}\n";
-
-int main(){
-    srand(time(NULL));
-
-    float polygons[POLYGONS][3][3];
-
-    cl_uint frame_buffer[WIDTH * HEIGHT];
-    float z_buffer[WIDTH * HEIGHT];
-
-    // ----- Check for Valid Platforms & GPUs
-    cl_platform_id platform;
-    cl_device_id device;
-    cl_uint number_of_platforms, number_of_devices;
-
-    clGetPlatformIDs(1, &platform, &number_of_platforms);
-
-    if(number_of_platforms == 0){
-        printf("No OpenCL Platforms");
-    }
-
-    clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, &number_of_devices);
-
-    if (number_of_devices == 0){
-        printf("No GPU's Found");
-    }
-    // -----
-
-    // ----- Setup OpenCL
-    cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
-    cl_command_queue queue = clCreateCommandQueue(context, device, 0, NULL);
-
-    cl_mem input_memory_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float) * 3 * 3 * POLYGONS, polygons, NULL);
-    cl_mem output_memory_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_uint) * POLYGONS, NULL, NULL);
-
-    cl_program kernel_program = clCreateProgramWithSource(context, 1, &kernel_source, NULL, NULL);
-    clBuildProgram(kernel_program, 1, &device, NULL, NULL, NULL);
-    cl_kernel compiled_kernel = clCreateKernel(kernel_program, "raster_kernel", NULL);
-    clSetKernelArg(compiled_kernel, 0, sizeof(cl_mem), &input_memory_buffer);
-    clSetKernelArg(compiled_kernel, 1, sizeof(cl_mem), &output_memory_buffer);
-
-    size_t size = POLYGONS;
-
-    cl_uint pattern = 121212;
-    // -----
-
-    SDL_Init(SDL_INIT_VIDEO);
-    SDL_Window* window = SDL_CreateWindow("Rasterizer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
-    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
-    SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
-
-    int running = 1;
-
-    int frame = 0;
-
-    Uint32 start_time, frame_time;
-    float fps;
-
-    while (running) {
-        start_time = SDL_GetTicks();
-
-        //if (frame % 1 == 0){
-            for (int p = 0; p < POLYGONS; p++){
-                for (int point = 0; point < 3; point++){
-                    for (int i = 0; i < 3; i++){
-                        polygons[p][point][i] = rand() % WIDTH + 1;
-                    }
-                }
-            }
-        //}
-
-        memset(&z_buffer, 0, sizeof(float) * WIDTH * HEIGHT);
-
-        clEnqueueFillBuffer(queue, output_memory_buffer, &pattern, sizeof(cl_uint), 0, sizeof(cl_uint) * POLYGONS, 0, NULL, NULL);
-
-        clEnqueueNDRangeKernel(queue, compiled_kernel, 1, NULL, &size, NULL, 0, NULL, NULL);
-
-        clFinish(queue);
-
-        clEnqueueReadBuffer(queue, output_memory_buffer, CL_TRUE, 0, sizeof(cl_uint) * POLYGONS, &frame_buffer, 0, NULL, NULL);
-
-        for (int i = 0; i < POLYGONS; i++){
-            printf("%u\n", frame_buffer[i]);
-        }
-
-        SDL_Event event;
-        while (SDL_PollEvent(&event)){
-            switch (event.type){
-                case SDL_QUIT:
-                running = 0;
-            }
-        }
-        
-        // for (int polygon = 0; polygon < POLYGONS; polygon++){
-        //     float x0 = polygons[polygon][0][0];
-        //     float y0 = polygons[polygon][0][1];
-        //     float z0 = polygons[polygon][0][2];
-        //     float x1 = polygons[polygon][1][0];
-        //     float y1 = polygons[polygon][1][1];
-        //     float z1 = polygons[polygon][1][2];
-        //     float x2 = polygons[polygon][2][0];
-        //     float y2 = polygons[polygon][2][1];
-        //     float z2 = polygons[polygon][2][2];
-            
-        //     float smallest_x = x0;
-        //     float largest_x = x0;
-        //     float smallest_y = y0;
-        //     float largest_y = y0;
-            
-        //     for (int point = 0; point < 3; point++){
-        //         float x = polygons[polygon][point][0];
-        //         float y = polygons[polygon][point][1];
-                
-        //         if (x > largest_x){
-        //             largest_x = x;
-        //         }
-                
-        //         if (x < smallest_x){
-        //             smallest_x = x;
-        //         }
-                
-        //         if (y > largest_y){
-        //             largest_y = y;
-        //         }
-                
-        //         if (y < smallest_y){
-        //             smallest_y = y;
-        //         }
-        //     }
-            
-        //     smallest_x = fmin(smallest_x, 0);
-        //     largest_x = fmax(largest_x, WIDTH);
-        //     smallest_y = fmin(smallest_y, 0);
-        //     largest_y = fmax(largest_y, HEIGHT);
-
-        //     // test every pixel in a rect around the triangle. If it's inside, color it.
-        //     for (int x = (int)smallest_x; x < largest_x; x++){
-        //         for (int y = (int)smallest_y; y < largest_y; y++){
-        //             int intersections = 0;
-                    
-        //             for (int i = 0; i < 3; i++){
-        //                 intersections += is_intersecting(x, y, 10000, 100000, polygons[polygon][i][0], polygons[polygon][i][1], polygons[polygon][(i + 1) % 3][0], polygons[polygon][(i + 1) % 3][1]);
-        //             }
-
-        //             if (intersections % 2 == 0){
-        //                 continue;
-        //             }
-
-        //             float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2);
-        //             float w0 = ((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2)) / denominator;
-        //             float w1 = ((y2 - y0) * (x - x0) + (x0 - x2) * (y - y2)) / denominator;
-        //             float w2 = 1.0 - w0 - w1;
-
-        //             if (denominator < 0) {
-        //                 w0 = -w0;
-        //                 w1 = -w1;
-        //                 w2 = -w2;
-        //                 denominator = -denominator;
-        //             }                    
-
-        //             float z = w0 * z0 + w1 * z1 + w2 * z2;
-
-        //             if (z < z_buffer[y * WIDTH + x]){
-        //                 z_buffer[y * WIDTH + x] = z;
-        //             }
-        //             else {
-        //                 continue;
-        //             }
-
-        //             if (z < 0){
-        //                 z *= -1;
-        //             }
-
-        //            frame_buffer[y * WIDTH + x] = 0xFFFFFFFF / POLYGONS * (polygon + 1);
-        //         }
-        //     }
-        // }
-        SDL_UpdateTexture(texture, NULL, frame_buffer, WIDTH * sizeof(cl_uint));
-        
-        SDL_RenderClear(renderer);
-        SDL_RenderCopy(renderer, texture, NULL, NULL);
-        SDL_RenderPresent(renderer);
-        
-        frame++;
-
-        frame_time = SDL_GetTicks()-start_time;
-        fps = (frame_time > 0) ? 1000.0f / frame_time : 0.0f;
-        // printf("%f fps\n", fps);
-        // printf("%d polygons\n", POLYGONS);
-    }
-    
-    clReleaseMemObject(input_memory_buffer);
-    clReleaseMemObject(output_memory_buffer);
-    clReleaseKernel(compiled_kernel);
-    clReleaseProgram(kernel_program);
-    clReleaseCommandQueue(queue);
-    clReleaseContext(context);
-
-    SDL_DestroyTexture(texture);
-    SDL_DestroyRenderer(renderer);
-    SDL_DestroyWindow(window);
-    SDL_Quit();
-}

File diff suppressed because it is too large
+ 0 - 175
src/RasterIver/source code/rasteriver.c


+ 35 - 0
src/headers/functions.h

@@ -0,0 +1,35 @@
+#ifndef FUNCTIONS_H
+#define FUNCTIONS_H
+
+#include "types.h"
+
+// returns the RI_context
+RI_context *RI_get_context();
+
+// initilizes RasterIver
+// returns completion code (0: fine, 1: error)
+int RI_init();
+
+// ticks RasterIver (updated window, check for events, renders scene, etc)
+void RI_tick();
+
+// renders a scene onto a texture
+// set the texture to NULL to render to the window's framebuffer
+void RI_render(RI_texture* texture, RI_scene *scene);
+
+// loads an OBJ file into memory as a mesh
+RI_mesh *RI_load_mesh(char* filename, RI_actor *actor);
+
+// allocates and returns a pointer to a new scene
+RI_scene *RI_new_scene();
+
+// allocates and returns a pointer to a new actor
+RI_actor *RI_new_actor();
+
+// allocates and returns a pointer to a new material
+RI_material *RI_new_material();
+
+// allocates and returns a pointer to a new texture
+RI_texture *RI_new_texture(int width, int height);
+
+#endif

+ 169 - 0
src/headers/math.h

@@ -0,0 +1,169 @@
+#ifndef MATH_H
+#define MATH_H
+
+#include "stdint.h"
+#include <math.h>
+#include <CL/cl.h>
+
+typedef struct {
+    cl_double w;
+    cl_double x;
+    cl_double y;
+    cl_double z;
+} RI_vector_4;
+
+typedef struct {
+    cl_double x;
+    cl_double y;
+    cl_double z;
+} RI_vector_3;
+    
+typedef struct {
+    cl_double x;
+    cl_double y;
+} RI_vector_2;
+
+typedef struct {
+    cl_int x;
+    cl_int y;
+} RI_vector_2i;
+
+// value-wise multiplacation.
+// multiply the whole vector by 1 value
+void vector_2_times(RI_vector_2 *vector, double value){
+    vector->x *= value;
+    vector->y *= value;
+}
+
+// value-wise multiplacation.
+// multiply the whole vector by 1 value
+void vector_3_times(RI_vector_3 *vector, double value){
+    vector->x *= value;
+    vector->y *= value;
+    vector->z *= value;
+}
+
+// "hadamard" addition.
+// add each value of one vector with the matching one on the other vector
+void vector_2_element_wise_add(RI_vector_2 *addend_a, RI_vector_2 addend_b){
+    addend_a->x += addend_b.x;
+    addend_a->y += addend_b.y;
+}
+
+// hadamard multiplacation.
+// multiply each value of one vector with the matching one on the other vector
+void vector_3_hadamard(RI_vector_3 *multiplicand, RI_vector_3 multiplicator){
+    multiplicand->x *= multiplicator.x;
+    multiplicand->y *= multiplicator.y;
+    multiplicand->z *= multiplicator.z;
+}
+
+// "hadamard" addition.
+// add each value of one vector with the matching one on the other vector
+void vector_3_element_wise_add(RI_vector_3 *addend_a, RI_vector_3 addend_b){
+    addend_a->x += addend_b.x;
+    addend_a->y += addend_b.y;
+    addend_a->z += addend_b.z;
+}
+
+// "hadamard" subtraction.
+// subtraction each value of one vector with the matching one on the other vector
+void vector_3_element_wise_subtract(RI_vector_3 *minuend, RI_vector_3 subtrahend){
+    minuend->x -= subtrahend.x;
+    minuend->y -= subtrahend.y;
+    minuend->z -= subtrahend.z;
+}
+
+// conjugate a quaterion.
+// (flip the sign of the x, y, z values)
+void quaternion_conjugate(RI_vector_4* quaternion){
+    quaternion->x *= -1.0;
+    quaternion->y *= -1.0;
+    quaternion->z *= -1.0;
+}
+
+// quaternion multiplacation
+void quaternion_multiply(RI_vector_4* a, RI_vector_4 b){
+    double w1 = a->w; double x1 = a->x; double y1 = a->y; double z1 = a->z;
+    double w2 = b.w; double x2 = b.x; double y2 = b.y; double z2 = b.z;
+
+    double w = w1*w2 - x1*x2 - y1*y2 - z1*z2;
+    double x = w1*x2 + x1*w2 + y1*z2 - z1*y2;
+    double y = w1*y2 - x1*z2 + y1*w2 + z1*x2;
+    double z = w1*z2 + x1*y2 - y1*x2 + z1*w2;
+
+    *a = (RI_vector_4){w, x, y, z};
+}
+
+// linear interpolate between 2 vectors
+void vector_2_lerp(RI_vector_2 vector_a, RI_vector_2 vector_b, RI_vector_2 *result, double w1){
+    double w0 = 1.0 - w1;
+
+    vector_2_times(result, 0);
+
+    vector_2_times(&vector_a, w0);
+    vector_2_times(&vector_b, w1);
+
+    vector_2_element_wise_add(result, vector_a);
+    vector_2_element_wise_add(result, vector_b);
+}
+
+// beziate between 2 vectors.
+// A & C: end points of the line
+// B: point that determines the curve; off the line
+void vector_2_bezier_interpolate(RI_vector_2 vector_a, RI_vector_2 vector_b, RI_vector_2 vector_c, RI_vector_2 *result, double w1){
+    double w0 = 1.0 - w1;
+
+    vector_2_lerp(vector_a, vector_b, &vector_b, w1); // this works because the first vector b is a copy and the second is a reference
+    vector_2_lerp(vector_b, vector_c, &vector_c, w1);
+
+    vector_2_lerp(vector_b, vector_c, result, w1);
+}
+
+// linear interpolate between 2 vectors
+void vector_3_lerp(RI_vector_3 vector_a, RI_vector_3 vector_b, RI_vector_3 *result, double w1){
+    double w0 = 1.0 - w1;
+
+    vector_3_times(result, 0);
+
+    vector_3_times(&vector_a, w0);
+    vector_3_times(&vector_b, w1);
+
+    vector_3_element_wise_add(result, vector_a);
+    vector_3_element_wise_add(result, vector_b);
+}
+
+// returns the distance between 2 points
+int distance_2(RI_vector_2 a, RI_vector_2 b){
+    return (int)sqrtf((double)((double)(a.x - b.x) * (double)(a.x - b.x)) + (double)((double)(a.y - b.y) * (double)(a.y - b.y)));
+}
+
+void quaternion_rotate(RI_vector_3 *position, RI_vector_4 rotation){
+    RI_vector_4 pos_quat = {0, position->x, position->y, position->z};
+
+    RI_vector_4 rotation_conjugation = rotation;
+    quaternion_conjugate(&rotation_conjugation);
+
+    quaternion_multiply(&rotation, pos_quat);
+
+    quaternion_multiply(&rotation, rotation_conjugation);
+
+
+    *position = (RI_vector_3){rotation.x, rotation.y, rotation.z};
+}
+
+void RI_euler_rotation_to_quaternion(RI_vector_4 *quaternion, RI_vector_3 euler_rotation){
+    double cx = cosf(euler_rotation.x * 0.5f);
+    double sx = sinf(euler_rotation.x * 0.5f);
+    double cy = cosf(euler_rotation.y * 0.5f);
+    double sy = sinf(euler_rotation.y * 0.5f);
+    double cz = cosf(euler_rotation.z * 0.5f);
+    double sz = sinf(euler_rotation.z * 0.5f);
+
+    quaternion->w = cx * cy * cz + sx * sy * sz;
+    quaternion->x = sx * cy * cz - cx * sy * sz;
+    quaternion->y = cx * sy * cz + sx * cy * sz;
+    quaternion->z = cx * cy * sz - sx * sy * cz;
+}
+
+#endif

+ 127 - 0
src/headers/memory.h

@@ -0,0 +1,127 @@
+#include "types.h"
+
+RI_context context;
+
+#define RI_realloc(__ptr, __size) written_RI_realloc(__ptr, __size, __func__, __LINE__, context)
+#define RI_malloc(__size) written_RI_malloc(__size, __func__, __LINE__, context)
+#define RI_calloc(__nmemb, __size) written_RI_calloc(__nmemb, __size, __func__, __LINE__, context)
+#define RI_free(__ptr) written_RI_free(__ptr, __func__, __LINE__, context)
+
+void* written_RI_realloc(void *__ptr, size_t __size, const char *caller, int line, RI_context context){
+    void *pointer = realloc(__ptr, __size);
+
+    if (context.memory.debug_memory) {
+        int current_allocation_index = 0;
+        int checking = 1;
+
+        while (checking){
+            if (!context.memory.allocation_table[current_allocation_index].reallocated_free && context.memory.allocation_table[current_allocation_index].pointer == __ptr){
+                context.memory.allocation_table[current_allocation_index].reallocated_free = 1;
+                
+                checking = 0;
+            }
+
+            current_allocation_index++;
+            
+            if (current_allocation_index >= context.memory.allocation_search_limit){
+                checking = 0;
+            }
+        }
+
+        if (context.memory.current_allocation_index >= context.memory.allocation_table_length){
+            context.memory.allocation_table_length += 50;
+            context.memory.allocation_search_limit += 50;
+            
+            context.memory.allocation_table = RI_realloc(context.memory.allocation_table, sizeof(RI_memory_allocation) * context.memory.allocation_table_length);
+        }
+
+        context.memory.allocation_table[context.memory.current_allocation_index].allocated = 1;
+        context.memory.allocation_table[context.memory.current_allocation_index].reallocated_alloc = 1;
+        context.memory.allocation_table[context.memory.current_allocation_index].reallocated_free = 0;
+        context.memory.allocation_table[context.memory.current_allocation_index].freed = 0;
+        context.memory.allocation_table[context.memory.current_allocation_index].line = line;
+        context.memory.allocation_table[context.memory.current_allocation_index].pointer = pointer;        
+        context.memory.allocation_table[context.memory.current_allocation_index].size = __size;
+
+        context.memory.current_allocation_index++;
+    }
+
+    return pointer;
+}
+
+void* written_RI_malloc(size_t __size, const char *caller, int line, RI_context context){
+    void *pointer = malloc(__size);
+    
+    if (context.memory.debug_memory) {
+        if (context.memory.current_allocation_index >= context.memory.allocation_table_length){
+            context.memory.allocation_table_length += 50;
+            context.memory.allocation_search_limit += 50;
+            
+            context.memory.allocation_table = RI_realloc(context.memory.allocation_table, sizeof(RI_memory_allocation) * context.memory.allocation_table_length);
+        }
+
+        context.memory.allocation_table[context.memory.current_allocation_index].allocated = 1;
+        context.memory.allocation_table[context.memory.current_allocation_index].reallocated_free = 0;
+        context.memory.allocation_table[context.memory.current_allocation_index].reallocated_alloc = 0;
+        context.memory.allocation_table[context.memory.current_allocation_index].freed = 0;
+        context.memory.allocation_table[context.memory.current_allocation_index].line = line;
+        context.memory.allocation_table[context.memory.current_allocation_index].pointer = pointer;        
+        context.memory.allocation_table[context.memory.current_allocation_index].size = __size;
+
+        context.memory.current_allocation_index++;
+    }
+
+    return pointer;
+}
+
+void* written_RI_calloc(size_t __nmemb, size_t __size, const char *caller, int line, RI_context context){
+    void *pointer = calloc(__nmemb, __size);
+    
+    if (context.memory.debug_memory) {
+        if (context.memory.current_allocation_index >= context.memory.allocation_table_length){
+            context.memory.allocation_table_length += 50;
+            context.memory.allocation_search_limit += 50;
+            
+            context.memory.allocation_table = RI_realloc(context.memory.allocation_table, sizeof(RI_memory_allocation) * context.memory.allocation_table_length);
+        }
+
+        context.memory.allocation_table[context.memory.current_allocation_index].allocated = 1;
+        context.memory.allocation_table[context.memory.current_allocation_index].reallocated_free = 0;
+        context.memory.allocation_table[context.memory.current_allocation_index].reallocated_alloc = 0;
+        context.memory.allocation_table[context.memory.current_allocation_index].freed = 0;
+        context.memory.allocation_table[context.memory.current_allocation_index].line = line;
+        context.memory.allocation_table[context.memory.current_allocation_index].pointer = pointer;        
+        context.memory.allocation_table[context.memory.current_allocation_index].size = __size * __nmemb;
+            
+        context.memory.current_allocation_index++;
+    }
+
+    return pointer;
+}
+
+void written_RI_free(void *__ptr, const char *caller, int line){
+    if (context.memory.debug_memory) {
+        // size_t size = 0;
+        
+        int current_allocation_index = 0;
+        int checking = 1;
+        
+        while (checking){
+            if (!context.memory.allocation_table[current_allocation_index].reallocated_free && context.memory.allocation_table[current_allocation_index].pointer == __ptr){
+                // i dont know what this does?
+                // size = context.memory.allocation_table[current_allocation_index].size;
+                context.memory.allocation_table[current_allocation_index].freed = 1;
+                
+                checking = 0;
+            }
+            
+            current_allocation_index++;
+            
+            if (current_allocation_index >= context.memory.allocation_search_limit){
+                checking = 0;
+            }
+        }
+    }
+ 
+    free(__ptr);
+}

+ 8 - 0
src/headers/rasteriver.h

@@ -0,0 +1,8 @@
+#ifndef RASTERIVER_H
+#define RASTERIVER_H
+
+#include "types.h"
+#include "functions.h"
+#include "math.h"
+
+#endif

+ 160 - 0
src/headers/types.h

@@ -0,0 +1,160 @@
+#ifndef STRUCTS_H
+#define STRUCTS_H
+
+#include <SDL2/SDL.h>
+#include <CL/cl.h>
+#include "math.h"
+
+typedef enum {
+    ri_true = 1,
+    ri_false = 0,
+} ri_bool;
+
+typedef struct { // A loaded texture file
+    uint32_t *image_buffer;
+    RI_vector_2i resolution;
+} RI_texture;
+
+typedef struct {
+    cl_uint position_0_index;
+    cl_uint position_1_index;
+    cl_uint position_2_index;
+
+    cl_uint normal_0_index;
+    cl_uint normal_1_index;
+    cl_uint normal_2_index;
+
+    cl_uint uv_0_index;
+    cl_uint uv_1_index;
+    cl_uint uv_2_index;
+
+    cl_uint should_render;
+} RI_face;
+
+typedef struct {
+    RI_face *faces;
+    RI_vector_3 *vertex_positions;
+    RI_vector_3 *normals;
+    RI_vector_2 *uvs;
+    cl_uint face_count, vertex_count, normal_count, uv_count;
+    cl_uint has_normals, has_uvs;
+} RI_mesh;
+
+typedef struct {
+    double r, g, b;
+} RI_color;
+
+typedef struct {
+    uint32_t albedo;
+} RI_material;
+
+typedef struct {
+    RI_vector_3 position;
+    RI_vector_4 rotation;
+    RI_vector_3 scale;
+    ri_bool active;
+    ri_bool has_normals;
+    ri_bool has_uvs;
+    int material_index;
+    int face_index;
+    int face_count;
+} RI_actor;
+
+typedef struct {
+    RI_vector_3 position_0, position_1, position_2;
+    RI_vector_3 normal_0, normal_1, normal_2;
+    RI_vector_2 uv_0, uv_1, uv_2;
+    int min_screen_x, max_screen_x, min_screen_y, max_screen_y;
+    int should_render;
+    int shrunk;
+    int split;
+} RI_renderable_face;
+
+typedef struct {
+    RI_vector_3 position;
+    RI_vector_4 rotation;
+    float FOV, min_clip, max_clip;
+} RI_camera;
+
+typedef struct {
+    RI_actor **actors;
+    RI_camera camera;
+    int length_of_actors_array, face_count;
+} RI_scene;
+
+typedef struct {
+    size_t size;
+    void *pointer;
+    int reallocated_free;
+    int reallocated_alloc;
+    int freed;
+    int allocated;
+    int line;
+} RI_memory_allocation;
+
+typedef struct {
+    int width, height, half_width, half_height;
+    char* title;
+} RI_window;
+
+typedef struct {
+    SDL_Window *window;
+    SDL_Renderer *renderer;
+    SDL_Texture *frame_buffer_texture;
+    uint32_t *frame_buffer_intermediate;
+    RI_texture *frame_buffer;
+    int pitch;
+} RI_SDL;
+
+typedef struct {
+    cl_platform_id platform;
+    cl_device_id device;
+    cl_context context;
+    cl_command_queue queue;
+    cl_kernel rasterization_kernel;
+    cl_kernel transformation_kernel;
+    cl_mem renderable_faces_mem_buffer;
+    cl_mem faces_mem_buffer;
+    cl_mem frame_buffer_mem_buffer;
+    cl_mem vertecies_mem_buffer;
+    cl_mem normals_mem_buffer;
+    cl_mem uvs_mem_buffer;
+    RI_renderable_face *faces_to_render;
+    RI_face *faces;
+    RI_vector_3 *vertecies;
+    RI_vector_3 *normals;
+    RI_vector_2 *uvs;
+    int face_count;
+    int vertex_count;
+    int normal_count;
+    int uv_count;
+    int length_of_renderable_faces_array;
+} RI_CL;
+
+typedef struct {
+    ri_bool debug_memory;
+    RI_memory_allocation *allocation_table;
+    int current_allocation_index;
+    int allocation_search_limit;
+    int allocation_table_length;
+} RI_memory;
+
+typedef struct {
+    RI_actor *default_actor;
+} RI_defaults;
+
+typedef struct {
+    RI_window window;
+    RI_SDL sdl;
+    RI_CL opencl;
+    RI_memory memory;
+    RI_defaults defaults;
+    ri_bool is_running;
+    char* debug_prefix;
+    ri_bool should_debug;   
+    int current_renderable_face_index;
+    int current_split_renderable_face_index;
+    int current_frame;
+} RI_context;
+
+#endif

+ 644 - 0
src/kernels/kernels.cl

@@ -0,0 +1,644 @@
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+typedef struct {
+    double w;
+    double x;
+    double y;
+    double z;
+} RI_vector_4;
+    
+typedef struct {
+    double x;
+    double y;
+    double z;
+} RI_vector_3;
+
+typedef struct {
+    double x;
+    double y;
+} RI_vector_2;
+
+typedef struct {
+    RI_vector_3 position_0, position_1, position_2;
+    RI_vector_3 normal_0, normal_1, normal_2;
+    RI_vector_2 uv_0, uv_1, uv_2;
+    int min_screen_x, max_screen_x, min_screen_y, max_screen_y;
+    int should_render;
+    int shrunk;
+    int split;
+} RI_renderable_face;
+
+typedef struct {
+    int position_0_index;
+    int position_1_index;
+    int position_2_index;
+
+    int normal_0_index;
+    int normal_1_index;
+    int normal_2_index;
+
+    int uv_0_index;
+    int uv_1_index;
+    int uv_2_index;
+
+    int should_render;
+} RI_face;
+
+typedef struct {
+    RI_vector_3 position;
+    RI_vector_4 rotation;
+    RI_vector_3 scale;;
+    int active;
+    int has_normals;
+    int has_uvs;
+    int material_index;
+    int face_index;
+    int face_count;
+} RI_actor;
+
+typedef struct {
+    RI_vector_3 position;
+    RI_vector_4 rotation;
+    float FOV, min_clip, max_clip;
+} RI_camera;
+
+// value-wise multiplacation.
+// multiply the whole vector by 1 value
+void vector_2_times(RI_vector_2 *vector, double value){
+    vector->x *= value;
+    vector->y *= value;
+}
+
+void global_vector_2_times(__global RI_vector_2 *vector, double value){
+    vector->x *= value;
+    vector->y *= value;
+}
+
+// value-wise multiplacation.
+// multiply the whole vector by 1 value
+void vector_3_times(RI_vector_3 *vector, double value){
+    vector->x *= value;
+    vector->y *= value;
+    vector->z *= value;
+}
+
+void global_vector_3_times(__global RI_vector_3 *vector, double value){
+    vector->x *= value;
+    vector->y *= value;
+    vector->z *= value;
+}
+
+// hadamard multiplacation.
+// multiply each value of one vector with the matching one on the other vector
+void vector_3_hadamard(RI_vector_3 *multiplicand, RI_vector_3 multiplicator){
+    multiplicand->x *= multiplicator.x;
+    multiplicand->y *= multiplicator.y;
+    multiplicand->z *= multiplicator.z;
+}
+
+void global_vector_3_hadamard(__global RI_vector_3 *multiplicand, RI_vector_3 multiplicator){
+    multiplicand->x *= multiplicator.x;
+    multiplicand->y *= multiplicator.y;
+    multiplicand->z *= multiplicator.z;
+}
+
+// "hadamard" addition.
+// add each value of one vector with the matching one on the other vector
+void vector_2_element_wise_add(RI_vector_2 *addend_a, RI_vector_2 addend_b){
+    addend_a->x += addend_b.x;
+    addend_a->y += addend_b.y;
+}
+
+void global_vector_2_element_wise_add(__global RI_vector_2 *addend_a, RI_vector_2 addend_b){
+    addend_a->x += addend_b.x;
+    addend_a->y += addend_b.y;
+}
+
+// "hadamard" addition.
+// add each value of one vector with the matching one on the other vector
+void vector_3_element_wise_add(RI_vector_3 *addend_a, RI_vector_3 addend_b){
+    addend_a->x += addend_b.x;
+    addend_a->y += addend_b.y;
+    addend_a->z += addend_b.z;
+}
+
+void global_vector_3_element_wise_add(__global RI_vector_3 *addend_a, RI_vector_3 addend_b){
+    addend_a->x += addend_b.x;
+    addend_a->y += addend_b.y;
+    addend_a->z += addend_b.z;
+}
+
+// "hadamard" subtraction.
+// subtraction each value of one vector with the matching one on the other vector
+void vector_3_element_wise_subtract(RI_vector_3 *minuend, RI_vector_3 subtrahend){
+    minuend->x -= subtrahend.x;
+    minuend->y -= subtrahend.y;
+    minuend->z -= subtrahend.z;
+}
+
+void global_vector_3_element_wise_subtract(__global RI_vector_3 *minuend, RI_vector_3 subtrahend){
+    minuend->x -= subtrahend.x;
+    minuend->y -= subtrahend.y;
+    minuend->z -= subtrahend.z;
+}
+
+// conjugate a quaterion.
+// (flip the sign of the x, y, z values)
+void quaternion_conjugate(RI_vector_4* quaternion){
+    quaternion->x *= -1.0;
+    quaternion->y *= -1.0;
+    quaternion->z *= -1.0;
+}
+
+void globla_quaternion_conjugate(__global RI_vector_4* quaternion){
+    quaternion->x *= -1.0;
+    quaternion->y *= -1.0;
+    quaternion->z *= -1.0;
+}
+
+// quaternion multiplacation
+void quaternion_multiply(RI_vector_4* a, RI_vector_4 b){
+    double w1 = a->w; double x1 = a->x; double y1 = a->y; double z1 = a->z;
+    double w2 = b.w; double x2 = b.x; double y2 = b.y; double z2 = b.z;
+
+    double w = w1*w2 - x1*x2 - y1*y2 - z1*z2;
+    double x = w1*x2 + x1*w2 + y1*z2 - z1*y2;
+    double y = w1*y2 - x1*z2 + y1*w2 + z1*x2;
+    double z = w1*z2 + x1*y2 - y1*x2 + z1*w2;
+
+    *a = (RI_vector_4){w, x, y, z};
+}
+
+void global_quaternion_multiply(__global RI_vector_4* a, RI_vector_4 b){
+    double w1 = a->w; double x1 = a->x; double y1 = a->y; double z1 = a->z;
+    double w2 = b.w; double x2 = b.x; double y2 = b.y; double z2 = b.z;
+
+    double w = w1*w2 - x1*x2 - y1*y2 - z1*z2;
+    double x = w1*x2 + x1*w2 + y1*z2 - z1*y2;
+    double y = w1*y2 - x1*z2 + y1*w2 + z1*x2;
+    double z = w1*z2 + x1*y2 - y1*x2 + z1*w2;
+
+    *a = (RI_vector_4){w, x, y, z};
+}
+
+// linear interpolate between 2 vectors
+void vector_2_lerp(RI_vector_2 vector_a, RI_vector_2 vector_b, RI_vector_2 *result, double w1){
+    double w0 = 1.0 - w1;
+
+    vector_2_times(result, 0);
+
+    vector_2_times(&vector_a, w0);
+    vector_2_times(&vector_b, w1);
+
+    vector_2_element_wise_add(result, vector_a);
+    vector_2_element_wise_add(result, vector_b);
+}
+
+void global_vector_2_lerp(RI_vector_2 vector_a, RI_vector_2 vector_b, __global RI_vector_2 *result, double w1){
+    double w0 = 1.0 - w1;
+
+    global_vector_2_times(result, 0);
+
+    vector_2_times(&vector_a, w0);
+    vector_2_times(&vector_b, w1);
+
+    global_vector_2_element_wise_add(result, vector_a);
+    global_vector_2_element_wise_add(result, vector_b);
+}
+
+// linear interpolate between 2 vectors
+void vector_3_lerp(RI_vector_3 vector_a, RI_vector_3 vector_b, RI_vector_3 *result, double w1){
+    double w0 = 1.0 - w1;
+
+    vector_3_times(result, 0);
+
+    vector_3_times(&vector_a, w0);
+    vector_3_times(&vector_b, w1);
+
+    vector_3_element_wise_add(result, vector_a);
+    vector_3_element_wise_add(result, vector_b);
+}
+
+void global_vector_3_lerp(RI_vector_3 vector_a, RI_vector_3 vector_b, __global RI_vector_3 *result, double w1){
+    double w0 = 1.0 - w1;
+
+    global_vector_3_times(result, 0);
+
+    vector_3_times(&vector_a, w0);
+    vector_3_times(&vector_b, w1);
+
+    global_vector_3_element_wise_add(result, vector_a);
+    global_vector_3_element_wise_add(result, vector_b);
+}
+
+void quaternion_rotate(RI_vector_3 *position, RI_vector_4 rotation){
+    RI_vector_4 pos_quat = {0, position->x, position->y, position->z};
+
+    RI_vector_4 rotation_conjugation = rotation;
+    quaternion_conjugate(&rotation_conjugation);
+
+    quaternion_multiply(&rotation, pos_quat);
+
+    quaternion_multiply(&rotation, rotation_conjugation);
+
+
+    *position = (RI_vector_3){rotation.x, rotation.y, rotation.z};
+}
+
+void global_quaternion_rotate(__global RI_vector_3 *position, RI_vector_4 rotation){
+    RI_vector_4 pos_quat = {0, position->x, position->y, position->z};
+
+    RI_vector_4 rotation_conjugation = rotation;
+    quaternion_conjugate(&rotation_conjugation);
+
+    quaternion_multiply(&rotation, pos_quat);
+
+    quaternion_multiply(&rotation, rotation_conjugation);
+
+    *position = (RI_vector_3){rotation.x, rotation.y, rotation.z};
+}
+
+
+__kernel void transformer(__global RI_face *faces, __global RI_vector_3 *vertecies, __global RI_vector_3 *normals, __global RI_vector_2 *uvs, __global RI_renderable_face *renderable_faces, RI_actor current_actor, RI_camera camera, int current_actor_index, int num_faces, int width, int height, double horizontal_fov_factor, double vertical_fov_factor){
+    int face_index = get_global_id(0);
+    
+    __global RI_face *cur_face = &faces[face_index + current_actor.face_index];
+
+    __global RI_renderable_face *cur_r_face = &renderable_faces[face_index];
+    
+    renderable_faces[num_faces + face_index].should_render = 0;
+
+    if (!cur_face->should_render){
+        cur_r_face->should_render = 0;
+
+        return;
+    }
+
+    int vert_pos_0_index = cur_face->position_0_index;
+    int vert_pos_1_index = cur_face->position_1_index;
+    int vert_pos_2_index = cur_face->position_2_index;
+    
+    int normal_0_index = cur_face->normal_0_index;
+    int normal_1_index = cur_face->normal_1_index;
+    int normal_2_index = cur_face->normal_2_index;
+
+    int uv_0_index = cur_face->uv_0_index;
+    int uv_1_index = cur_face->uv_1_index;
+    int uv_2_index = cur_face->uv_2_index;
+
+    // cur_r_face->parent_actor = current_actor;
+    cur_r_face->shrunk = 0;
+    cur_r_face->split = 0;
+
+    // cur_r_face->material = current_actor.material;
+
+    cur_r_face->position_0 = vertecies[vert_pos_0_index];
+    cur_r_face->position_1 = vertecies[vert_pos_1_index];
+    cur_r_face->position_2 = vertecies[vert_pos_2_index];
+
+    cur_r_face->normal_0 = normals[normal_0_index];
+    cur_r_face->normal_1 = normals[normal_1_index];
+    cur_r_face->normal_2 = normals[normal_2_index];
+
+    if (current_actor.has_uvs){
+        cur_r_face->uv_0 = uvs[uv_0_index];
+        cur_r_face->uv_1 = uvs[uv_1_index];
+        cur_r_face->uv_2 = uvs[uv_2_index];
+    }
+
+    // scale
+    global_vector_3_hadamard(&cur_r_face->position_0, current_actor.scale);
+    global_vector_3_hadamard(&cur_r_face->position_1, current_actor.scale);
+    global_vector_3_hadamard(&cur_r_face->position_2, current_actor.scale);
+
+    // actor rotation
+    global_quaternion_rotate(&cur_r_face->position_0, current_actor.rotation);
+    global_quaternion_rotate(&cur_r_face->position_1, current_actor.rotation);
+    global_quaternion_rotate(&cur_r_face->position_2, current_actor.rotation);
+
+    global_quaternion_rotate(&cur_r_face->normal_0, current_actor.rotation);
+    global_quaternion_rotate(&cur_r_face->normal_1, current_actor.rotation);
+    global_quaternion_rotate(&cur_r_face->normal_2, current_actor.rotation);
+    
+    // object position
+    global_vector_3_element_wise_add(&cur_r_face->position_0, current_actor.position);
+    global_vector_3_element_wise_add(&cur_r_face->position_1, current_actor.position);
+    global_vector_3_element_wise_add(&cur_r_face->position_2, current_actor.position);    
+
+    // camera position & rotation
+    global_vector_3_element_wise_subtract(&cur_r_face->position_0, camera.position);
+    global_vector_3_element_wise_subtract(&cur_r_face->position_1, camera.position);
+    global_vector_3_element_wise_subtract(&cur_r_face->position_2, camera.position);
+
+    global_quaternion_rotate(&cur_r_face->position_0, camera.rotation);
+    global_quaternion_rotate(&cur_r_face->position_1, camera.rotation);
+    global_quaternion_rotate(&cur_r_face->position_2, camera.rotation);        
+
+    __global RI_vector_3 *pos_0 = &cur_r_face->position_0;
+    __global RI_vector_3 *pos_1 = &cur_r_face->position_1;
+    __global RI_vector_3 *pos_2 = &cur_r_face->position_2;
+
+    int is_0_clipped = pos_0->z < camera.min_clip;
+    int is_1_clipped = pos_1->z < camera.min_clip;
+    int is_2_clipped = pos_2->z < camera.min_clip;
+
+    int clip_count = is_0_clipped + is_1_clipped + is_2_clipped;
+
+    cur_r_face->should_render = 1;
+
+    switch(clip_count){
+        case 3: {// ignore polygon, it's behind the camera
+            return;
+            break;
+        }
+
+        case 2:{ // shrink poylgon
+            __global RI_vector_3 *unclipped_point, *point_a, *point_b;
+            __global RI_vector_3 *unclipped_normal, *normal_a, *normal_b;
+            __global RI_vector_2 *unclipped_uv, *uv_a, *uv_b;
+
+            if (!is_0_clipped){ 
+                unclipped_point = &cur_r_face->position_0;
+                point_a = &cur_r_face->position_1;
+                point_b = &cur_r_face->position_2;
+                
+                unclipped_normal = &cur_r_face->normal_0;
+                normal_a = &cur_r_face->normal_1;
+                normal_b = &cur_r_face->normal_2;
+            
+                unclipped_uv = &cur_r_face->uv_0;
+                uv_a = &cur_r_face->uv_1;
+                uv_b = &cur_r_face->uv_2;
+            }
+            else if (!is_1_clipped){ 
+                unclipped_point = &cur_r_face->position_1;
+                point_a = &cur_r_face->position_2;
+                point_b = &cur_r_face->position_0;
+                
+                unclipped_normal = &cur_r_face->normal_1;
+                normal_a = &cur_r_face->normal_2;
+                normal_b = &cur_r_face->normal_0;
+            
+                unclipped_uv = &cur_r_face->uv_1;
+                uv_a = &cur_r_face->uv_2;
+                uv_b = &cur_r_face->uv_0;
+            }
+            else if (!is_2_clipped){ 
+                unclipped_point = &cur_r_face->position_2;
+                point_a = &cur_r_face->position_0;
+                point_b = &cur_r_face->position_1;
+                
+                unclipped_normal = &cur_r_face->normal_2;
+                normal_a = &cur_r_face->normal_0;
+                normal_b = &cur_r_face->normal_1;
+            
+                unclipped_uv = &cur_r_face->uv_2;
+                uv_a = &cur_r_face->uv_0;
+                uv_b = &cur_r_face->uv_1;
+            }
+        
+            double fraction_a_to_unclip = (camera.min_clip - unclipped_point->z) / (point_a->z - unclipped_point->z);                          
+            double fraction_b_to_unclip = (camera.min_clip - unclipped_point->z) / (point_b->z - unclipped_point->z);  
+
+            global_vector_3_lerp(*unclipped_point, *point_a, point_a, fraction_a_to_unclip);
+            global_vector_3_lerp(*unclipped_point, *point_b, point_b, fraction_b_to_unclip);
+
+            global_vector_3_lerp(*unclipped_normal, *normal_a, normal_a, fraction_a_to_unclip);
+            global_vector_3_lerp(*unclipped_normal, *normal_b, normal_b, fraction_b_to_unclip);
+
+            global_vector_2_lerp(*unclipped_uv, *uv_a, uv_a, fraction_a_to_unclip);
+            global_vector_2_lerp(*unclipped_uv, *uv_b, uv_b, fraction_b_to_unclip);
+
+            cur_r_face->shrunk = 1;     
+
+            break;}
+
+        case 1: {// split polygon
+            RI_vector_3 clipped_point, point_a, point_b;
+            RI_vector_3 clipped_normal, normal_a, normal_b;
+            RI_vector_2 clipped_uv, uv_a, uv_b;
+
+            cur_r_face->split = 1;
+
+            if (is_0_clipped){ 
+                clipped_point = cur_r_face->position_0;
+                point_a = cur_r_face->position_1;
+                point_b = cur_r_face->position_2;
+                
+                clipped_normal = cur_r_face->normal_0;
+                normal_a = cur_r_face->normal_1;
+                normal_b = cur_r_face->normal_2;
+            
+                clipped_uv = cur_r_face->uv_0;
+                uv_a = cur_r_face->uv_1;
+                uv_b = cur_r_face->uv_2;
+            }
+            else if (is_1_clipped){ 
+                clipped_point = cur_r_face->position_1;
+                point_a = cur_r_face->position_2;
+                point_b = cur_r_face->position_0;
+                
+                clipped_normal = cur_r_face->normal_1;
+                normal_a = cur_r_face->normal_2;
+                normal_b = cur_r_face->normal_0;
+            
+                clipped_uv = cur_r_face->uv_1;
+                uv_a = cur_r_face->uv_2;
+                uv_b = cur_r_face->uv_0;
+            }
+            else if (is_2_clipped){ 
+                clipped_point = cur_r_face->position_2;
+                point_a = cur_r_face->position_0;
+                point_b = cur_r_face->position_1;
+                
+                clipped_normal = cur_r_face->normal_2;
+                normal_a = cur_r_face->normal_0;
+                normal_b = cur_r_face->normal_1;
+            
+                clipped_uv = cur_r_face->uv_2;
+                uv_a = cur_r_face->uv_0;
+                uv_b = cur_r_face->uv_1;
+            }
+
+            double fraction_a_to_clip = (camera.min_clip - clipped_point.z) / (point_a.z - clipped_point.z);                        
+            double fraction_b_to_clip = (camera.min_clip - clipped_point.z) / (point_b.z - clipped_point.z);                        
+
+            RI_vector_3 new_point_a, new_point_b;  // the new points that move along the polygon's edge to match the z value of min_clip.
+            RI_vector_3 new_normal_a, new_normal_b;  // they come from the clipped point which was originally only 1
+            RI_vector_2 new_uv_a, new_uv_b;
+            
+            vector_3_lerp(clipped_point, point_a, &new_point_a, fraction_a_to_clip);
+            vector_3_lerp(clipped_point, point_b, &new_point_b, fraction_b_to_clip);
+            
+            vector_3_lerp(clipped_normal, normal_a, &new_normal_a, fraction_a_to_clip);
+            vector_3_lerp(clipped_normal, normal_b, &new_normal_b, fraction_b_to_clip);
+            
+            vector_2_lerp(clipped_uv, uv_a, &new_uv_a, fraction_a_to_clip);
+            vector_2_lerp(clipped_uv, uv_b, &new_uv_b, fraction_b_to_clip);
+
+            // okay, now we have a quad (in clockwise order, point a, point b, new point b, new point a)
+            // quads are easy to turn into tris >w<
+
+            __global RI_renderable_face *cur_r_split_face = &renderable_faces[num_faces + face_index];
+
+            // cur_r_split_face->parent_actor = current_actor;
+
+            cur_r_split_face->should_render = 1;
+
+            // cur_r_split_face->material = cur_r_face->material;
+
+            cur_r_face->position_0 = point_a;
+            cur_r_face->position_1 = point_b;
+            cur_r_face->position_2 = new_point_a;
+
+            cur_r_face->normal_0 = normal_a;
+            cur_r_face->normal_1 = normal_b;
+            cur_r_face->normal_2 = new_normal_a;
+
+            cur_r_face->uv_0 = uv_a;
+            cur_r_face->uv_1 = uv_b;
+            cur_r_face->uv_2 = new_uv_a;
+
+            cur_r_split_face->position_0 = point_b;
+            cur_r_split_face->position_1 = new_point_b;
+            cur_r_split_face->position_2 = new_point_a;
+
+            cur_r_split_face->normal_0 = normal_b;
+            cur_r_split_face->normal_1 = new_normal_b;
+            cur_r_split_face->normal_2 = new_normal_a;
+
+            cur_r_split_face->uv_0 = uv_b;
+            cur_r_split_face->uv_1 = new_uv_b;
+            cur_r_split_face->uv_2 = new_uv_a;
+
+            cur_r_split_face->position_0.x = cur_r_split_face->position_0.x / cur_r_split_face->position_0.z * horizontal_fov_factor;
+            cur_r_split_face->position_0.y = cur_r_split_face->position_0.y / cur_r_split_face->position_0.z * vertical_fov_factor;
+            
+            cur_r_split_face->position_1.x = cur_r_split_face->position_1.x / cur_r_split_face->position_1.z * horizontal_fov_factor;
+            cur_r_split_face->position_1.y = cur_r_split_face->position_1.y / cur_r_split_face->position_1.z * vertical_fov_factor;
+
+            cur_r_split_face->position_2.x = cur_r_split_face->position_2.x / cur_r_split_face->position_2.z * horizontal_fov_factor;
+            cur_r_split_face->position_2.y = cur_r_split_face->position_2.y / cur_r_split_face->position_2.z * vertical_fov_factor;
+
+            cur_r_split_face->min_screen_x = cur_r_split_face->position_0.x; 
+            if (cur_r_split_face->position_1.x < cur_r_split_face->min_screen_x) cur_r_split_face->min_screen_x = cur_r_split_face->position_1.x;
+            if (cur_r_split_face->position_2.x < cur_r_split_face->min_screen_x) cur_r_split_face->min_screen_x = cur_r_split_face->position_2.x;
+            cur_r_split_face->min_screen_x = max(cur_r_split_face->min_screen_x, -width / 2); 
+
+            cur_r_split_face->max_screen_x = cur_r_split_face->position_0.x; 
+            if (cur_r_split_face->position_1.x > cur_r_split_face->max_screen_x) cur_r_split_face->max_screen_x = cur_r_split_face->position_1.x;
+            if (cur_r_split_face->position_2.x > cur_r_split_face->max_screen_x) cur_r_split_face->max_screen_x = cur_r_split_face->position_2.x;
+            cur_r_split_face->max_screen_x = min(cur_r_split_face->max_screen_x, width / 2); 
+
+            cur_r_split_face->min_screen_y = cur_r_split_face->position_0.y; 
+            if (cur_r_split_face->position_1.y < cur_r_split_face->min_screen_y) cur_r_split_face->min_screen_y = cur_r_split_face->position_1.y;
+            if (cur_r_split_face->position_2.y < cur_r_split_face->min_screen_y) cur_r_split_face->min_screen_y = cur_r_split_face->position_2.y;
+            cur_r_split_face->min_screen_y = max(cur_r_split_face->min_screen_y, -height / 2); 
+
+            cur_r_split_face->max_screen_y = cur_r_split_face->position_0.y; 
+            if (cur_r_split_face->position_1.y > cur_r_split_face->max_screen_y) cur_r_split_face->max_screen_y = cur_r_split_face->position_1.y;
+            if (cur_r_split_face->position_2.y > cur_r_split_face->max_screen_y) cur_r_split_face->max_screen_y = cur_r_split_face->position_2.y;
+            cur_r_split_face->max_screen_y = min(cur_r_split_face->max_screen_y, height / 2); 
+
+            break;
+        }
+
+        case 0:{ // no issues, ignore
+            break;
+        }
+    }
+
+    // current_actor.material->vertex_shader(&cur_r_face->position_0, &cur_r_face->position_1, &cur_r_face->position_2, horizontal_fov_factor, vertical_fov_factor);
+
+    cur_r_face->min_screen_x = pos_0->x; 
+    if (pos_1->x < cur_r_face->min_screen_x) cur_r_face->min_screen_x = pos_1->x;
+    if (pos_2->x < cur_r_face->min_screen_x) cur_r_face->min_screen_x = pos_2->x;
+    cur_r_face->min_screen_x = max(cur_r_face->min_screen_x, -width / 2); 
+
+    cur_r_face->max_screen_x = pos_0->x; 
+    if (pos_1->x > cur_r_face->max_screen_x) cur_r_face->max_screen_x = pos_1->x;
+    if (pos_2->x > cur_r_face->max_screen_x) cur_r_face->max_screen_x = pos_2->x;
+    cur_r_face->max_screen_x = min(cur_r_face->max_screen_x, width / 2); 
+
+    cur_r_face->min_screen_y = pos_0->y; 
+    if (pos_1->y < cur_r_face->min_screen_y) cur_r_face->min_screen_y = pos_1->y;
+    if (pos_2->y < cur_r_face->min_screen_y) cur_r_face->min_screen_y = pos_2->y;
+    cur_r_face->min_screen_y = max(cur_r_face->min_screen_y, -height / 2); 
+
+    cur_r_face->max_screen_y = pos_0->y; 
+    if (pos_1->y > cur_r_face->max_screen_y) cur_r_face->max_screen_y = pos_1->y;
+    if (pos_2->y > cur_r_face->max_screen_y) cur_r_face->max_screen_y = pos_2->y;
+    cur_r_face->max_screen_y = min(cur_r_face->max_screen_y, height / 2); 
+    
+    return;
+}
+
+__kernel void rasterizer(__global RI_renderable_face *renderable_faces, __global uint *frame_buffer, int width, int height, int half_width, int half_height, int number_of_renderable_faces, int number_of_split_renderable_faces){
+    int pixel_x = get_global_id(0); if (pixel_x >= width) return;
+    int pixel_y = get_global_id(1); if (pixel_y >= height) return;
+    int idx = pixel_y * width + pixel_x;
+
+    int x = pixel_x - half_width;
+    int y = pixel_y - half_height;
+
+    double z = INFINITY;
+
+    uint pixel_color = 0xFFFFFFFF;
+
+    for (int face_i = 0; face_i < number_of_renderable_faces + number_of_split_renderable_faces; ++face_i){
+        __global RI_renderable_face *current_face = &renderable_faces[face_i];
+        
+        if (!current_face->should_render) continue;
+        
+        RI_vector_2 uv_0 = current_face->uv_0;
+        RI_vector_2 uv_1 = current_face->uv_1;
+        RI_vector_2 uv_2 = current_face->uv_2;
+        
+        RI_vector_3 normal_0 = current_face->normal_0;
+        RI_vector_3 normal_1 = current_face->normal_1;
+        RI_vector_3 normal_2 = current_face->normal_2;
+        
+        RI_vector_3 pos_0 = current_face->position_0;
+        RI_vector_3 pos_1 = current_face->position_1;
+        RI_vector_3 pos_2 = current_face->position_2;
+        
+        if (x < current_face->min_screen_x || x > current_face->max_screen_x || y < current_face->min_screen_y || y > current_face->max_screen_y)
+            continue;
+        
+        double denominator, w0, w1, w2;
+
+        denominator = (pos_1.y - pos_2.y) * (pos_0.x - pos_2.x) + (pos_2.x - pos_1.x) * (pos_0.y - pos_2.y);
+        w0 = ((pos_1.y - pos_2.y) * (x - pos_2.x) + (pos_2.x - pos_1.x) * (y - pos_2.y)) / denominator;
+        w1 = ((pos_2.y - pos_0.y) * (x - pos_0.x) + (pos_0.x - pos_2.x) * (y - pos_0.y)) / denominator; 
+        w2 = 1.0 - w0 - w1; 
+        
+        double w_over_z = (w0 / pos_0.z + w1 / pos_1.z + w2 / pos_2.z); 
+        double interpolated_z = 1.0 / w_over_z;
+        
+        if (!(w0 >= 0 && w1 >= 0 && w2 >= 0)){    
+            continue;
+        }
+        
+        if (interpolated_z >= z){                        
+            continue;
+        }
+        
+        double alpha = 1;
+        
+        double ux, uy;
+        ux = uy = -1;
+        
+        RI_vector_3 interpolated_normal = {0};
+        
+        interpolated_normal.x = (w0 * (normal_0.x / pos_0.z) + w1 * (normal_1.x / pos_1.z) + w2 * (normal_2.x / pos_2.z)) / w_over_z;    
+        interpolated_normal.y = (w0 * (normal_0.y / pos_0.z) + w1 * (normal_1.y / pos_1.z) + w2 * (normal_2.y / pos_2.z)) / w_over_z;        
+        interpolated_normal.z = (w0 * (normal_0.z / pos_0.z) + w1 * (normal_1.z / pos_1.z) + w2 * (normal_2.z / pos_2.z)) / w_over_z;        
+        
+        pixel_color = 255 << 24 | (int)((interpolated_normal.x + 1.0) * 127.5) << 16 | (int)((interpolated_normal.y + 1.0) * 127.5) << 8 | (int)((interpolated_normal.z + 1.0) * 127.5);
+        z = interpolated_z;
+    }
+    
+    frame_buffer[idx] = pixel_color;
+
+    return;
+}

+ 52 - 137
src/launch program/main.c

@@ -1,145 +1,60 @@
-#include <stdio.h>
-#include "../RasterIver/headers/rasteriver.h"
+#include "../headers/rasteriver.h"
 #include <time.h>
-#include <stdlib.h>
-
-int width = 400;
-int height = 400;
-
-int main(){ 
-    srand(time(NULL));                                                         
-
-    RI_SetFlag(RI_FLAG_DEBUG, 1);
-    RI_SetFlag(RI_FLAG_DEBUG_LEVEL, RI_DEBUG_HIGH);
-    RI_SetFlag(RI_FLAG_DEBUG_TICK, 0);
-    RI_SetFlag(RI_FLAG_DEBUG_FPS, 0);
-    RI_SetFlag(RI_FLAG_SHOW_FPS, 1);
-    RI_SetFlag(RI_FLAG_SHOW_FRAME, 0);
-    RI_SetFlag(RI_FLAG_SHOW_BUFFER, RI_BUFFER_COMPLETE);
-    RI_SetFlag(RI_FLAG_CLEAN_POLYGONS, 1);
-    RI_SetFlag(RI_FLAG_POPULATE_POLYGONS, 0);
-    RI_SetFlag(RI_FLAG_BE_MASTER_RENDERER, 1);
-    RI_SetFlag(RI_FLAG_HANDLE_SDL_EVENTS, 0);
-    RI_SetFlag(RI_FLAG_SHOW_INFO, 0);
-    RI_SetFlag(RI_FLAG_USE_CPU, 1);
-
-    RI_SetValue(RI_VALUE_WIREFRAME_SCALE, 0.06);
-    RI_SetValue(RI_VALUE_MINIMUM_CLIP, 90);
-
-    char prefix[50] = "[RASTERIVER IS AMAZING] ";
-    RI_SetDebugPrefix(prefix);
-    // RI_SetFpsCap(15);
-
-    if (RI_Init(width, height, "Rasteriver Test") == RI_ERROR){
+
+int main(){
+    RI_context* context = RI_get_context();
+    
+    context->window.width = 800;
+    context->window.height = 800;
+    context->window.title = "This is RasterIver 3.0!!!!!!!";
+    
+    if (RI_init() != 0){
+        printf("failed to init RI\n");
         return 1;
     }
 
-    RI_newObject object_buffer[9] = {
-        {10, 0, 100,          
-            -0.3, 0, 0, 0,          
-            5, 10, 30,       
-            RI_MATERIAL_HAS_TEXTURE, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        {50, 0, 100,        
-            0, 0, 0, 0,          
-            10, 10, 10,        
-            RI_PMP_TEXTURED, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        {-50, 0, 100,         
-            0, 0, 0, 0,          
-            10, 10, 10,      
-            RI_PMP_TEXTURED, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        {0, 50, 100,       
-            0, 0, 0, 0,          
-            10, 10, 10,          
-            RI_PMP_TEXTURED, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        {0, -50, 100,       
-            0, 0, 0, 0,          
-            10, 10, 10,         
-            RI_PMP_TEXTURED, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        {-50, 50, 100,       
-            0, 0, 0, 0,          
-            10, 10, 10,         
-            RI_PMP_TEXTURED, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        {-50, -50, 100,          
-            0, 0, 0, 0,          
-            10, 10, 10,      
-            RI_PMP_TEXTURED, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        {50, 50, 100,          
-            0, 0, 0, 0,          
-            10, 10, 10,       
-            RI_PMP_TEXTURED, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        {50, -50, 100,        
-            0, 0, 0, 0,          
-            10, 10, 10,        
-            RI_PMP_TEXTURED, 
-            "objects/cube.obj", 
-            "textures/bill_mcdinner.png"},
-        };
-
-        int objects_to_request = 1;
-
-    RI_objects objects = RI_RequestObjects(object_buffer, objects_to_request);
-
-        for (int i = 0; i < objects_to_request; i++){
-            objects[i].material.albedo.a = 255;// * ((float)i / objects_to_request);
-            objects[i].material.albedo.r = 255;// * ((float)i / objects_to_request);
-            objects[i].material.albedo.g = 255;// * ((float)i / objects_to_request);
-            objects[i].material.albedo.b = 255;// * ((float)i / objects_to_request);
-        }
+    RI_scene *scene = RI_new_scene();
+
+    RI_actor *actor = RI_new_actor();
+
+    RI_load_mesh("objects/cube.obj", actor);
+    
+    actor->scale = (RI_vector_3){100, 100, 100};
+    actor->position = (RI_vector_3){0, 0, 0};
+    actor->rotation = (RI_vector_4){1, 0, 0, 0};
+
+    scene->actors = malloc(sizeof(RI_actor) * 10);
+
+    scene->actors[0] = actor;
+
+    scene->length_of_actors_array = 1;
+
+    long int start, end;
+    double fps = 0;
+
+    double delta_time = 0;
+    double delta_min = 0.00001;
+    double delta_max = 1;
+    while (context->is_running){
+        start = clock();
         
-        float frame = 0;
-        SDL_Event event;
-
-        int selected_triangle = -1;
-        RI_SetValue(RI_VALUE_SELECTED_TRIANGLE, selected_triangle);
-    while (RI_IsRunning() == RI_RUNNING){        
-        // objects[0].transform.rotation.x += rand() % 100 * 0.01;
-        // objects[0].transform.rotation.y += rand() % 100 * 0.02;
-        // objects[0].transform.rotation.z += rand() % 100 * 0.03;
-        while( SDL_PollEvent( &event ) ){
-                
-            switch( event.type ){
-                /* Keyboard event */
-                /* Pass the event data onto PrintKeyInfo() */
-                case SDL_KEYDOWN:
-                    selected_triangle = (selected_triangle + 1) % 12;
-    break;
-
-                /* SDL_QUIT event (window close) */
-                case SDL_QUIT:
-                    RI_Stop();
-                    break;
-
-                default:
-                    break;
-            }
-
-        }
-        for (int i = 0; i < objects_to_request; i++){
-        objects[0].transform.rotation.x += 0.05;
-
-            objects[i].transform.position.z = 110 + sin(frame) * 20;
-        }
-
-        frame -= 0.05;
-
-        RI_Tick();
+        RI_render(NULL, scene);
+
+        actor->position = (RI_vector_3){0, 0, 1000};
+
+        RI_euler_rotation_to_quaternion(&actor->rotation, (RI_vector_3){context->current_frame * 0.001, context->current_frame * 0.001, context->current_frame * 0.001});
+        
+        RI_tick();
+
+        end = clock();
+
+        delta_time = fmin(fmax((double)(end - start) / (double)(CLOCKS_PER_SEC), delta_min), delta_max);
+        fps = 1.0 / delta_time;
+
+        printf("%f\n", fps);
     }
 
-    RI_Stop();
+    free(scene->actors);
+
+    return 0;
 }

+ 615 - 0
src/main/main.c

@@ -0,0 +1,615 @@
+// rasteriver.c
+
+#include <CL/cl.h>
+#include <SDL2/SDL.h>
+#include "../headers/rasteriver.h"
+#include "../headers/memory.h"
+
+RI_context context;
+
+#define RI_realloc(__ptr, __size) written_RI_realloc(__ptr, __size, __func__, __LINE__, context)
+#define RI_malloc(__size) written_RI_malloc(__size, __func__, __LINE__, context)
+#define RI_calloc(__nmemb, __size) written_RI_calloc(__nmemb, __size, __func__, __LINE__, context)
+#define RI_free(__ptr) written_RI_free(__ptr, __func__, __LINE__, context)
+
+#define PI 3.14159265359
+#define PI2 1.57079632679
+
+void debug(char *string, ...){
+    if (!context.should_debug)
+        return;
+
+    va_list args;
+    va_start(args, string);
+
+    char message[500];
+
+    strcpy(message, context.debug_prefix);
+
+    strcat(message, string);
+
+    vprintf(message, args);
+    printf("\n");
+
+    va_end(args);
+}
+
+RI_texture *RI_new_texture(int width, int height){
+    RI_texture *new_texture = RI_malloc(sizeof(RI_texture));
+
+    new_texture->image_buffer = RI_malloc(sizeof(uint32_t) * width * height);
+    new_texture->resolution.x = width;
+    new_texture->resolution.y = height;
+
+    return new_texture;
+}
+
+RI_material *RI_new_material(){
+    RI_material *new_material = RI_malloc(sizeof(RI_material));
+
+    new_material->albedo = 0xFFFF00FF;
+
+    return new_material;
+}
+
+RI_actor *RI_new_actor(){
+    RI_actor *new_actor = RI_malloc(sizeof(RI_actor));
+
+    if (context.defaults.default_actor){
+        *new_actor = *context.defaults.default_actor;
+    } else {
+        new_actor->position = (RI_vector_3){0, 0, 0};
+        new_actor->scale = (RI_vector_3){1, 1, 1};
+        new_actor->rotation = (RI_vector_4){1, 0, 0, 0};
+        new_actor->active = 1;
+    }
+
+    return new_actor;
+}
+
+RI_scene *RI_new_scene(){
+    RI_scene *new_scene = RI_malloc(sizeof(RI_scene));
+
+    new_scene->camera.FOV = PI2;
+    new_scene->camera.max_clip = 100000;
+    new_scene->camera.min_clip = 0.01;
+    new_scene->camera.position = (RI_vector_3){0, 0, 0};
+    new_scene->camera.rotation = (RI_vector_4){1, 0, 0, 0};
+
+    return new_scene;
+}
+
+RI_mesh *RI_load_mesh(char *filename, RI_actor *actor){
+    int previous_face_count = context.opencl.face_count;
+    int previous_vertecies_count = context.opencl.vertex_count;
+    int previous_normals_count = context.opencl.normal_count;
+    int previous_uvs_count = context.opencl.uv_count;
+
+    FILE *file = fopen(filename, "r");
+
+    if (!file){
+        debug("[Mesh Loader] Error! File \"%s\" not found", filename);
+        return NULL;
+    }
+    
+    char line[512];
+    
+    int face_count = 0;
+
+    while (fgets(line, sizeof(line), file)) {
+        if (line[0] == 'f' && line[1] == ' ') { // face
+            ++face_count;
+            ++context.opencl.face_count;
+        }
+        else if (line[0] == 'v'){
+            if (line[1] == ' ') { // vertex
+                ++context.opencl.vertex_count;
+            }
+            else if (line[1] == 'n') { // normal
+                ++context.opencl.normal_count;
+            }
+            else if (line[1] == 't') { // UV
+                ++context.opencl.uv_count;
+            }
+        }
+    }
+
+    rewind(file);
+
+    context.opencl.faces = RI_realloc(context.opencl.faces, sizeof(RI_face) * context.opencl.face_count);
+    context.opencl.vertecies = RI_realloc(context.opencl.vertecies, sizeof(RI_vector_3) * context.opencl.vertex_count);
+    context.opencl.normals = RI_realloc(context.opencl.normals, sizeof(RI_vector_3) * context.opencl.normal_count);
+    context.opencl.uvs = RI_realloc(context.opencl.uvs, sizeof(RI_vector_2) * context.opencl.uv_count);
+
+    int current_face_index = previous_face_count;
+    int current_vertex_index = previous_vertecies_count;
+    int current_normal_index = previous_normals_count;
+    int current_uv_index = previous_uvs_count;
+
+    int has_normals, has_uvs;
+    has_normals = has_uvs = 0;
+
+    while (fgets(line, sizeof(line), file)) {
+        if (line[0] == 'f' && line[1] == ' ') {
+            int vertex_0_index, vertex_1_index, vertex_2_index, normal_0_index, normal_1_index, normal_2_index, uv_0_index, uv_1_index, uv_2_index;
+
+            int matches = sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d/", 
+                &vertex_0_index, &uv_0_index, &normal_0_index, 
+                &vertex_1_index, &uv_1_index, &normal_1_index, 
+                &vertex_2_index, &uv_2_index, &normal_2_index);
+
+            if (matches != 9){
+                vertex_0_index = -1;
+                vertex_1_index = -1;
+                vertex_2_index = -1;
+                
+                normal_0_index = -1;
+                normal_1_index = -1;
+                normal_2_index = -1;
+                
+                uv_0_index = -1;
+                uv_1_index = -1;
+                uv_2_index = -1;
+
+                if (strchr(line, '/')){
+                    sscanf(line, "f %d//%d %d//%d %d//%d", 
+                        &vertex_0_index, &normal_0_index, 
+                        &vertex_1_index, &normal_1_index, 
+                        &vertex_2_index, &normal_2_index);
+                
+                    has_normals = 1;
+                }
+                else {
+                    sscanf(line, "f %d %d %d", 
+                        &vertex_0_index, 
+                        &vertex_1_index, 
+                        &vertex_2_index);
+                }
+            }
+            else {
+                has_normals = has_uvs = 1;
+            }
+
+            context.opencl.faces[current_face_index].position_0_index = vertex_0_index - 1 + previous_vertecies_count;
+            context.opencl.faces[current_face_index].position_1_index = vertex_1_index - 1 + previous_vertecies_count;
+            context.opencl.faces[current_face_index].position_2_index = vertex_2_index - 1 + previous_vertecies_count;
+
+            context.opencl.faces[current_face_index].normal_0_index = normal_0_index - 1 + previous_normals_count;
+            context.opencl.faces[current_face_index].normal_1_index = normal_1_index - 1 + previous_normals_count;
+            context.opencl.faces[current_face_index].normal_2_index = normal_2_index - 1 + previous_normals_count;
+            
+            context.opencl.faces[current_face_index].uv_0_index = uv_0_index - 1 + previous_uvs_count;
+            context.opencl.faces[current_face_index].uv_1_index = uv_1_index - 1 + previous_uvs_count;
+            context.opencl.faces[current_face_index].uv_2_index = uv_2_index - 1 + previous_uvs_count;
+
+            context.opencl.faces[current_face_index].should_render = 1;
+
+            ++current_face_index;
+        }
+        else if (line[0] == 'v' && line[1] == ' ') {
+            double x, y, z;
+            
+            sscanf(line, "v %lf %lf %lf", &x, &y, &z);
+
+            context.opencl.vertecies[current_vertex_index].x = x;
+            context.opencl.vertecies[current_vertex_index].y = y;
+            context.opencl.vertecies[current_vertex_index].z = z;
+
+            ++current_vertex_index;
+        } 
+        else if (line[0] == 'v' && line[1] == 'n') {
+            double x, y, z;
+            
+            sscanf(line, "vn %lf %lf %lf", &x, &y, &z);
+
+            context.opencl.normals[current_normal_index].x = x;
+            context.opencl.normals[current_normal_index].y = y;
+            context.opencl.normals[current_normal_index].z = z;
+
+            ++current_normal_index;
+        }
+        else if (line[0] == 'v' && line[1] == 't') {
+            double x, y, z;
+
+            sscanf(line, "vt %lf %lf %lf", &x, &y, &z);
+
+            context.opencl.uvs[current_uv_index].x = x;
+            context.opencl.uvs[current_uv_index].y = y;
+            // UVS are almost always 2D so we don't need Z (the type itself is a vector 2f, not 3f) 
+
+            ++current_uv_index;
+        } 
+    }
+
+    char* loading_mesh_notice_string;
+
+    if (has_normals && !has_uvs) loading_mesh_notice_string = "normals";
+    else if (!has_normals && has_uvs) loading_mesh_notice_string = "UVs";
+    else if (!has_normals && !has_uvs) loading_mesh_notice_string = "normals and UVs";
+    
+    if (!has_normals || !has_uvs) debug("[Mesh Loader] Notice! Mesh \"%s\" is missing %s", filename, loading_mesh_notice_string);
+    
+    actor->has_normals = has_normals;
+    actor->has_uvs = has_uvs;
+
+    actor->face_count = context.opencl.face_count - previous_face_count;
+    actor->face_index = previous_face_count;
+
+    debug("[Mesh Loader] Loaded mesh \"%s\"! %d faces, %d verticies, %d normals, %d uvs", filename, current_face_index, current_vertex_index, current_normal_index, current_uv_index); 
+
+    clFinish(context.opencl.queue);
+
+    if (previous_face_count != context.opencl.face_count) {
+        if (context.opencl.faces_mem_buffer) clReleaseMemObject(context.opencl.faces_mem_buffer);
+
+        context.opencl.faces_mem_buffer = clCreateBuffer(context.opencl.context, CL_MEM_READ_WRITE, sizeof(RI_face) * context.opencl.face_count, NULL, NULL);
+
+        clSetKernelArg(context.opencl.transformation_kernel, 0, sizeof(cl_mem), &context.opencl.faces_mem_buffer);
+    }
+
+    if (previous_vertecies_count != context.opencl.vertex_count) {
+        if (context.opencl.vertecies_mem_buffer) clReleaseMemObject(context.opencl.vertecies_mem_buffer);
+
+        context.opencl.vertecies_mem_buffer = clCreateBuffer(context.opencl.context, CL_MEM_READ_WRITE, sizeof(RI_vector_3) * context.opencl.vertex_count, NULL, NULL);
+
+        clSetKernelArg(context.opencl.transformation_kernel, 1, sizeof(cl_mem), &context.opencl.vertecies_mem_buffer);
+    }
+
+    if (previous_normals_count != context.opencl.normal_count) {
+        if (context.opencl.normals_mem_buffer) clReleaseMemObject(context.opencl.normals_mem_buffer);
+
+        context.opencl.normals_mem_buffer = clCreateBuffer(context.opencl.context, CL_MEM_READ_WRITE, sizeof(RI_vector_3) * context.opencl.normal_count, NULL, NULL);
+
+        clSetKernelArg(context.opencl.transformation_kernel, 2, sizeof(cl_mem), &context.opencl.normals_mem_buffer);
+    }
+
+    if (previous_uvs_count != context.opencl.uv_count) {
+        if (context.opencl.uvs_mem_buffer) clReleaseMemObject(context.opencl.uvs_mem_buffer);
+
+        context.opencl.uvs_mem_buffer = clCreateBuffer(context.opencl.context, CL_MEM_READ_WRITE, sizeof(RI_vector_2) * context.opencl.uv_count, NULL, NULL);
+
+        clSetKernelArg(context.opencl.transformation_kernel, 3, sizeof(cl_mem), &context.opencl.uvs_mem_buffer);
+    }
+
+    fclose(file);
+}
+
+void RI_render(RI_texture *target_texture, RI_scene *scene){
+    if (!target_texture){
+        target_texture = context.sdl.frame_buffer;
+    }
+
+    // transformer 
+    
+    double horizontal_fov_factor = (double)target_texture->resolution.x / tanf(0.5 * scene->camera.FOV);
+    double vertical_fov_factor = (double)target_texture->resolution.y / tanf(0.5 * scene->camera.FOV);
+    
+
+    // kernel args
+    clSetKernelArg(context.opencl.transformation_kernel, 6, sizeof(RI_camera), &scene->camera);
+    clSetKernelArg(context.opencl.transformation_kernel, 11, sizeof(double), &horizontal_fov_factor);
+    clSetKernelArg(context.opencl.transformation_kernel, 12, sizeof(double), &vertical_fov_factor);
+
+
+    // count faces
+    scene->face_count = 0;
+    for (int actor_index = 0; actor_index < scene->length_of_actors_array; ++actor_index){
+        scene->face_count += scene->actors[actor_index]->face_count;
+    }
+
+
+    // allocate faces_to_render if face count increases
+    if (scene->face_count > context.opencl.length_of_renderable_faces_array){
+        context.opencl.faces_to_render = RI_realloc(context.opencl.faces_to_render, sizeof(RI_renderable_face) * scene->face_count * 2); // x2 because faces can be split
+    
+        context.opencl.length_of_renderable_faces_array = scene->face_count;
+    }
+
+    
+    // set faces_to_render to zero
+    memset(context.opencl.faces_to_render, 0, sizeof(RI_renderable_face) * scene->face_count * 2);
+
+    clSetKernelArg(context.opencl.transformation_kernel, 4, sizeof(cl_mem), &context.opencl.renderable_faces_mem_buffer);
+
+    context.current_renderable_face_index = 0;
+    context.current_split_renderable_face_index = 0;
+
+    debug("transforming polygons...");
+
+    // transform polygons
+    for (int actor_index = 0; actor_index < scene->length_of_actors_array; ++actor_index){
+        debug("actor index: %d face count: %d", actor_index, scene->actors[actor_index]->face_count);
+        
+        if (scene->actors[actor_index]->face_count <= 0) continue;
+        
+        const size_t t_global_work_size[1] = {scene->actors[actor_index]->face_count};
+        const size_t t_local_work_size[1] = {(int)fmin(scene->actors[actor_index]->face_count, 32)};
+
+        debug("transformer global work size: {%d}", scene->actors[actor_index]->face_count);    
+        debug("transformer local work size: {%d}", (int)fmin(scene->actors[actor_index]->face_count, 32));    
+
+        clSetKernelArg(context.opencl.transformation_kernel, 7, sizeof(int), &actor_index);
+        clSetKernelArg(context.opencl.transformation_kernel, 8, sizeof(int), &scene->actors[actor_index]->face_count);
+        
+        clSetKernelArg(context.opencl.transformation_kernel, 5, sizeof(RI_actor), &scene->actors[actor_index]);
+
+        debug("running kernel...");
+
+        clEnqueueNDRangeKernel(context.opencl.queue, context.opencl.transformation_kernel, 1, NULL, t_global_work_size, t_local_work_size, 0, NULL, NULL);
+        clFinish(context.opencl.queue);
+    
+        debug("done");
+    }
+
+    debug("done");    
+    
+
+    // rasterize
+
+    // set width, height and kernel width, height
+    int x = context.window.width;
+    int y = context.window.height;
+
+    int x_div_32 = ceil(context.window.width / 32.0);
+    int y_div_32 = ceil(context.window.height / 32.0);
+
+    if (context.window.width % 32 != 0)
+        x = 32 * x_div_32;
+
+    if (context.window.height % 32 != 0)
+        y = 32 * y_div_32;
+
+    const size_t r_global_work_size[2] = {x, y};
+    const size_t r_local_work_size[2] = {32, 32};
+
+    debug("rasterizer global work size: {%d, %d}", x, y);    
+    debug("rasterizer local work size: {%d, %d}", 32, 32);    
+
+    // kernel args
+    clSetKernelArg(context.opencl.rasterization_kernel, 0, sizeof(cl_mem), &context.opencl.renderable_faces_mem_buffer);
+    clSetKernelArg(context.opencl.rasterization_kernel, 6, sizeof(int), &context.current_renderable_face_index);
+    clSetKernelArg(context.opencl.rasterization_kernel, 7, sizeof(int), &context.current_split_renderable_face_index);
+
+    debug("rasterizing...");
+
+    // run raster kernel
+    clEnqueueNDRangeKernel(context.opencl.queue, context.opencl.rasterization_kernel, 2, NULL, r_global_work_size, r_local_work_size, 0, NULL, NULL);
+    clFinish(context.opencl.queue);
+    
+    debug("done\ncopying frame buffer...");
+
+    // put GPU frame buffer into CPU
+    clEnqueueReadBuffer(context.opencl.queue, context.opencl.frame_buffer_mem_buffer, CL_TRUE, 0, context.window.width * context.window.height * sizeof(uint32_t), context.sdl.frame_buffer->image_buffer, 0, NULL, NULL);
+    clFinish(context.opencl.queue);
+
+    debug("done");
+}
+
+void RI_tick(){
+    SDL_Event event;
+
+    while (SDL_PollEvent(&event)){
+        switch (event.type){
+            case SDL_QUIT: {
+                context.is_running = ri_false;
+
+                break;
+            }
+
+            default: {
+                break;
+            }
+        }
+    }
+
+    SDL_LockTexture(context.sdl.frame_buffer_texture, NULL, (void*)&context.sdl.frame_buffer_intermediate, &context.sdl.pitch);
+
+    memcpy(context.sdl.frame_buffer_intermediate, context.sdl.frame_buffer->image_buffer, context.window.width * context.window.height * sizeof(uint32_t));
+
+    SDL_UnlockTexture(context.sdl.frame_buffer_texture);
+
+    SDL_RenderCopy(context.sdl.renderer, context.sdl.frame_buffer_texture, NULL, NULL);
+    SDL_RenderPresent(context.sdl.renderer);
+
+    ++context.current_frame;
+
+    return;
+}
+
+RI_context *RI_get_context(){
+    context.sdl = (RI_SDL){NULL, NULL, NULL, NULL, 0};
+    context.window = (RI_window){800, 800, 400, 400, "RasterIver Window"};
+
+    return &context;
+} 
+
+// Convert a CL file to a string
+char *load_kernel_source(const char *filename) {
+    FILE *f = fopen(filename, "rb");
+
+    if (f == NULL){
+        debug("couldn't open kernel file \"%s\"", filename);
+    }
+
+    fseek(f, 0, SEEK_END);
+    size_t size = ftell(f);
+    rewind(f);
+    char *source = malloc(size + 1);
+    fread(source, 1, size, f);
+    source[size] = '\0';
+    fclose(f);
+    return source;
+}
+
+int RI_init(){
+    context.window.half_width = context.window.width / 2;
+    context.window.half_height = context.window.height / 2;
+
+    context.current_frame = 0;
+
+    // init SDL
+    context.sdl.window = SDL_CreateWindow(context.window.title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, context.window.width, context.window.height, 0);
+    context.sdl.renderer = SDL_CreateRenderer(context.sdl.window, -1, SDL_RENDERER_ACCELERATED);
+    context.sdl.frame_buffer_texture = SDL_CreateTexture(context.sdl.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, context.window.width, context.window.height);
+
+    context.sdl.frame_buffer_intermediate = malloc(sizeof(uint32_t) * context.window.width * context.window.height);
+    context.sdl.frame_buffer = RI_new_texture(context.window.width, context.window.height);
+
+    context.is_running = ri_true;
+    context.should_debug = ri_true;
+
+    context.debug_prefix = "[RasterIver] ";
+
+    context.defaults.default_actor = RI_new_actor();
+    
+    RI_load_mesh("objects/cube.obj", context.defaults.default_actor);
+
+    // init OpenCL
+ 
+    context.opencl.length_of_renderable_faces_array = 10000; // allocate 10,000 faces so we dont have to worry about it
+    context.opencl.face_count = 0;
+    context.opencl.vertex_count = 0;
+    context.opencl.normal_count = 0;
+    context.opencl.uv_count = 0;
+    
+    context.opencl.faces_to_render = RI_malloc(sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array);
+    context.opencl.faces = RI_malloc(sizeof(RI_face) * context.opencl.face_count);
+
+    cl_int error;
+
+    cl_uint num_platforms = 0;
+    error = clGetPlatformIDs(0, NULL, &num_platforms);
+
+    cl_platform_id *platforms = malloc(sizeof(cl_platform_id) * num_platforms);
+    error = clGetPlatformIDs(num_platforms, platforms, NULL);
+
+    cl_device_id *devices; 
+    
+    cl_platform_id chosen_platform = NULL;
+    char pname[256];
+    for (cl_uint i = 0; i < num_platforms; i++) {
+        error = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(pname), pname, NULL);
+
+        debug("get platform info result: %d", error);
+
+        cl_uint num_devices = 0;
+        error = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
+
+        debug("num devices result: %d", error);
+
+        devices = malloc(sizeof(cl_device_id) * num_devices);
+        error = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
+
+        if (i == 1){
+            context.opencl.device = devices[0];
+        }
+
+        debug("get device ids result: %d", error);
+
+        debug("-platform #%d: NAME: %s | DEVICE COUNT: %d", i, pname, num_devices);
+
+        for (int j = 0; j < num_devices; ++j){
+            debug("-\\ device #%d: ID: %u", j, devices[j]);
+        }
+
+        free(devices);
+    }
+
+    clGetPlatformInfo(chosen_platform, CL_PLATFORM_NAME, sizeof(pname), pname, NULL);
+
+    context.opencl.platform = platforms[0];
+
+    debug("device id: %u", context.opencl.device);
+
+    context.opencl.context = clCreateContext(NULL, 1, &context.opencl.device, NULL, NULL, NULL);
+    context.opencl.queue = clCreateCommandQueue(context.opencl.context, context.opencl.device, 0, &error);
+
+    // build programs
+
+    char *program_source = load_kernel_source("src/kernels/kernels.cl");    
+    cl_program rasterization_program = clCreateProgramWithSource(context.opencl.context, 1, (const char**)&program_source, NULL, NULL);
+    free(program_source);
+
+    cl_int result = clBuildProgram(rasterization_program, 1, &context.opencl.device, "", NULL, NULL);
+
+    if (result != CL_SUCCESS){
+        char log[256];
+
+        debug("rasterization program build failed (%d). Log: \n  %s", clGetProgramBuildInfo(rasterization_program, context.opencl.device, CL_PROGRAM_BUILD_LOG, 10000, log, NULL), log);
+    
+        return 1;
+    }
+
+    // kernels
+
+    context.opencl.rasterization_kernel = clCreateKernel(rasterization_program, "rasterizer", &error);
+
+    if (error != CL_SUCCESS){
+        debug("couldn't create rasterizer kernel");
+        return 1;
+    }
+
+    context.opencl.transformation_kernel = clCreateKernel(rasterization_program, "transformer", &error);
+
+    if (error != CL_SUCCESS){
+        debug("couldn't create transformer kernel");
+        return 1;
+    }
+
+    // rasterizer
+
+    context.opencl.renderable_faces_mem_buffer = clCreateBuffer(context.opencl.context, CL_MEM_READ_WRITE, sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array, NULL, &error);
+    
+    if (error != CL_SUCCESS){
+        debug("couldn't create renderable faces memory buffer");
+        return 1;
+    }
+    
+    context.opencl.frame_buffer_mem_buffer = clCreateBuffer(context.opencl.context, CL_MEM_READ_WRITE, sizeof(uint32_t) * context.window.width * context.window.height, NULL, &error);
+
+    if (error != CL_SUCCESS || !context.opencl.frame_buffer_mem_buffer){
+        debug("couldn't create frame buffer memory buffer");
+        return 1;
+    }
+
+// rasterizer(__global RI_renderable_face *renderable_faces, __global uint *frame_buffer, 
+//            int width, int height, int half_width, int half_height, int number_of_renderable_faces, 
+//            int number_of_split_renderable_faces)
+
+    clSetKernelArg(context.opencl.rasterization_kernel, 0, sizeof(cl_mem), &context.opencl.renderable_faces_mem_buffer);
+    clSetKernelArg(context.opencl.rasterization_kernel, 1, sizeof(cl_mem), &context.opencl.frame_buffer_mem_buffer);
+    clSetKernelArg(context.opencl.rasterization_kernel, 2, sizeof(int), &context.window.width);
+    clSetKernelArg(context.opencl.rasterization_kernel, 3, sizeof(int), &context.window.height);
+    clSetKernelArg(context.opencl.rasterization_kernel, 4, sizeof(int), &context.window.half_width);
+    clSetKernelArg(context.opencl.rasterization_kernel, 5, sizeof(int), &context.window.half_height);
+    clSetKernelArg(context.opencl.rasterization_kernel, 6, sizeof(int), &context.current_renderable_face_index);
+    clSetKernelArg(context.opencl.rasterization_kernel, 7, sizeof(int), &context.current_split_renderable_face_index);
+
+    // transformer
+
+    context.opencl.faces_mem_buffer = NULL;
+    context.opencl.vertecies_mem_buffer = NULL;
+    context.opencl.normals_mem_buffer = NULL;
+    context.opencl.uvs_mem_buffer = NULL;
+
+// transformer(__global RI_face *faces, __global RI_vector_3 *vertecies, __global RI_vector_3 *normals, 
+//             __global RI_vector_2 *uvs, __global RI_renderable_face *renderable_faces, RI_actor current_actor, 
+//             RI_camera camera, int current_actor_index, int num_faces, int width, int height, 
+//             double horizontal_fov_factor, double vertical_fov_factor)
+    
+    // clSetKernelArg(context.opencl.transformation_kernel, 0, sizeof(cl_mem), &context.opencl.faces_mem_buffer);
+    // clSetKernelArg(context.opencl.transformation_kernel, 1, sizeof(cl_mem), &context.opencl.vertecies_mem_buffer);
+    // clSetKernelArg(context.opencl.transformation_kernel, 2, sizeof(cl_mem), &context.opencl.normals_mem_buffer);
+    // clSetKernelArg(context.opencl.transformation_kernel, 3, sizeof(cl_mem), &context.opencl.uvs_mem_buffer);
+    // clSetKernelArg(context.opencl.transformation_kernel, 4, sizeof(cl_mem), &context.opencl.renderable_faces_mem_buffer);
+    // clSetKernelArg(context.opencl.transformation_kernel, 5, sizeof(RI_actor), &context.window.half_height);
+    // clSetKernelArg(context.opencl.transformation_kernel, 6, sizeof(RI_camera), &context.current_renderable_face_index);
+    // clSetKernelArg(context.opencl.transformation_kernel, 7, sizeof(int), &actor_index);
+    // clSetKernelArg(context.opencl.transformation_kernel, 8, sizeof(int), &face_count);
+    clSetKernelArg(context.opencl.transformation_kernel, 9, sizeof(int), &context.window.width);
+    clSetKernelArg(context.opencl.transformation_kernel, 10, sizeof(int), &context.window.height);
+    // clSetKernelArg(context.opencl.transformation_kernel, 11, sizeof(double), &horizontal_fov_factor);
+    // clSetKernelArg(context.opencl.transformation_kernel, 12, sizeof(double), &vertical_fov_factor);
+
+    return 0;
+}

+ 0 - 4
src/scripts/build_all.sh

@@ -1,4 +0,0 @@
-echo "[COMPILER] Building Rasteriver"
-./lib_build.sh $1
-echo "[COMPILER] Building Main"
-./build.sh $2

+ 0 - 3
src/scripts/build_rasteriver.sh

@@ -1,3 +0,0 @@
-echo "[LIB]      Building..."
-gcc  -Wall -Wextra -D CL_TARGET_OPENCL_VERSION=120 -fPIC -shared -o librasteriver.so $1 -lc -lSDL2 -lm -lOpenCL
-echo "[LIB]      Built"

+ 0 - 3
src/scripts/build_test_program.sh

@@ -1,3 +0,0 @@
-echo "[MAIN]     Building..."
-gcc -g -Wall -Wextra -D CL_TARGET_OPENCL_VERSION=120 $1 -o main.bin -L. -lrasteriver -Wl,-rpath=.
-echo "[MAIN]     Built"

+ 0 - 3
src/scripts/dcopy.sh

@@ -1,3 +0,0 @@
-echo "[MAIN]     Building..."
-gcc  -Wall -Wextra -D CL_TARGET_OPENCL_VERSION=120 $1 -o main.bin -lSDL2 -lm -lOpenCL
-echo "[MAIN]     Built"

+ 0 - 6
src/scripts/debug.sh

@@ -1,6 +0,0 @@
-clear
-echo building...
-gcc -g -Wall -Wextra -D CL_TARGET_OPENCL_VERSION=120 $1 -o main.bin -lSDL2 -lm -lOpenCL
-echo built...
-echo debugging...
-gdb ./main.bin

BIN
textures/test_guy_texture_256.png


+ 1 - 1
val

@@ -1 +1 @@
-valgrind --leak-check=full --track-origins=yes ./builds/final\ binaries/main.bin
+valgrind --leak-check=full --track-origins=yes ./builds/main.bin

Some files were not shown because too many files changed in this diff