Last active
March 11, 2019 22:54
-
-
Save Sir-Irk/9fb80d264e4ec61523bc9524c040d544 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <stdint.h> | |
| #include <assert.h> | |
| #define JM_MATH_IMPLEMENTATION | |
| #define JM_MATH_USE_STDLIB | |
| #include "jm_math.h" | |
| #define STB_IMAGE_IMPLEMENTATION | |
| #define STB_IMAGE_WRITE_IMPLEMENTATION | |
| #include "stb_image.h" | |
| #include "stb_image_write.h" | |
| inline uint32_t get_blue(uint32_t color) { return (color >> 16) & 0xFF; } | |
| inline uint32_t get_green(uint32_t color) { return (color >> 8) & 0xFF; } | |
| inline uint32_t get_red(uint32_t color) { return (color >> 0) & 0xFF; } | |
| //NOTE: Staight up comparison of pixel values | |
| int pixel_compare(const void *a, const void *b) | |
| { | |
| uint32_t color0 = *(uint32_t *)a; | |
| uint32_t color1 = *(uint32_t *)b; | |
| if(color0 > color1) return 1; | |
| if(color0 < color1) return -1; | |
| return 0; | |
| } | |
| inline uint32_t averaged_color(uint32_t color) | |
| { | |
| uint32_t r = get_red(color); | |
| uint32_t g = get_green(color); | |
| uint32_t b = get_blue(color); | |
| return (r + g + b) / 3; | |
| } | |
| //NOTE: Comparison is done using the average of each channel(no alpha). This can provide a slightly smoother | |
| // appearance to the end result. | |
| int pixel_compare_average(const void *a, const void *b) | |
| { | |
| uint32_t avg0 = averaged_color(*(uint32_t *)a); | |
| uint32_t avg1 = averaged_color(*(uint32_t *)b); | |
| if(avg0 > avg1) return 1; | |
| if(avg0 < avg1) return -1; | |
| return 0; | |
| } | |
| //NOTE: human eyes tend to be more sensitive to green light and much less | |
| // sensitive to blue light and red light. | |
| #define EYE_RED_COLOR_BIAS 0.2216f | |
| #define EYE_GREEN_COLOR_BIAS 0.7152f | |
| #define EYE_BLUE_COLOR_BIAS 0.0832f | |
| inline float human_eye_color_intensity_bias(uint32_t color) | |
| { | |
| //NOTE: map channels from 0-255 to 0.0f-1.0f | |
| float r = (float)get_red(color) / UCHAR_MAX; | |
| float g = (float)get_green(color) / UCHAR_MAX; | |
| float b = (float)get_blue(color) / UCHAR_MAX; | |
| return jmClamp01(jmDot(V3(r, g, b), V3(EYE_RED_COLOR_BIAS, EYE_GREEN_COLOR_BIAS, EYE_BLUE_COLOR_BIAS))); | |
| } | |
| int pixel_compare_eye_bias(const void *a, const void *b) | |
| { | |
| float intensity0 = human_eye_color_intensity_bias(*(uint32_t *)a); | |
| float intensity1 = human_eye_color_intensity_bias(*(uint32_t *)b); | |
| if(intensity0 > intensity1) return 1; | |
| if(intensity0 < intensity1) return -1; | |
| return 0; | |
| } | |
| int main(void) | |
| { | |
| int w, h; | |
| uint8_t *pixels = stbi_load("galaxy.jpg", &w, &h, 0, 4); | |
| assert(pixels); | |
| //NOTE: sort each row separately | |
| for(int i = 0; i < h; ++i) | |
| { | |
| qsort(&((uint32_t *)pixels)[i * w], w, sizeof(uint32_t), pixel_compare_eye_bias); | |
| } | |
| stbi_write_png("galaxy_sorted_05.png", w, h, 4, pixels, 0); | |
| STBI_FREE(pixels); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment