Procházet zdrojové kódy

new quickstart docs;
reformat docs;
new simple uint32 test

Sean Barrett před 11 roky
rodič
revize
9f66b441bd
2 změnil soubory, kde provedl 174 přidání a 128 odebrání
  1. 138 128
      stb_image_resize.h
  2. 36 0
      tests/resample_test.cpp

+ 138 - 128
stb_image_resize.h

@@ -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
 #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

+ 36 - 0
tests/resample_test.cpp

@@ -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