<commit_before>#include "pixel.h"

static const colorlayout_t *get_color_map(GLenum format) {
    #define map(fmt, ...)                               \
        case fmt: {                                     \
        static colorlayout_t layout = {fmt, __VA_ARGS__}; \
        return &layout; }
    switch (format) {
        map(GL_RED, 0, -1, -1, -1);
        map(GL_RG, 0, 1, -1, -1);
        map(GL_RGBA, 0, 1, 2, 3);
        map(GL_RGB, 0, 1, 2, -1);
        map(GL_BGRA, 2, 1, 0, 3);
        map(GL_BGR, 2, 1, 0, -1);
		map(GL_LUMINANCE_ALPHA, 0, 0, 0, 1);
		map(GL_ALPHA, -1, -1, -1, 0);
        default:
            printf("libGL: unknown pixel format %i\n", format);
            break;
    }
    static colorlayout_t null = {0};
    return &null;
    #undef map
}

extern int raster_need_transform();
GLfloat raster_transformf(GLfloat pix, GLubyte number);
GLubyte raster_transform(GLubyte pix, GLubyte number);

static inline
bool remap_pixel(const GLvoid *src, GLvoid *dst, bool transform, 
                 const colorlayout_t *src_color, GLenum src_type,
                 const colorlayout_t *dst_color, GLenum dst_type) {

    #define type_case(constant, type, ...)        \
        case constant: {                          \
            const type *s = (const type *)src;    \
            type *d = (type *)dst;                \
            type v = *s;                          \
            __VA_ARGS__                           \
            break;                                \
        }

    #define default(arr, amod, vmod, key, def) \
        key >= 0 ? arr[amod key] vmod : def

    #define carefully(arr, amod, key, value) \
        if (key >= 0) d[amod key] = value;

    #define read_each(amod, vmod)                                 \
        pixel.r = default(s, amod, vmod, src_color->red, 0.0f);      \
        pixel.g = default(s, amod, vmod, src_color->green, 0.0f);    \
        pixel.b = default(s, amod, vmod, src_color->blue, 0.0f);     \
        pixel.a = default(s, amod, vmod, src_color->alpha, 1.0f);

    #define write_each(amod, vmod)                         \
        carefully(d, amod, dst_color->red, pixel.r vmod)   \
        carefully(d, amod, dst_color->green, pixel.g vmod) \
        carefully(d, amod, dst_color->blue, pixel.b vmod)  \
        carefully(d, amod, dst_color->alpha, pixel.a vmod)

    // this pixel stores our intermediate color
    // it will be RGBA and normalized to between (0.0 - 1.0f)
    pixel_t pixel;
    switch (src_type) {
        type_case(GL_DOUBLE, GLdouble, read_each(,))
        type_case(GL_FLOAT, GLfloat, read_each(,))
        case GL_UNSIGNED_INT_8_8_8_8_REV:
        type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f))
        type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(3 - , / 255.0f))
        type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort,
            s = (GLushort[]){
                (v & 31),
                ((v & 0x03e0) >> 5),
                ((v & 0x7c00) >> 10),
                ((v & 0x8000) >> 15)*31,
            };
            read_each(, / 31.0f);
        )
        default:
            // TODO: add glSetError?
            printf("libGL: Unsupported source data type: %i\n", src_type);
            return false;
            break;
    }
	if (transform) {
		pixel.r=raster_transformf(pixel.r, 0);
		pixel.g=raster_transformf(pixel.g, 1);
		pixel.b=raster_transformf(pixel.b, 2);
		pixel.a=raster_transformf(pixel.a, 3);
	}

    switch (dst_type) {
        type_case(GL_FLOAT, GLfloat, write_each(,))
        type_case(GL_UNSIGNED_BYTE, GLubyte, write_each(, * 255.0))
        // TODO: force 565 to RGB? then we can change [4] -> 3
        type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
            GLfloat color[4];
            color[dst_color->red] = pixel.r;
            color[dst_color->green] = pixel.g;
            color[dst_color->blue] = pixel.b;
            *d = ((GLuint)(color[0] * 31) & 0x1f << 11) |
                 ((GLuint)(color[1] * 63) & 0x3f << 5) |
                 ((GLuint)(color[2] * 31) & 0x1f);
        )
        default:
            printf("libGL: Unsupported target data type: %i\n", dst_type);
            return false;
            break;
    }
    return true;

    #undef type_case
    #undef default
    #undef carefully
    #undef read_each
    #undef write_each
}

bool pixel_convert(const GLvoid *src, GLvoid **dst,
                   GLuint width, GLuint height,
                   GLenum src_format, GLenum src_type,
                   GLenum dst_format, GLenum dst_type) {
    const colorlayout_t *src_color, *dst_color;
    GLuint pixels = width * height;
    GLuint dst_size = pixels * pixel_sizeof(dst_format, dst_type);

    //printf("pixel conversion: %ix%i - %04x, %04x -> %04x, %04x, transform=%i\n", width, height, src_format, src_type, dst_format, dst_type, raster_need_transform());
    src_color = get_color_map(src_format);
    dst_color = get_color_map(dst_format);
    if (!dst_size || !pixel_sizeof(src_format, src_type)
        || !src_color->type || !dst_color->type)
        return false;

    printf("src%04x[%i,%i,%i,%i] -> dst%04x[%i,%i,%i,%i]\n", src_format, src_color->red, src_color->green, src_color->blue, src_color->alpha, 
                                                            dst_format, dst_color->red, dst_color->green, dst_color->blue, dst_color->alpha);
    if (src_type == dst_type && src_color->type == dst_color->type) {
        *dst = malloc(dst_size);
        memcpy(*dst, src, dst_size);
		if ((raster_need_transform()) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE)) {
			for (int aa=0; aa<dst_size; aa++)
				((GLubyte*)*dst)[aa]=raster_transform(((GLubyte*)*dst)[aa], aa%4);
		}
		if (raster_need_transform() && (dst_format==GL_RGB) && (dst_type==GL_UNSIGNED_BYTE)) {<commit_msg>remove a leftover debug printf<commit_after>#include "pixel.h"

static const colorlayout_t *get_color_map(GLenum format) {
    #define map(fmt, ...)                               \
        case fmt: {                                     \
        static colorlayout_t layout = {fmt, __VA_ARGS__}; \
        return &layout; }
    switch (format) {
        map(GL_RED, 0, -1, -1, -1);
        map(GL_RG, 0, 1, -1, -1);
        map(GL_RGBA, 0, 1, 2, 3);
        map(GL_RGB, 0, 1, 2, -1);
        map(GL_BGRA, 2, 1, 0, 3);
        map(GL_BGR, 2, 1, 0, -1);
		map(GL_LUMINANCE_ALPHA, 0, 0, 0, 1);
		map(GL_ALPHA, -1, -1, -1, 0);
        default:
            printf("libGL: unknown pixel format %i\n", format);
            break;
    }
    static colorlayout_t null = {0};
    return &null;
    #undef map
}

extern int raster_need_transform();
GLfloat raster_transformf(GLfloat pix, GLubyte number);
GLubyte raster_transform(GLubyte pix, GLubyte number);

static inline
bool remap_pixel(const GLvoid *src, GLvoid *dst, bool transform, 
                 const colorlayout_t *src_color, GLenum src_type,
                 const colorlayout_t *dst_color, GLenum dst_type) {

    #define type_case(constant, type, ...)        \
        case constant: {                          \
            const type *s = (const type *)src;    \
            type *d = (type *)dst;                \
            type v = *s;                          \
            __VA_ARGS__                           \
            break;                                \
        }

    #define default(arr, amod, vmod, key, def) \
        key >= 0 ? arr[amod key] vmod : def

    #define carefully(arr, amod, key, value) \
        if (key >= 0) d[amod key] = value;

    #define read_each(amod, vmod)                                 \
        pixel.r = default(s, amod, vmod, src_color->red, 0.0f);      \
        pixel.g = default(s, amod, vmod, src_color->green, 0.0f);    \
        pixel.b = default(s, amod, vmod, src_color->blue, 0.0f);     \
        pixel.a = default(s, amod, vmod, src_color->alpha, 1.0f);

    #define write_each(amod, vmod)                         \
        carefully(d, amod, dst_color->red, pixel.r vmod)   \
        carefully(d, amod, dst_color->green, pixel.g vmod) \
        carefully(d, amod, dst_color->blue, pixel.b vmod)  \
        carefully(d, amod, dst_color->alpha, pixel.a vmod)

    // this pixel stores our intermediate color
    // it will be RGBA and normalized to between (0.0 - 1.0f)
    pixel_t pixel;
    switch (src_type) {
        type_case(GL_DOUBLE, GLdouble, read_each(,))
        type_case(GL_FLOAT, GLfloat, read_each(,))
        case GL_UNSIGNED_INT_8_8_8_8_REV:
        type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f))
        type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(3 - , / 255.0f))
        type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort,
            s = (GLushort[]){
                (v & 31),
                ((v & 0x03e0) >> 5),
                ((v & 0x7c00) >> 10),
                ((v & 0x8000) >> 15)*31,
            };
            read_each(, / 31.0f);
        )
        default:
            // TODO: add glSetError?
            printf("libGL: Unsupported source data type: %i\n", src_type);
            return false;
            break;
    }
	if (transform) {
		pixel.r=raster_transformf(pixel.r, 0);
		pixel.g=raster_transformf(pixel.g, 1);
		pixel.b=raster_transformf(pixel.b, 2);
		pixel.a=raster_transformf(pixel.a, 3);
	}

    switch (dst_type) {
        type_case(GL_FLOAT, GLfloat, write_each(,))
        type_case(GL_UNSIGNED_BYTE, GLubyte, write_each(, * 255.0))
        // TODO: force 565 to RGB? then we can change [4] -> 3
        type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort,
            GLfloat color[4];
            color[dst_color->red] = pixel.r;
            color[dst_color->green] = pixel.g;
            color[dst_color->blue] = pixel.b;
            *d = ((GLuint)(color[0] * 31) & 0x1f << 11) |
                 ((GLuint)(color[1] * 63) & 0x3f << 5) |
                 ((GLuint)(color[2] * 31) & 0x1f);
        )
        default:
            printf("libGL: Unsupported target data type: %i\n", dst_type);
            return false;
            break;
    }
    return true;

    #undef type_case
    #undef default
    #undef carefully
    #undef read_each
    #undef write_each
}

bool pixel_convert(const GLvoid *src, GLvoid **dst,
                   GLuint width, GLuint height,
                   GLenum src_format, GLenum src_type,
                   GLenum dst_format, GLenum dst_type) {
    const colorlayout_t *src_color, *dst_color;
    GLuint pixels = width * height;
    GLuint dst_size = pixels * pixel_sizeof(dst_format, dst_type);

    //printf("pixel conversion: %ix%i - %04x, %04x -> %04x, %04x, transform=%i\n", width, height, src_format, src_type, dst_format, dst_type, raster_need_transform());
    src_color = get_color_map(src_format);
    dst_color = get_color_map(dst_format);
    if (!dst_size || !pixel_sizeof(src_format, src_type)
        || !src_color->type || !dst_color->type)
        return false;

    if (src_type == dst_type && src_color->type == dst_color->type) {
        *dst = malloc(dst_size);
        memcpy(*dst, src, dst_size);
		if ((raster_need_transform()) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE)) {
			for (int aa=0; aa<dst_size; aa++)
				((GLubyte*)*dst)[aa]=raster_transform(((GLubyte*)*dst)[aa], aa%4);
		}
		if (raster_need_transform() && (dst_format==GL_RGB) && (dst_type==GL_UNSIGNED_BYTE)) {
{'fraction_non_alphanumeric': 0.13512083259834187, 'fraction_numerical': 0.024695713529723055, 'mean_word_length': 1.9768968233132056, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5581365', 'n_tokens_mistral': 4211, 'n_tokens_neox': 3945, 'n_words': 874}