-%-%.SH VI. Runtime optimization
-%-%
-%-%A new feature in libpng 1.2.0 is the ability to dynamically switch between
-%-%standard and optimized versions of some routines. Currently these are
-%-%limited to three computationally intensive tasks when reading PNG files:
-%-%decoding row filters, expanding interlacing, and combining interlaced or
-%-%transparent row data with previous row data. Currently the optimized
-%-%versions are available only for x86 (Intel, AMD, etc.) platforms with
-%-%MMX support, though this may change in future versions. (For example,
-%-%the non-MMX assembler optimizations for zlib might become similarly
-%-%runtime-selectable in future releases, in which case libpng could be
-%-%extended to support them. Alternatively, the compile-time choice of
-%-%floating-point versus integer routines for gamma correction might become
-%-%runtime-selectable.)
-%-%
-%-%Because such optimizations tend to be very platform- and compiler-dependent,
-%-%both in how they are written and in how they perform, the new runtime code
-%-%in libpng has been written to allow programs to query, enable, and disable
-%-%either specific optimizations or all such optimizations. For example, to
-%-%enable all possible optimizations (bearing in mind that some "optimizations"
-%-%may actually run more slowly in rare cases):
-%-%
-%-% #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
-%-% png_uint_32 mask, flags;
-%-%
-%-% flags = png_get_asm_flags(png_ptr);
-%-% mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
-%-% png_set_asm_flags(png_ptr, flags | mask);
-%-% #endif
-%-%
-%-%To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ
-%-%by itself when calling png_get_asm_flagmask(); similarly for optimizing
-%-%only writing. To disable all optimizations:
-%-%
-%-% #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
-%-% flags = png_get_asm_flags(png_ptr);
-%-% mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
-%-% png_set_asm_flags(png_ptr, flags & ~mask);
-%-% #endif
-%-%
-%-%To enable or disable only MMX-related features, use png_get_mmx_flagmask()
-%-%in place of png_get_asm_flagmask(). The mmx version takes one additional
-%-%parameter:
-%-%
-%-% #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
-%-% int selection = PNG_SELECT_READ | PNG_SELECT_WRITE;
-%-% int compilerID;
-%-%
-%-% mask = png_get_mmx_flagmask(selection, &compilerID);
-%-% #endif
-%-%
-%-%On return, compilerID will indicate which version of the MMX assembler
-%-%optimizations was compiled. Currently two flavors exist: Microsoft
-%-%Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2).
-%-%On non-x86 platforms or on systems compiled without MMX optimizations, a
-%-%value of -1 is used.
-%-%
-%-%Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return
-%-%all valid, settable optimization bits for the version of the library that's
-%-%currently in use. In the case of shared (dynamically linked) libraries,
-%-%this may include optimizations that did not exist at the time the code was
-%-%written and compiled. It is also possible, of course, to enable only known,
-%-%specific optimizations; for example:
-%-%
-%-% #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
-%-% flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
-%-% | PNG_ASM_FLAG_MMX_READ_INTERLACE \
-%-% | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
-%-% | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
-%-% | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
-%-% | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
-%-% png_set_asm_flags(png_ptr, flags);
-%-% #endif
-%-%
-%-%This method would enable only the MMX read-optimizations available at the
-%-%time of libpng 1.2.0's release, regardless of whether a later version of
-%-%the DLL were actually being used. (Also note that these functions did not
-%-%exist in versions older than 1.2.0, so any attempt to run a dynamically
-%-%linked app on such an older version would fail.)
-%-%
-%-%To determine whether the processor supports MMX instructions at all, use
-%-%the png_mmx_support() function:
-%-%
-%-% #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
-%-% mmxsupport = png_mmx_support();
-%-% #endif
-%-%
-%-%It returns -1 if MMX support is not compiled into libpng, 0 if MMX code
-%-%is compiled but MMX is not supported by the processor, or 1 if MMX support
-%-%is fully available. Note that png_mmx_support(), png_get_mmx_flagmask(),
-%-%and png_get_asm_flagmask() all may be called without allocating and ini-
-%-%tializing any PNG structures (for example, as part of a usage screen or
-%-%"about" box).
-%-%
-%-%The following code can be used to prevent an application from using the
-%-%thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK
-%-%defined:
-%-%
-%-%#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
-%-% && defined(PNG_THREAD_UNSAFE_OK)
-%-% /* Disable thread-unsafe features of pnggccrd */
-%-% if (png_access_version() >= 10200)
-%-% {
-%-% png_uint_32 mmx_disable_mask = 0;
-%-% png_uint_32 asm_flags;
-%-%
-%-% mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
-%-% | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
-%-% | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
-%-% | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
-%-% asm_flags = png_get_asm_flags(png_ptr);
-%-% png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
-%-% }
-%-%#endif
-%-%
-%-%For more extensive examples of runtime querying, enabling and disabling
-%-%of optimized features, see contrib/gregbook/readpng2.c in the libpng
-%-%source-code distribution.
-%-%
-.SH VI. MNG support
+.SH VI. Runtime optimization
+
+A new feature in libpng 1.2.0 is the ability to dynamically switch between
+standard and optimized versions of some routines. Currently these are
+limited to three computationally intensive tasks when reading PNG files:
+decoding row filters, expanding interlacing, and combining interlaced or
+transparent row data with previous row data. Currently the optimized
+versions are available only for x86 (Intel, AMD, etc.) platforms with
+MMX support, though this may change in future versions. (For example,
+the non-MMX assembler optimizations for zlib might become similarly
+runtime-selectable in future releases, in which case libpng could be
+extended to support them. Alternatively, the compile-time choice of
+floating-point versus integer routines for gamma correction might become
+runtime-selectable.)
+
+Because such optimizations tend to be very platform- and compiler-dependent,
+both in how they are written and in how they perform, the new runtime code
+in libpng has been written to allow programs to query, enable, and disable
+either specific optimizations or all such optimizations. For example, to
+enable all possible optimizations (bearing in mind that some "optimizations"
+may actually run more slowly in rare cases):
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ png_uint_32 mask, flags;
+
+ flags = png_get_asm_flags(png_ptr);
+ mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+ png_set_asm_flags(png_ptr, flags | mask);
+ #endif
+
+To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ
+by itself when calling png_get_asm_flagmask(); similarly for optimizing
+only writing. To disable all optimizations:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ flags = png_get_asm_flags(png_ptr);
+ mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+ png_set_asm_flags(png_ptr, flags & ~mask);
+ #endif
+
+To enable or disable only MMX-related features, use png_get_mmx_flagmask()
+in place of png_get_asm_flagmask(). The mmx version takes one additional
+parameter:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ int selection = PNG_SELECT_READ | PNG_SELECT_WRITE;
+ int compilerID;
+
+ mask = png_get_mmx_flagmask(selection, &compilerID);
+ #endif
+
+On return, compilerID will indicate which version of the MMX assembler
+optimizations was compiled. Currently two flavors exist: Microsoft
+Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2).
+On non-x86 platforms or on systems compiled without MMX optimizations, a
+value of -1 is used.
+
+Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return
+all valid, settable optimization bits for the version of the library that's
+currently in use. In the case of shared (dynamically linked) libraries,
+this may include optimizations that did not exist at the time the code was
+written and compiled. It is also possible, of course, to enable only known,
+specific optimizations; for example:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_INTERLACE \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+ png_set_asm_flags(png_ptr, flags);
+ #endif
+
+This method would enable only the MMX read-optimizations available at the
+time of libpng 1.2.0's release, regardless of whether a later version of
+the DLL were actually being used. (Also note that these functions did not
+exist in versions older than 1.2.0, so any attempt to run a dynamically
+linked app on such an older version would fail.)
+
+To determine whether the processor supports MMX instructions at all, use
+the png_mmx_support() function:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ mmxsupport = png_mmx_support();
+ #endif
+
+It returns -1 if MMX support is not compiled into libpng, 0 if MMX code
+is compiled but MMX is not supported by the processor, or 1 if MMX support
+is fully available. Note that png_mmx_support(), png_get_mmx_flagmask(),
+and png_get_asm_flagmask() all may be called without allocating and ini-
+tializing any PNG structures (for example, as part of a usage screen or
+"about" box).
+
+The following code can be used to prevent an application from using the
+thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK
+defined:
+
+#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
+ && defined(PNG_THREAD_UNSAFE_OK)
+ /* Disable thread-unsafe features of pnggccrd */
+ if (png_access_version() >= 10200)
+ {
+ png_uint_32 mmx_disable_mask = 0;
+ png_uint_32 asm_flags;
+
+ mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
+ asm_flags = png_get_asm_flags(png_ptr);
+ png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
+ }
+#endif
+
+For more extensive examples of runtime querying, enabling and disabling
+of optimized features, see contrib/gregbook/readpng2.c in the libpng
+source-code distribution.
+
+.SH VII. MNG support