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