diff --git a/stb_resample.h b/stb_resample.h index a451568..68b53e7 100644 --- a/stb_resample.h +++ b/stb_resample.h @@ -257,8 +257,8 @@ extern "C" { #ifndef STBR_MALLOC #include -#define STBR_MALLOC malloc -#define STBR_FREE free +#define STBR_MALLOC(x) malloc(x) +#define STBR_FREE(x) free(x) #endif @@ -1033,77 +1033,74 @@ static float* stbr__get_ring_buffer_scanline(int get_scanline, float* ring_buffe } -static stbr_inline void stbr__encode_scanline(void* output_buffer, int output_texel_index, float* encode_buffer, int encode_texel_index, int channels, int premul_alpha_channel, int decode) +static stbr_inline void stbr__encode_pixel(void* output_buffer, int output_texel_index, float* encode_buffer, int encode_texel_index, int channels, int premul_alpha_channel, int decode) { int n; float divide_alpha = 1; - if (premul_alpha_channel) - divide_alpha = encode_buffer[encode_texel_index + premul_alpha_channel]; + if (premul_alpha_channel) { + float alpha = encode_buffer[encode_texel_index + premul_alpha_channel]; + float reciprocal_alpha = alpha ? 1.0 / alpha : 0; + for (n = 0; n < channels; n++) + if (n != premul_alpha_channel) + encode_buffer[encode_texel_index + n] *= reciprocal_alpha; + } switch (decode) { case STBR__DECODE(STBR_TYPE_UINT8, STBR_COLORSPACE_LINEAR): for (n = 0; n < channels; n++) { - float divide_alpha_channel = (n == premul_alpha_channel) ? 1 : divide_alpha; - ((unsigned char*)output_buffer)[output_texel_index + n] = (unsigned char)(stbr__saturate(encode_buffer[encode_texel_index + n] / divide_alpha_channel) * 255); + ((unsigned char*)output_buffer)[output_texel_index + n] = (unsigned char)(stbr__saturate(encode_buffer[encode_texel_index + n]) * 255); } break; case STBR__DECODE(STBR_TYPE_UINT8, STBR_COLORSPACE_SRGB): for (n = 0; n < channels; n++) { - float divide_alpha_channel = (n == premul_alpha_channel) ? 1 : divide_alpha; - ((unsigned char*)output_buffer)[output_texel_index + n] = stbr__linear_uchar_to_srgb_uchar[(unsigned char)(stbr__saturate(encode_buffer[encode_texel_index + n] / divide_alpha_channel) * 255)]; + ((unsigned char*)output_buffer)[output_texel_index + n] = stbr__linear_uchar_to_srgb_uchar[(unsigned char)(stbr__saturate(encode_buffer[encode_texel_index + n]) * 255)]; } break; case STBR__DECODE(STBR_TYPE_UINT16, STBR_COLORSPACE_LINEAR): for (n = 0; n < channels; n++) { - float divide_alpha_channel = (n == premul_alpha_channel) ? 1 : divide_alpha; - ((unsigned short*)output_buffer)[output_texel_index + n] = (unsigned short)(stbr__saturate(encode_buffer[encode_texel_index + n] / divide_alpha_channel) * 65535); + ((unsigned short*)output_buffer)[output_texel_index + n] = (unsigned short)(stbr__saturate(encode_buffer[encode_texel_index + n]) * 65535); } break; case STBR__DECODE(STBR_TYPE_UINT16, STBR_COLORSPACE_SRGB): for (n = 0; n < channels; n++) { - float divide_alpha_channel = (n == premul_alpha_channel) ? 1 : divide_alpha; - ((unsigned short*)output_buffer)[output_texel_index + n] = (unsigned short)(stbr__linear_to_srgb(stbr__saturate(encode_buffer[encode_texel_index + n] / divide_alpha_channel)) * 65535); + ((unsigned short*)output_buffer)[output_texel_index + n] = (unsigned short)(stbr__linear_to_srgb(stbr__saturate(encode_buffer[encode_texel_index + n])) * 65535); } break; case STBR__DECODE(STBR_TYPE_UINT32, STBR_COLORSPACE_LINEAR): for (n = 0; n < channels; n++) { - float divide_alpha_channel = (n == premul_alpha_channel) ? 1 : divide_alpha; - ((unsigned int*)output_buffer)[output_texel_index + n] = (unsigned int)(((double)stbr__saturate(encode_buffer[encode_texel_index + n] / divide_alpha_channel)) * 4294967295); + ((unsigned int*)output_buffer)[output_texel_index + n] = (unsigned int)(((double)stbr__saturate(encode_buffer[encode_texel_index + n])) * 4294967295); } break; case STBR__DECODE(STBR_TYPE_UINT32, STBR_COLORSPACE_SRGB): for (n = 0; n < channels; n++) { - float divide_alpha_channel = (n == premul_alpha_channel) ? 1 : divide_alpha; - ((unsigned int*)output_buffer)[output_texel_index + n] = (unsigned int)(((double)stbr__linear_to_srgb(stbr__saturate(encode_buffer[encode_texel_index + n] / divide_alpha_channel))) * 4294967295); + ((unsigned int*)output_buffer)[output_texel_index + n] = (unsigned int)(((double)stbr__linear_to_srgb(stbr__saturate(encode_buffer[encode_texel_index + n]))) * 4294967295); } break; case STBR__DECODE(STBR_TYPE_FLOAT, STBR_COLORSPACE_LINEAR): for (n = 0; n < channels; n++) { - float divide_alpha_channel = (n == premul_alpha_channel) ? 1 : divide_alpha; - ((float*)output_buffer)[output_texel_index + n] = stbr__saturate(encode_buffer[encode_texel_index + n] / divide_alpha_channel); + ((float*)output_buffer)[output_texel_index + n] = stbr__saturate(encode_buffer[encode_texel_index + n]); } break; case STBR__DECODE(STBR_TYPE_FLOAT, STBR_COLORSPACE_SRGB): for (n = 0; n < channels; n++) { - float divide_alpha_channel = (n == premul_alpha_channel) ? 1 : divide_alpha; - ((float*)output_buffer)[output_texel_index + n] = stbr__linear_to_srgb(stbr__saturate(encode_buffer[encode_texel_index + n] / divide_alpha_channel)); + ((float*)output_buffer)[output_texel_index + n] = stbr__linear_to_srgb(stbr__saturate(encode_buffer[encode_texel_index + n])); } break; @@ -1168,7 +1165,7 @@ static void stbr__resample_vertical_upsample(stbr__info* stbr_info, int n, int i encode_buffer[c] += ring_buffer_entry[in_texel_index + c] * coefficient; } - stbr__encode_scanline(output_data, out_texel_index, encode_buffer, 0, channels, premul_alpha_channel, decode); + stbr__encode_pixel(output_data, out_texel_index, encode_buffer, 0, channels, premul_alpha_channel, decode); } } @@ -1303,7 +1300,7 @@ static void stbr__empty_ring_buffer(stbr__info* stbr_info, int first_necessary_s int ring_texel_index = texel_index; int output_texel_index = output_row + texel_index; - stbr__encode_scanline(output_data, output_texel_index, ring_buffer_entry, ring_texel_index, channels, premul_alpha_channel, decode); + stbr__encode_pixel(output_data, output_texel_index, ring_buffer_entry, ring_texel_index, channels, premul_alpha_channel, decode); } }