@ -96,8 +96,13 @@ STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , i
# define STBIR_ALPHA_CHANNEL_NONE -1
# define STBIR_ALPHA_CHANNEL_NONE -1
# define STBIR_FLAG_PREMULTIPLIED_ALPHA (1 << 0) // If this flag is not set, the specified alpha channel will be multiplied into all other channels before resampling, then divided back out after.
// Set this flag if your texture has premultiplied alpha. Otherwise, stbir will
# define STBIR_FLAG_ALPHA_USES_COLORSPACE (1 << 1) // The specified alpha channel should be handled as gamma-corrected value even when doing sRGB operations.
// use alpha-correct resampling by multiplying the the specified alpha channel
// into all other channels before resampling, then dividing back out after.
# define STBIR_FLAG_PREMULTIPLIED_ALPHA (1 << 0)
// The specified alpha channel should be handled as gamma-corrected value even
// when doing sRGB operations.
# define STBIR_FLAG_ALPHA_USES_COLORSPACE (1 << 1)
STBIRDEF int stbir_resize_uint8_srgb ( const unsigned char * input_pixels , int input_w , int input_h , int input_stride_in_bytes ,
STBIRDEF int stbir_resize_uint8_srgb ( const unsigned char * input_pixels , int input_w , int input_h , int input_stride_in_bytes ,
unsigned char * output_pixels , int output_w , int output_h , int output_stride_in_bytes ,
unsigned char * output_pixels , int output_w , int output_h , int output_stride_in_bytes ,
@ -201,7 +206,7 @@ STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int
stbir_datatype datatype ,
stbir_datatype datatype ,
int num_channels , int alpha_channel , int flags ,
int num_channels , int alpha_channel , int flags ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_colorspace space , void * alloc_context ) ;
stbir_colorspace space , void * alloc_context ) ;
STBIRDEF int stbir_resize_subpixel ( const void * input_pixels , int input_w , int input_h , int input_stride_in_bytes ,
STBIRDEF int stbir_resize_subpixel ( const void * input_pixels , int input_w , int input_h , int input_stride_in_bytes ,
@ -209,7 +214,7 @@ STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int
stbir_datatype datatype ,
stbir_datatype datatype ,
int num_channels , int alpha_channel , int flags ,
int num_channels , int alpha_channel , int flags ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_colorspace space , void * alloc_context ,
stbir_colorspace space , void * alloc_context ,
float x_scale , float y_scale ,
float x_scale , float y_scale ,
float x_offset , float y_offset ) ;
float x_offset , float y_offset ) ;
@ -219,12 +224,25 @@ STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int
stbir_datatype datatype ,
stbir_datatype datatype ,
int num_channels , int alpha_channel , int flags ,
int num_channels , int alpha_channel , int flags ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_colorspace space , void * alloc_context ,
stbir_colorspace space , void * alloc_context ,
float s0 , float t0 , float s1 , float t1 ) ;
float s0 , float t0 , float s1 , float t1 ) ;
// (s0, t0) & (s1, t1) are the top-left and bottom right corner (uv addressing style: [0, 1]x[0, 1]) of a region of the input image to use.
// (s0, t0) & (s1, t1) are the top-left and bottom right corner (uv addressing style: [0, 1]x[0, 1]) of a region of the input image to use.
// Define this if you want a progress report.
// Example:
// void my_progress_report(float progress)
// {
// printf("Progress: %f%%\n", progress*100);
// }
//
// #define STBIR_PROGRESS_REPORT my_progress_report
# ifndef STBIR_PROGRESS_REPORT
# define STBIR_PROGRESS_REPORT(float_0_to_1)
# endif
//
//
//
//
//// end header file /////////////////////////////////////////////////////
//// end header file /////////////////////////////////////////////////////
@ -1448,6 +1466,8 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
// Now all buffers should be ready to write a row of vertical sampling.
// Now all buffers should be ready to write a row of vertical sampling.
stbir__resample_vertical_upsample ( stbir_info , y , in_first_scanline , in_last_scanline , in_center_of_out ) ;
stbir__resample_vertical_upsample ( stbir_info , y , in_first_scanline , in_last_scanline , in_center_of_out ) ;
STBIR_PROGRESS_REPORT ( ( float ) y / stbir_info - > output_h ) ;
}
}
}
}
@ -1530,6 +1550,8 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
// Now the horizontal buffer is ready to write to all ring buffer rows.
// Now the horizontal buffer is ready to write to all ring buffer rows.
stbir__resample_vertical_downsample ( stbir_info , y , out_first_scanline , out_last_scanline , out_center_of_in ) ;
stbir__resample_vertical_downsample ( stbir_info , y , out_first_scanline , out_last_scanline , out_center_of_in ) ;
STBIR_PROGRESS_REPORT ( ( float ) ( y + stbir__get_filter_pixel_margin_vertical ( stbir_info ) ) / ( max_y + stbir__get_filter_pixel_margin_vertical ( stbir_info ) ) ) ;
}
}
stbir__empty_ring_buffer ( stbir_info , stbir_info - > output_h ) ;
stbir__empty_ring_buffer ( stbir_info , stbir_info - > output_h ) ;
@ -1650,7 +1672,7 @@ static int stbir__resize_allocated(stbir__info *info,
return 0 ;
return 0 ;
if ( alpha_channel < 0 )
if ( alpha_channel < 0 )
flags = STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_PREMULTIPLIED_ALPHA ;
flags | = STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_PREMULTIPLIED_ALPHA ;
if ( ! ( flags & STBIR_FLAG_ALPHA_USES_COLORSPACE ) | | ! ( flags & STBIR_FLAG_PREMULTIPLIED_ALPHA ) )
if ( ! ( flags & STBIR_FLAG_ALPHA_USES_COLORSPACE ) | | ! ( flags & STBIR_FLAG_PREMULTIPLIED_ALPHA ) )
STBIR_ASSERT ( alpha_channel > = 0 & & alpha_channel < info - > channels ) ;
STBIR_ASSERT ( alpha_channel > = 0 & & alpha_channel < info - > channels ) ;
@ -1733,7 +1755,7 @@ static int stbir__resize_allocated(stbir__info *info,
}
}
static int stbir_resize_arbitrary (
static int stbir__ resize_arbitrary (
void * alloc_context ,
void * alloc_context ,
const void * input_data , int input_w , int input_h , int input_stride_in_bytes ,
const void * input_data , int input_w , int input_h , int input_stride_in_bytes ,
void * output_data , int output_w , int output_h , int output_stride_in_bytes ,
void * output_data , int output_w , int output_h , int output_stride_in_bytes ,
@ -1751,7 +1773,7 @@ static int stbir_resize_arbitrary(
stbir__calculate_transform ( & info , s0 , t0 , s1 , t1 , transform ) ;
stbir__calculate_transform ( & info , s0 , t0 , s1 , t1 , transform ) ;
stbir__choose_filter ( & info , h_filter , v_filter ) ;
stbir__choose_filter ( & info , h_filter , v_filter ) ;
memory_required = stbir__calculate_memory ( & info ) ;
memory_required = stbir__calculate_memory ( & info ) ;
extra_memory = STBIR_MALLOC ( NULL , memory_required ) ;
extra_memory = STBIR_MALLOC ( alloc_context , memory_required ) ;
if ( ! extra_memory )
if ( ! extra_memory )
return 0 ;
return 0 ;
@ -1760,9 +1782,9 @@ static int stbir_resize_arbitrary(
output_data , output_stride_in_bytes ,
output_data , output_stride_in_bytes ,
alpha_channel , flags , type ,
alpha_channel , flags , type ,
edge_horizontal , edge_vertical ,
edge_horizontal , edge_vertical ,
colorspace , extra_memory , memory_required ) ;
colorspace , extra_memory , memory_required ) ;
STBIR_FREE ( context , extra_memory ) ;
STBIR_FREE ( alloc_ context, extra_memory ) ;
return result ;
return result ;
}
}
@ -1771,7 +1793,7 @@ STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int inp
unsigned char * output_pixels , int output_w , int output_h , int output_stride_in_bytes ,
unsigned char * output_pixels , int output_w , int output_h , int output_stride_in_bytes ,
int num_channels )
int num_channels )
{
{
return stbir_resize_arbitrary ( NULL , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( NULL , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , NULL , num_channels , - 1 , 0 , STBIR_TYPE_UINT8 , STBIR_FILTER_DEFAULT , STBIR_FILTER_DEFAULT ,
0 , 0 , 1 , 1 , NULL , num_channels , - 1 , 0 , STBIR_TYPE_UINT8 , STBIR_FILTER_DEFAULT , STBIR_FILTER_DEFAULT ,
STBIR_EDGE_CLAMP , STBIR_EDGE_CLAMP , STBIR_COLORSPACE_LINEAR ) ;
STBIR_EDGE_CLAMP , STBIR_EDGE_CLAMP , STBIR_COLORSPACE_LINEAR ) ;
@ -1781,7 +1803,7 @@ STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , i
float * output_pixels , int output_w , int output_h , int output_stride_in_bytes ,
float * output_pixels , int output_w , int output_h , int output_stride_in_bytes ,
int num_channels )
int num_channels )
{
{
return stbir_resize_arbitrary ( NULL , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( NULL , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , NULL , num_channels , - 1 , 0 , STBIR_TYPE_FLOAT , STBIR_FILTER_DEFAULT , STBIR_FILTER_DEFAULT ,
0 , 0 , 1 , 1 , NULL , num_channels , - 1 , 0 , STBIR_TYPE_FLOAT , STBIR_FILTER_DEFAULT , STBIR_FILTER_DEFAULT ,
STBIR_EDGE_CLAMP , STBIR_EDGE_CLAMP , STBIR_COLORSPACE_LINEAR ) ;
STBIR_EDGE_CLAMP , STBIR_EDGE_CLAMP , STBIR_COLORSPACE_LINEAR ) ;
@ -1791,7 +1813,7 @@ STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int inp
unsigned char * output_pixels , int output_w , int output_h , int output_stride_in_bytes ,
unsigned char * output_pixels , int output_w , int output_h , int output_stride_in_bytes ,
int num_channels , int alpha_channel , int flags )
int num_channels , int alpha_channel , int flags )
{
{
return stbir_resize_arbitrary ( NULL , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( NULL , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_UINT8 , STBIR_FILTER_DEFAULT , STBIR_FILTER_DEFAULT ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_UINT8 , STBIR_FILTER_DEFAULT , STBIR_FILTER_DEFAULT ,
STBIR_EDGE_CLAMP , STBIR_EDGE_CLAMP , STBIR_COLORSPACE_SRGB ) ;
STBIR_EDGE_CLAMP , STBIR_EDGE_CLAMP , STBIR_COLORSPACE_SRGB ) ;
@ -1802,7 +1824,7 @@ STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels
int num_channels , int alpha_channel , int flags ,
int num_channels , int alpha_channel , int flags ,
stbir_edge edge_wrap_mode )
stbir_edge edge_wrap_mode )
{
{
return stbir_resize_arbitrary ( NULL , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( NULL , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_UINT8 , STBIR_FILTER_DEFAULT , STBIR_FILTER_DEFAULT ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_UINT8 , STBIR_FILTER_DEFAULT , STBIR_FILTER_DEFAULT ,
edge_wrap_mode , edge_wrap_mode , STBIR_COLORSPACE_SRGB ) ;
edge_wrap_mode , edge_wrap_mode , STBIR_COLORSPACE_SRGB ) ;
@ -1814,7 +1836,7 @@ STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int
stbir_edge edge_wrap_mode , stbir_filter filter , stbir_colorspace space ,
stbir_edge edge_wrap_mode , stbir_filter filter , stbir_colorspace space ,
void * alloc_context )
void * alloc_context )
{
{
return stbir_resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_UINT8 , filter , filter ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_UINT8 , filter , filter ,
edge_wrap_mode , edge_wrap_mode , space ) ;
edge_wrap_mode , edge_wrap_mode , space ) ;
@ -1826,7 +1848,7 @@ STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int
stbir_edge edge_wrap_mode , stbir_filter filter , stbir_colorspace space ,
stbir_edge edge_wrap_mode , stbir_filter filter , stbir_colorspace space ,
void * alloc_context )
void * alloc_context )
{
{
return stbir_resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_UINT16 , filter , filter ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_UINT16 , filter , filter ,
edge_wrap_mode , edge_wrap_mode , space ) ;
edge_wrap_mode , edge_wrap_mode , space ) ;
@ -1839,7 +1861,7 @@ STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int
stbir_edge edge_wrap_mode , stbir_filter filter , stbir_colorspace space ,
stbir_edge edge_wrap_mode , stbir_filter filter , stbir_colorspace space ,
void * alloc_context )
void * alloc_context )
{
{
return stbir_resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_FLOAT , filter , filter ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , STBIR_TYPE_FLOAT , filter , filter ,
edge_wrap_mode , edge_wrap_mode , space ) ;
edge_wrap_mode , edge_wrap_mode , space ) ;
@ -1851,10 +1873,10 @@ STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int
stbir_datatype datatype ,
stbir_datatype datatype ,
int num_channels , int alpha_channel , int flags ,
int num_channels , int alpha_channel , int flags ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_colorspace space , void * alloc_context )
stbir_colorspace space , void * alloc_context )
{
{
return stbir_resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , datatype , filter_horizontal , filter_vertical ,
0 , 0 , 1 , 1 , NULL , num_channels , alpha_channel , flags , datatype , filter_horizontal , filter_vertical ,
edge_mode_horizontal , edge_mode_vertical , space ) ;
edge_mode_horizontal , edge_mode_vertical , space ) ;
@ -1866,7 +1888,7 @@ STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int
stbir_datatype datatype ,
stbir_datatype datatype ,
int num_channels , int alpha_channel , int flags ,
int num_channels , int alpha_channel , int flags ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_colorspace space , void * alloc_context ,
stbir_colorspace space , void * alloc_context ,
float x_scale , float y_scale ,
float x_scale , float y_scale ,
float x_offset , float y_offset )
float x_offset , float y_offset )
@ -1876,7 +1898,7 @@ STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int
transform [ 1 ] = y_scale ;
transform [ 1 ] = y_scale ;
transform [ 2 ] = x_offset ;
transform [ 2 ] = x_offset ;
transform [ 3 ] = y_offset ;
transform [ 3 ] = y_offset ;
return stbir_resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
0 , 0 , 1 , 1 , transform , num_channels , alpha_channel , flags , datatype , filter_horizontal , filter_vertical ,
0 , 0 , 1 , 1 , transform , num_channels , alpha_channel , flags , datatype , filter_horizontal , filter_vertical ,
edge_mode_horizontal , edge_mode_vertical , space ) ;
edge_mode_horizontal , edge_mode_vertical , space ) ;
@ -1887,11 +1909,11 @@ STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int
stbir_datatype datatype ,
stbir_datatype datatype ,
int num_channels , int alpha_channel , int flags ,
int num_channels , int alpha_channel , int flags ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_edge edge_mode_horizontal , stbir_edge edge_mode_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_filter filter_horizontal , stbir_filter filter_vertical ,
stbir_colorspace space , void * alloc_context ,
stbir_colorspace space , void * alloc_context ,
float s0 , float t0 , float s1 , float t1 )
float s0 , float t0 , float s1 , float t1 )
{
{
return stbir_resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
return stbir__ resize_arbitrary ( alloc_context , input_pixels , input_w , input_h , input_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
output_pixels , output_w , output_h , output_stride_in_bytes ,
s0 , t0 , s1 , t1 , NULL , num_channels , alpha_channel , flags , datatype , filter_horizontal , filter_vertical ,
s0 , t0 , s1 , t1 , NULL , num_channels , alpha_channel , flags , datatype , filter_horizontal , filter_vertical ,
edge_mode_horizontal , edge_mode_vertical , space ) ;
edge_mode_horizontal , edge_mode_vertical , space ) ;