|
|
|
@ -1,161 +1,171 @@ |
|
|
|
|
/* stb_image_resize - v0.90 - public domain image resizing
|
|
|
|
|
by Jorge L Rodriguez (@VinoBS) - 2014 |
|
|
|
|
http://github.com/nothings/stb
|
|
|
|
|
/* stb_image_resize - v0.90 - public domain image resizing
|
|
|
|
|
by Jorge L Rodriguez (@VinoBS) - 2014 |
|
|
|
|
http://github.com/nothings/stb
|
|
|
|
|
|
|
|
|
|
Written with emphasis on usage and speed. Only scaling is |
|
|
|
|
currently supported, no rotations or translations. |
|
|
|
|
Written with emphasis on usability, portability, and efficiency. (No |
|
|
|
|
SIMD or threads, so it will not be the fastest implementation around.) |
|
|
|
|
Only scaling is supported, no rotations or translations. |
|
|
|
|
|
|
|
|
|
DOCUMENTATION |
|
|
|
|
COMPILING & LINKING |
|
|
|
|
In one C/C++ file that #includes this file, do this: |
|
|
|
|
#define STB_IMAGE_RESIZE_IMPLEMENTATION |
|
|
|
|
before the #include. That will create the implementation in that file. |
|
|
|
|
|
|
|
|
|
COMPILING & LINKING |
|
|
|
|
In one C/C++ file that #includes this file, do this: |
|
|
|
|
#define STB_IMAGE_RESIZE_IMPLEMENTATION |
|
|
|
|
before the #include. That will create the implementation in that file. |
|
|
|
|
QUICKSTART |
|
|
|
|
stbir_resize_uint8( input_pixels , in_w , in_h , 0, |
|
|
|
|
output_pixels, out_w, out_h, 0, num_channels) |
|
|
|
|
stbir_resize_float(...) |
|
|
|
|
stbir_resize_uint8_srgb( input_pixels , in_w , in_h , 0, |
|
|
|
|
output_pixels, out_w, out_h, 0, |
|
|
|
|
num_channels , alpha_ chan , 0) |
|
|
|
|
stbir_resize_uint8_srgb_edgemode( |
|
|
|
|
input_pixels , in_w , in_h , 0,
|
|
|
|
|
output_pixels, out_w, out_h, 0,
|
|
|
|
|
num_channels , alpha_chan , 0, STBIR_EDGE_CLAMP) |
|
|
|
|
WRAP/REFLECT/ZERO |
|
|
|
|
|
|
|
|
|
VERY QUICK GUIDE |
|
|
|
|
A typical resize of a in_w by in_h image to out_w by out_h with 4 channels where channel #3 is the alpha channel might look like: |
|
|
|
|
int success = stbir_resize_uint8_srgb_edgemode(input_pixels, in_w, in_h, 0, output_pixels, out_w, out_h, 0, 4, 3, 0, STBIR_EDGE_CLAMP); |
|
|
|
|
FULL API |
|
|
|
|
See the "header file" section of the source for API documentation. |
|
|
|
|
|
|
|
|
|
FULL API |
|
|
|
|
See the "header file" section of the source for API documentation. |
|
|
|
|
ADDITIONAL DOCUMENTATION |
|
|
|
|
|
|
|
|
|
MEMORY ALLOCATION |
|
|
|
|
The resize functions here perform a single memory allocation using |
|
|
|
|
malloc. To control the memory allocation, before the #include that |
|
|
|
|
triggers the implementation, do: |
|
|
|
|
MEMORY ALLOCATION |
|
|
|
|
The resize functions here perform a single memory allocation using |
|
|
|
|
malloc. To control the memory allocation, before the #include that |
|
|
|
|
triggers the implementation, do: |
|
|
|
|
|
|
|
|
|
#define STBIR_MALLOC(size,context) ... |
|
|
|
|
#define STBIR_FREE(ptr,context) ... |
|
|
|
|
#define STBIR_MALLOC(size,context) ... |
|
|
|
|
#define STBIR_FREE(ptr,context) ... |
|
|
|
|
|
|
|
|
|
Each resize function makes exactly one call to malloc/free, so to use |
|
|
|
|
temp memory, store the temp memory in the context and return that. |
|
|
|
|
Each resize function makes exactly one call to malloc/free, so to use |
|
|
|
|
temp memory, store the temp memory in the context and return that. |
|
|
|
|
|
|
|
|
|
ASSERT |
|
|
|
|
Define STBIR_ASSERT(boolval) to override assert() and not use assert.h |
|
|
|
|
ASSERT |
|
|
|
|
Define STBIR_ASSERT(boolval) to override assert() and not use assert.h |
|
|
|
|
|
|
|
|
|
DEFAULT FILTERS |
|
|
|
|
For functions which don't provide explicit control over what filters |
|
|
|
|
to use, you can change the compile-time defaults with |
|
|
|
|
DEFAULT FILTERS |
|
|
|
|
For functions which don't provide explicit control over what filters |
|
|
|
|
to use, you can change the compile-time defaults with |
|
|
|
|
|
|
|
|
|
#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_something |
|
|
|
|
#define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_something |
|
|
|
|
#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_something |
|
|
|
|
#define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_something |
|
|
|
|
|
|
|
|
|
See stbir_filter in the header-file section for the list of filters. |
|
|
|
|
See stbir_filter in the header-file section for the list of filters. |
|
|
|
|
|
|
|
|
|
NEW FILTERS |
|
|
|
|
A number of 1D filter kernels are used. For a list of |
|
|
|
|
supported filters see the stbir_filter enum. To add a new filter, |
|
|
|
|
write a filter function and add it to stbir__filter_info_table. |
|
|
|
|
NEW FILTERS |
|
|
|
|
A number of 1D filter kernels are used. For a list of |
|
|
|
|
supported filters see the stbir_filter enum. To add a new filter, |
|
|
|
|
write a filter function and add it to stbir__filter_info_table. |
|
|
|
|
|
|
|
|
|
PROGRESS |
|
|
|
|
For interactive use with slow resize operations, you can install |
|
|
|
|
a progress-report callback: |
|
|
|
|
PROGRESS |
|
|
|
|
For interactive use with slow resize operations, you can install |
|
|
|
|
a progress-report callback: |
|
|
|
|
|
|
|
|
|
#define STBIR_PROGRESS_REPORT(val) some_func(val) |
|
|
|
|
#define STBIR_PROGRESS_REPORT(val) some_func(val) |
|
|
|
|
|
|
|
|
|
The parameter val is a float which goes from 0 to 1 as progress is made. |
|
|
|
|
The parameter val is a float which goes from 0 to 1 as progress is made. |
|
|
|
|
|
|
|
|
|
For example: |
|
|
|
|
For example: |
|
|
|
|
|
|
|
|
|
static void my_progress_report(float progress); |
|
|
|
|
#define STBIR_PROGRESS_REPORT(val) my_progress_report(val) |
|
|
|
|
static void my_progress_report(float progress); |
|
|
|
|
#define STBIR_PROGRESS_REPORT(val) my_progress_report(val) |
|
|
|
|
|
|
|
|
|
#define STB_IMAGE_RESIZE_IMPLEMENTATION |
|
|
|
|
#include "stb_image_resize.h" |
|
|
|
|
#define STB_IMAGE_RESIZE_IMPLEMENTATION |
|
|
|
|
#include "stb_image_resize.h" |
|
|
|
|
|
|
|
|
|
static void my_progress_report(float progress) |
|
|
|
|
{ |
|
|
|
|
printf("Progress: %f%%\n", progress*100); |
|
|
|
|
} |
|
|
|
|
static void my_progress_report(float progress) |
|
|
|
|
{ |
|
|
|
|
printf("Progress: %f%%\n", progress*100); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ALPHA CHANNEL |
|
|
|
|
Most of the resizing functions provide the ability to control how |
|
|
|
|
the alpha channel of an image is processed. The important things |
|
|
|
|
to know about this: |
|
|
|
|
|
|
|
|
|
1. The best mathematically-behaved version of alpha to use is |
|
|
|
|
called "premultiplied alpha", in which the other color channels |
|
|
|
|
have had the alpha value multiplied in. If you use premultiplied |
|
|
|
|
alpha, linear filtering (such as image resampling done by this |
|
|
|
|
library, or performed in texture units on GPUs) does the "right |
|
|
|
|
thing". While premultiplied alpha is standard in the movie CGI |
|
|
|
|
industry, it is still uncommon in the videogame/real-time world. |
|
|
|
|
|
|
|
|
|
If you linearly filter non-premultiplied alpha, strange effects |
|
|
|
|
occur. (For example, the average of 1% opaque bright green |
|
|
|
|
and 99% opaque black produces 50% transparent dark green when |
|
|
|
|
non-premultiplied, whereas premultiplied it produces 50% |
|
|
|
|
transparent near-black. The former introduces green energy |
|
|
|
|
that doesn't exist in the source image.) |
|
|
|
|
|
|
|
|
|
2. Artists should not edit premultiplied-alpha images; artists |
|
|
|
|
want non-premultiplied alpha images. Thus, art tools generally output |
|
|
|
|
non-premultiplied alpha images. |
|
|
|
|
|
|
|
|
|
3. You will get best results in most cases by converting images |
|
|
|
|
to premultiplied alpha before processing them mathematically. |
|
|
|
|
|
|
|
|
|
4. If you pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, the |
|
|
|
|
resizer does not do anything special for the alpha channel; |
|
|
|
|
it is resampled identically to other channels. This produces |
|
|
|
|
the correct results for premultiplied-alpha images, but produces |
|
|
|
|
less-than-ideal results for non-premultiplied-alpha images. |
|
|
|
|
|
|
|
|
|
5. If you do not pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, |
|
|
|
|
then the resizer weights the contribution of input pixels |
|
|
|
|
based on their alpha values, or, equivalently, it multiplies |
|
|
|
|
the alpha value into the color channels, resamples, then divides |
|
|
|
|
by the resultant alpha value. Input pixels which have alpha=0 do |
|
|
|
|
not contribute at all to output pixels unless _all_ of the input |
|
|
|
|
pixels affecting that output pixel have alpha=0, in which case |
|
|
|
|
the result for that pixel is the same as it would be without |
|
|
|
|
STBIR_FLAG_ALPHA_PREMULTIPLIED. However, this is only true for |
|
|
|
|
input images in integer formats. For input images in float format, |
|
|
|
|
input pixels with alpha=0 have no effect, and output pixels |
|
|
|
|
which have alpha=0 will be 0 in all channels. (For float images, |
|
|
|
|
you can manually achieve the same result by adding a tiny epsilon |
|
|
|
|
value to the alpha channel of every image, and then subtracting |
|
|
|
|
or clamping it at the end.) |
|
|
|
|
|
|
|
|
|
6. You can suppress the behavior described in #5 and make |
|
|
|
|
all-0-alpha pixels have 0 in all channels by #defining |
|
|
|
|
STBIR_NO_ALPHA_EPSILON. |
|
|
|
|
|
|
|
|
|
7. You can separately control whether the alpha channel is |
|
|
|
|
interpreted as linear or affected by the colorspace. By default |
|
|
|
|
it is linear; you almost never want to apply the colorspace. |
|
|
|
|
(For example, graphics hardware does not apply sRGB conversion |
|
|
|
|
to the alpha channel.) |
|
|
|
|
|
|
|
|
|
ADDITIONAL CONTRIBUTORS |
|
|
|
|
Sean Barrett: API design, optimizations |
|
|
|
|
|
|
|
|
|
REVISIONS |
|
|
|
|
0.90 (2014-??-??) first released version |
|
|
|
|
|
|
|
|
|
LICENSE |
|
|
|
|
This software is in the public domain. Where that dedication is not |
|
|
|
|
recognized, you are granted a perpetual, irrevocable license to copy |
|
|
|
|
and modify this file as you see fit. |
|
|
|
|
|
|
|
|
|
TODO |
|
|
|
|
Don't decode all of the image data when only processing a partial tile |
|
|
|
|
Installable filters? |
|
|
|
|
Resize that respects alpha test coverage |
|
|
|
|
(Reference code: FloatImage::alphaTestCoverage and FloatImage::scaleAlphaToCoverage: |
|
|
|
|
https://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvimage/FloatImage.cpp )
|
|
|
|
|
ALPHA CHANNEL |
|
|
|
|
Most of the resizing functions provide the ability to control how |
|
|
|
|
the alpha channel of an image is processed. The important things |
|
|
|
|
to know about this: |
|
|
|
|
|
|
|
|
|
1. The best mathematically-behaved version of alpha to use is |
|
|
|
|
called "premultiplied alpha", in which the other color channels |
|
|
|
|
have had the alpha value multiplied in. If you use premultiplied |
|
|
|
|
alpha, linear filtering (such as image resampling done by this |
|
|
|
|
library, or performed in texture units on GPUs) does the "right |
|
|
|
|
thing". While premultiplied alpha is standard in the movie CGI |
|
|
|
|
industry, it is still uncommon in the videogame/real-time world. |
|
|
|
|
|
|
|
|
|
If you linearly filter non-premultiplied alpha, strange effects |
|
|
|
|
occur. (For example, the average of 1% opaque bright green |
|
|
|
|
and 99% opaque black produces 50% transparent dark green when |
|
|
|
|
non-premultiplied, whereas premultiplied it produces 50% |
|
|
|
|
transparent near-black. The former introduces green energy |
|
|
|
|
that doesn't exist in the source image.) |
|
|
|
|
|
|
|
|
|
2. Artists should not edit premultiplied-alpha images; artists |
|
|
|
|
want non-premultiplied alpha images. Thus, art tools generally output |
|
|
|
|
non-premultiplied alpha images. |
|
|
|
|
|
|
|
|
|
3. You will get best results in most cases by converting images |
|
|
|
|
to premultiplied alpha before processing them mathematically. |
|
|
|
|
|
|
|
|
|
4. If you pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, the |
|
|
|
|
resizer does not do anything special for the alpha channel; |
|
|
|
|
it is resampled identically to other channels. This produces |
|
|
|
|
the correct results for premultiplied-alpha images, but produces |
|
|
|
|
less-than-ideal results for non-premultiplied-alpha images. |
|
|
|
|
|
|
|
|
|
5. If you do not pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, |
|
|
|
|
then the resizer weights the contribution of input pixels |
|
|
|
|
based on their alpha values, or, equivalently, it multiplies |
|
|
|
|
the alpha value into the color channels, resamples, then divides |
|
|
|
|
by the resultant alpha value. Input pixels which have alpha=0 do |
|
|
|
|
not contribute at all to output pixels unless _all_ of the input |
|
|
|
|
pixels affecting that output pixel have alpha=0, in which case |
|
|
|
|
the result for that pixel is the same as it would be without |
|
|
|
|
STBIR_FLAG_ALPHA_PREMULTIPLIED. However, this is only true for |
|
|
|
|
input images in integer formats. For input images in float format, |
|
|
|
|
input pixels with alpha=0 have no effect, and output pixels |
|
|
|
|
which have alpha=0 will be 0 in all channels. (For float images, |
|
|
|
|
you can manually achieve the same result by adding a tiny epsilon |
|
|
|
|
value to the alpha channel of every image, and then subtracting |
|
|
|
|
or clamping it at the end.) |
|
|
|
|
|
|
|
|
|
6. You can suppress the behavior described in #5 and make |
|
|
|
|
all-0-alpha pixels have 0 in all channels by #defining |
|
|
|
|
STBIR_NO_ALPHA_EPSILON. |
|
|
|
|
|
|
|
|
|
7. You can separately control whether the alpha channel is |
|
|
|
|
interpreted as linear or affected by the colorspace. By default |
|
|
|
|
it is linear; you almost never want to apply the colorspace. |
|
|
|
|
(For example, graphics hardware does not apply sRGB conversion |
|
|
|
|
to the alpha channel.) |
|
|
|
|
|
|
|
|
|
ADDITIONAL CONTRIBUTORS |
|
|
|
|
Sean Barrett: API design, optimizations |
|
|
|
|
|
|
|
|
|
REVISIONS |
|
|
|
|
0.90 (2014-??-??) first released version |
|
|
|
|
|
|
|
|
|
LICENSE |
|
|
|
|
This software is in the public domain. Where that dedication is not |
|
|
|
|
recognized, you are granted a perpetual, irrevocable license to copy |
|
|
|
|
and modify this file as you see fit. |
|
|
|
|
|
|
|
|
|
TODO |
|
|
|
|
Don't decode all of the image data when only processing a partial tile |
|
|
|
|
Installable filters? |
|
|
|
|
Resize that respects alpha test coverage |
|
|
|
|
(Reference code: FloatImage::alphaTestCoverage and FloatImage::scaleAlphaToCoverage: |
|
|
|
|
https://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvimage/FloatImage.cpp )
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifndef STBIR_INCLUDE_STB_IMAGE_RESIZE_H |
|
|
|
|
#define STBIR_INCLUDE_STB_IMAGE_RESIZE_H |
|
|
|
|
|
|
|
|
|
typedef unsigned char stbir_uint8; |
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER |
|
|
|
|
typedef unsigned char stbir_uint8; |
|
|
|
|
typedef unsigned short stbir_uint16; |
|
|
|
|
typedef unsigned int stbir_uint32; |
|
|
|
|
#else |
|
|
|
|
#include <stdint.h> |
|
|
|
|
typedef uint8_t stbir_uint8; |
|
|
|
|
typedef uint16_t stbir_uint16; |
|
|
|
|
typedef uint32_t stbir_uint32; |
|
|
|
|
#endif |
|
|
|
@ -372,7 +382,7 @@ STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int |
|
|
|
|
#ifndef STBIR_MALLOC |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#define STBIR_MALLOC(size,c) malloc(size) |
|
|
|
|
#define STBIR_FREE(ptr,c) free(ptr) |
|
|
|
|
#define STBIR_FREE(ptr,c) free(ptr) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifndef _MSC_VER |
|
|
|
|