+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.
+
+VI. MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions. To enable them, use the
+png_permit_mng_features() function:
+
+ feature_set = png_permit_mng_features(png_ptr, mask)
+ mask is a png_uint_32 containing the logical OR of the
+ features you want to enable. These include
+ PNG_FLAG_MNG_EMPTY_PLTE
+ PNG_FLAG_MNG_FILTER_64
+ PNG_ALL_MNG_FEATURES
+ feature_set is a png_uint_32 that is the logical AND of
+ your mask with the set of MNG features that is
+ supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped
+in a MNG datastream. As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks. Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them. You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+VII. Changes to Libpng from version 0.88